X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Futil.c;h=5421a6b5c53beab448e4c23a9d9be1004b92f8ea;hp=f1ec74f0730176770f44f88927c05497be5fe71f;hb=4f8059f2d0a74a9922128b162d9c9343b305999c;hpb=f9695b9f40035f1a20968293255761a8301eaba0 diff --git a/src/util.c b/src/util.c index f1ec74f0..5421a6b5 100644 --- a/src/util.c +++ b/src/util.c @@ -30,19 +30,25 @@ #include #define _GNU_SOURCE -#include -#include "wimlib_internal.h" #include "endianness.h" #include "timestamp.h" +#include "wimlib_internal.h" #include #include -#include #include +#include +#include + #ifdef __WIN32__ -#include "win32.h" +# include "win32.h" +# define pread win32_pread +# define pwrite win32_pwrite +# define writev win32_writev +#else +# include /* for writev() and `struct iovec' */ #endif static size_t @@ -564,79 +570,75 @@ zap_backslashes(tchar *s) } } -/* Write @n bytes from @buf to the file descriptor @fd, retrying on internupt - * and on short writes. - * - * Returns short count and set errno on failure. */ +/* Like read(), but keep trying until everything has been written or we know for + * sure that there was an error (or end-of-file). */ size_t -full_write(int fd, const void *buf, size_t n) +full_read(int fd, void *buf, size_t count) { - const void *p = buf; - ssize_t ret; - ssize_t total = 0; + ssize_t bytes_read; + size_t bytes_remaining; - while (total != n) { - ret = write(fd, p, n); - if (ret <= 0) { - if (errno == EINTR) - continue; - if (ret == 0) + for (bytes_remaining = count; + bytes_remaining != 0; + bytes_remaining -= bytes_read, buf += bytes_read) + { + bytes_read = read(fd, buf, bytes_remaining); + if (bytes_read <= 0) { + if (bytes_read == 0) errno = EIO; + else if (errno == EINTR) + continue; break; } - total += ret; - p += ret; } - return total; + return count - bytes_remaining; } -/* Read @n bytes from the file descriptor @fd to the buffer @buf, retrying on - * interrupt and on short reads. - * - * Returns short count and set errno on failure. */ +/* Like write(), but keep trying until everything has been written or we know + * for sure that there was an error. */ size_t -full_read(int fd, void *buf, size_t n) +full_write(int fd, const void *buf, size_t count) { - size_t bytes_remaining = n; - while (bytes_remaining) { - ssize_t bytes_read = read(fd, buf, bytes_remaining); - if (bytes_read <= 0) { + ssize_t bytes_written; + size_t bytes_remaining; + + for (bytes_remaining = count; + bytes_remaining != 0; + bytes_remaining -= bytes_written, buf += bytes_written) + { + bytes_written = write(fd, buf, bytes_remaining); + if (bytes_written < 0) { if (errno == EINTR) continue; - if (bytes_read == 0) - errno = EIO; break; } - bytes_remaining -= bytes_read; - buf += bytes_read; } - return n - bytes_remaining; + return count - bytes_remaining; } -/* Read @n bytes from the file descriptor @fd at the offset @offset to the - * buffer @buf, retrying on interrupt and on short reads. - * - * Returns short count and set errno on failure. */ +/* Like pread(), but keep trying until everything has been read or we know for + * sure that there was an error (or end-of-file) */ size_t -full_pread(int fd, void *buf, size_t nbyte, off_t offset) +full_pread(int fd, void *buf, size_t count, off_t offset) { - size_t bytes_remaining = nbyte; ssize_t bytes_read; + size_t bytes_remaining; - while (bytes_remaining) { + for (bytes_remaining = count; + bytes_remaining != 0; + bytes_remaining -= bytes_read, buf += bytes_read, + offset += bytes_read) + { bytes_read = pread(fd, buf, bytes_remaining, offset); if (bytes_read <= 0) { - if (errno == EINTR) - continue; if (bytes_read == 0) errno = EIO; + else if (errno == EINTR) + continue; break; } - bytes_remaining -= bytes_read; - buf += bytes_read; - offset += bytes_read; } - return nbyte - bytes_remaining; + return count - bytes_remaining; } /* Like pwrite(), but keep trying until everything has been written or we know @@ -644,28 +646,57 @@ full_pread(int fd, void *buf, size_t nbyte, off_t offset) size_t full_pwrite(int fd, const void *buf, size_t count, off_t offset) { - ssize_t bytes_remaining = count; ssize_t bytes_written; + size_t bytes_remaining; - while (bytes_remaining > 0) { + for (bytes_remaining = count; + bytes_remaining != 0; + bytes_remaining -= bytes_written, buf += bytes_written, + offset += bytes_written) + { bytes_written = pwrite(fd, buf, bytes_remaining, offset); - if (bytes_written <= 0) { + if (bytes_written < 0) { if (errno == EINTR) continue; - if (bytes_written == 0) - errno = EIO; break; } - bytes_remaining -= bytes_written; - buf += bytes_written; - offset += bytes_written; } return count - bytes_remaining; } +/* Like writev(), but keep trying until everything has been written or we know + * for sure that there was an error. */ +size_t +full_writev(int fd, struct iovec *iov, int iovcnt) +{ + size_t total_bytes_written = 0; + while (iovcnt > 0) { + ssize_t bytes_written; + + bytes_written = writev(fd, iov, iovcnt); + if (bytes_written < 0) { + if (errno == EINTR) + continue; + break; + } + total_bytes_written += bytes_written; + while (bytes_written) { + if (bytes_written >= iov[0].iov_len) { + bytes_written -= iov[0].iov_len; + iov++; + iovcnt--; + } else { + iov[0].iov_base += bytes_written; + iov[0].iov_len -= bytes_written; + bytes_written = 0; + } + } + } + return total_bytes_written; +} off_t -filedes_offset(filedes_t fd) +filedes_offset(int fd) { return lseek(fd, 0, SEEK_CUR); }