From 8d69f256d18d4a2fc8295399224d433748b8a466 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sat, 21 Oct 2023 13:57:25 +0200 Subject: [PATCH] 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 --- src/unix/fs.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/unix/fs.c b/src/unix/fs.c index 595fc2c3a..0403e2682 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -82,6 +82,13 @@ # include #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); }