POSIX: make readv() and writev() conform to IEEE Std 1003.1-2001

The standardized version of readv() and writev() take an int as the third
parameter. Arguably a size_t makes more sense, but the standardization bodies
decided otherwise.

The non-standard functions of readv_pos() and writev_pos() have been updated
for consistency. The corresponding _kern_readv() and _kern_writev() internal
functions continue to take the size_t parameter.

The ABI will not change, even though on 64 bit machines the size of the count
parameter will change from 8 to 4 bytes.

The actual use will be slightly different. Like with the size_t argument type,
it will not be possible to give a count lower than 0. If the value is less than
0, then the B_BAD_VALUE/EINVAL error will be set.

Change-Id: I949c8ed67dbc0b4e209768cbdee554c929fc242e
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3770
Reviewed-by: Jérôme Duval <[email protected]>
This commit is contained in:
Niels Sascha Reedijk
2021-03-16 12:03:02 +00:00
committed by Adrien Destugues
parent 4f7db7e037
commit fc03b45a71
5 changed files with 39 additions and 26 deletions
+4 -4
View File
@@ -19,10 +19,10 @@ typedef struct iovec {
extern "C" { extern "C" {
#endif #endif
ssize_t readv(int fd, const struct iovec *vector, size_t count); ssize_t readv(int fd, const struct iovec *vector, int count);
ssize_t readv_pos(int fd, off_t pos, const struct iovec *vec, size_t count); ssize_t readv_pos(int fd, off_t pos, const struct iovec *vec, int count);
ssize_t writev(int fd, const struct iovec *vector, size_t count); ssize_t writev(int fd, const struct iovec *vector, int count);
ssize_t writev_pos(int fd, off_t pos, const struct iovec *vec, size_t count); ssize_t writev_pos(int fd, off_t pos, const struct iovec *vec, int count);
#ifdef __cplusplus #ifdef __cplusplus
} }
+4 -4
View File
@@ -20,13 +20,13 @@ extern "C" {
#endif #endif
fssh_ssize_t fssh_readv(int fd, const struct fssh_iovec *vector, fssh_ssize_t fssh_readv(int fd, const struct fssh_iovec *vector,
fssh_size_t count); int count);
fssh_ssize_t fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_ssize_t fssh_readv_pos(int fd, fssh_off_t pos, const struct
fssh_iovec *vec, fssh_size_t count); fssh_iovec *vec, int count);
fssh_ssize_t fssh_writev(int fd, const struct fssh_iovec *vector, fssh_ssize_t fssh_writev(int fd, const struct fssh_iovec *vector,
fssh_size_t count); int count);
fssh_ssize_t fssh_writev_pos(int fd, fssh_off_t pos, fssh_ssize_t fssh_writev_pos(int fd, fssh_off_t pos,
const struct fssh_iovec *vec, fssh_size_t count); const struct fssh_iovec *vec, int count);
#ifdef __cplusplus #ifdef __cplusplus
} }
+5 -2
View File
@@ -986,11 +986,14 @@ write(int fd, const void *buffer, size_t bufferSize)
ssize_t ssize_t
writev(int fd, const struct iovec* vecs, size_t count) writev(int fd, const struct iovec* vecs, int count)
{ {
size_t totalWritten = 0; size_t totalWritten = 0;
for (size_t i = 0; i < count; i++) { if (count < 0)
RETURN_AND_SET_ERRNO(B_BAD_VALUE);
for (int i = 0; i < count; i++) {
ssize_t written = write(fd, vecs[i].iov_base, vecs[i].iov_len); ssize_t written = write(fd, vecs[i].iov_base, vecs[i].iov_len);
if (written < 0) if (written < 0)
return totalWritten == 0 ? written : totalWritten; return totalWritten == 0 ? written : totalWritten;
+18 -8
View File
@@ -14,19 +14,24 @@
ssize_t ssize_t
readv(int fd, const struct iovec *vecs, size_t count) readv(int fd, const struct iovec *vecs, int count)
{ {
ssize_t bytes = _kern_readv(fd, -1, vecs, count); ssize_t bytes;
if (count < 0) {
__set_errno(B_BAD_VALUE);
return -1;
}
bytes = _kern_readv(fd, -1, vecs, count);
RETURN_AND_SET_ERRNO(bytes); RETURN_AND_SET_ERRNO(bytes);
} }
ssize_t ssize_t
readv_pos(int fd, off_t pos, const struct iovec *vecs, size_t count) readv_pos(int fd, off_t pos, const struct iovec *vecs, int count)
{ {
ssize_t bytes; ssize_t bytes;
if (pos < 0) { if (pos < 0 || count < 0) {
__set_errno(B_BAD_VALUE); __set_errno(B_BAD_VALUE);
return -1; return -1;
} }
@@ -37,19 +42,24 @@ readv_pos(int fd, off_t pos, const struct iovec *vecs, size_t count)
ssize_t ssize_t
writev(int fd, const struct iovec *vecs, size_t count) writev(int fd, const struct iovec *vecs, int count)
{ {
ssize_t bytes = _kern_writev(fd, -1, vecs, count); ssize_t bytes;
if (count < 0) {
__set_errno(B_BAD_VALUE);
return -1;
}
bytes = _kern_writev(fd, -1, vecs, count);
RETURN_AND_SET_ERRNO(bytes); RETURN_AND_SET_ERRNO(bytes);
} }
ssize_t ssize_t
writev_pos(int fd, off_t pos, const struct iovec *vecs, size_t count) writev_pos(int fd, off_t pos, const struct iovec *vecs, int count)
{ {
ssize_t bytes; ssize_t bytes;
if (pos < 0) { if (pos < 0 || count < 0) {
__set_errno(B_BAD_VALUE); __set_errno(B_BAD_VALUE);
return -1; return -1;
} }
+8 -8
View File
@@ -19,19 +19,19 @@
#include "partition_support.h" #include "partition_support.h"
static const fssh_size_t kMaxIOVecs = 1024; static const int kMaxIOVecs = 1024;
bool bool
prepare_iovecs(const struct fssh_iovec *vecs, fssh_size_t count, prepare_iovecs(const struct fssh_iovec *vecs, int count,
struct iovec* systemVecs) struct iovec* systemVecs)
{ {
if (count > kMaxIOVecs) { if (count < 0 || count > kMaxIOVecs) {
errno = B_BAD_VALUE; errno = B_BAD_VALUE;
return false; return false;
} }
for (fssh_size_t i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
systemVecs[i].iov_base = vecs[i].iov_base; systemVecs[i].iov_base = vecs[i].iov_base;
systemVecs[i].iov_len = vecs[i].iov_len; systemVecs[i].iov_len = vecs[i].iov_len;
} }
@@ -41,7 +41,7 @@ prepare_iovecs(const struct fssh_iovec *vecs, fssh_size_t count,
fssh_ssize_t fssh_ssize_t
fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count) fssh_readv(int fd, const struct fssh_iovec *vector, int count)
{ {
struct iovec systemVecs[kMaxIOVecs]; struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vector, count, systemVecs)) if (!prepare_iovecs(vector, count, systemVecs))
@@ -62,7 +62,7 @@ fssh_readv(int fd, const struct fssh_iovec *vector, fssh_size_t count)
fssh_ssize_t fssh_ssize_t
fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec, fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
fssh_size_t count) int count)
{ {
struct iovec systemVecs[kMaxIOVecs]; struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vec, count, systemVecs)) if (!prepare_iovecs(vec, count, systemVecs))
@@ -77,7 +77,7 @@ fssh_readv_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
fssh_ssize_t fssh_ssize_t
fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count) fssh_writev(int fd, const struct fssh_iovec *vector, int count)
{ {
struct iovec systemVecs[kMaxIOVecs]; struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vector, count, systemVecs)) if (!prepare_iovecs(vector, count, systemVecs))
@@ -98,7 +98,7 @@ fssh_writev(int fd, const struct fssh_iovec *vector, fssh_size_t count)
fssh_ssize_t fssh_ssize_t
fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec, fssh_writev_pos(int fd, fssh_off_t pos, const struct fssh_iovec *vec,
fssh_size_t count) int count)
{ {
struct iovec systemVecs[kMaxIOVecs]; struct iovec systemVecs[kMaxIOVecs];
if (!prepare_iovecs(vec, count, systemVecs)) if (!prepare_iovecs(vec, count, systemVecs))