unix: add back preadv/pwritev fallback

Implement in terms of pread/pwrite and only try to read/write the first
buffer. Callers are supposed to handle partial reads and libuv takes
care of partial writes.

(Our own fs_read_bufs test doesn't but that's fine because this commit
is a fix-up for unsupported platforms that aren't in our CI matrix.)

Fixes: https://github.com/libuv/libuv/issues/4176
This commit is contained in:
Ben Noordhuis 2023-10-21 13:57:25 +02:00
parent 815dd8a25c
commit 8d69f256d1

View File

@ -82,6 +82,13 @@
# include <sys/statfs.h>
#endif
#if defined(__CYGWIN__) || defined(__HAIKU__) || defined(__sun)
#define preadv(fd, bufs, nbufs, off) \
pread(fd, (bufs)->iov_base, (bufs)->iov_len, off)
#define pwritev(fd, bufs, nbufs, off) \
pwrite(fd, (bufs)->iov_base, (bufs)->iov_len, off)
#endif
#if defined(_AIX) && _XOPEN_SOURCE <= 600
extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
#endif
@ -406,15 +413,16 @@ static ssize_t uv__fs_read_do(int fd,
if (nbufs > iovmax)
nbufs = iovmax;
result = 0;
if (off < 0) {
if (nbufs == 1)
result = read(fd, bufs->iov_base, bufs->iov_len);
else
else if (nbufs > 1)
result = readv(fd, bufs, nbufs);
} else {
if (nbufs == 1)
result = pread(fd, bufs->iov_base, bufs->iov_len, off);
else
else if (nbufs > 1)
result = preadv(fd, bufs, nbufs, off);
}
@ -1089,15 +1097,16 @@ static ssize_t uv__fs_write_do(int fd,
int64_t off) {
ssize_t r;
r = 0;
if (off < 0) {
if (nbufs == 1)
r = write(fd, bufs->iov_base, bufs->iov_len);
else
else if (nbufs > 1)
r = writev(fd, bufs, nbufs);
} else {
if (nbufs == 1)
r = pwrite(fd, bufs->iov_base, bufs->iov_len, off);
else
else if (nbufs > 1)
r = pwritev(fd, bufs, nbufs, off);
}