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:
committed by
Adrien Destugues
parent
4f7db7e037
commit
fc03b45a71
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user