diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2021-04-15 14:34:55 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2021-04-15 14:36:39 -0400 |
commit | 9870b77f9000c55bbe507bbb11d6d20fac2e8da0 (patch) | |
tree | 6dd24948300c2b1bd5cbca40ba52e4ac9178650c | |
parent | b7111f2f01dce9516aea5250e765124300f2fa3a (diff) | |
download | bfs-9870b77f9000c55bbe507bbb11d6d20fac2e8da0.tar.xz |
util: Tweak the safe read/write functions
-rw-r--r-- | bar.c | 2 | ||||
-rw-r--r-- | spawn.c | 8 | ||||
-rw-r--r-- | util.c | 71 | ||||
-rw-r--r-- | util.h | 27 |
4 files changed, 49 insertions, 59 deletions
@@ -58,7 +58,7 @@ static int bfs_bar_getsize(struct bfs_bar *bar) { /** Async Signal Safe puts(). */ static int ass_puts(int fd, const char *str) { size_t len = strlen(str); - return safe_write_all(fd, str, len) == (ssize_t)len ? 0 : -1; + return xwrite(fd, str, len) == len ? 0 : -1; } /** Number of decimal digits needed for terminal sizes. */ @@ -189,9 +189,9 @@ static void bfs_spawn_exec(const char *exe, const struct bfs_spawn *ctx, char ** fail: error = errno; - // In case of write error parent will still see that we exited - // unsuccessfully, but won't know why. - (void) safe_write_all(pipefd[1], &error, sizeof(error)); + // In case of a write error, the parent will still see that we exited + // unsuccessfully, but won't know why + (void) xwrite(pipefd[1], &error, sizeof(error)); close(pipefd[1]); _Exit(127); @@ -221,7 +221,7 @@ pid_t bfs_spawn(const char *exe, const struct bfs_spawn *ctx, char **argv, char // Parent close(pipefd[1]); - ssize_t nbytes = safe_read_all(pipefd[0], &error, sizeof(error)); + ssize_t nbytes = xread(pipefd[0], &error, sizeof(error)); close(pipefd[0]); if (nbytes == sizeof(error)) { int wstatus; @@ -369,57 +369,48 @@ int bfs_minor(dev_t dev) { #endif } -ssize_t safe_read(int fd, void *buf, size_t nbytes) { - for (;;) { - ssize_t ret = read(fd, buf, nbytes); - if (ret < 0 && errno == EINTR) { - continue; - } - return ret; - } -} - -ssize_t safe_read_all(int fd, void *buf, size_t nbytes) { +size_t xread(int fd, void *buf, size_t nbytes) { size_t count = 0; - for (;;) { + + while (count < nbytes) { ssize_t ret = read(fd, (char *)buf + count, nbytes - count); - if (ret < 0 && errno == EINTR) { - continue; - } if (ret < 0) { - return ret; // always return error < 0 - } - count += ret; - if (ret == 0 || count == nbytes) { // EOF or success - return count; + if (errno == EINTR) { + continue; + } else { + break; + } + } else if (ret == 0) { + // EOF + errno = 0; + break; + } else { + count += ret; } } -} -ssize_t safe_write(int fd, const void *buf, size_t nbytes) { - for (;;) { - ssize_t ret = write(fd, buf, nbytes); - if (ret < 0 && errno == EINTR) { - continue; - } - return ret; - } + return count; } -ssize_t safe_write_all(int fd, const void *buf, size_t nbytes) -{ +size_t xwrite(int fd, const void *buf, size_t nbytes) { size_t count = 0; - for (;;) { + + while (count < nbytes) { ssize_t ret = write(fd, (const char *)buf + count, nbytes - count); - if (ret < 0 && errno == EINTR) { - continue; - } if (ret < 0) { - return ret; // always return error < 0 - } - count += ret; - if (ret == 0 || count == nbytes) { // EOF (should never happen with write) or success - return count; + if (errno == EINTR) { + continue; + } else { + break; + } + } else if (ret == 0) { + // EOF? + errno = 0; + break; + } else { + count += ret; } } + + return count; } @@ -226,23 +226,22 @@ int bfs_major(dev_t dev); int bfs_minor(dev_t dev); /** - * A safe version of read() that handles interrupted system calls. - */ -ssize_t safe_read(int fd, void *buf, size_t nbytes); - -/** - * A safe version of read() that handles interrupted system calls and partial reads. - */ -ssize_t safe_read_all(int fd, void *buf, size_t nbytes); - -/** - * A safe version of write() that handles interrupted system calls. + * A safe version of read() that handles interrupted system calls and partial + * reads. + * + * @return + * The number of bytes read. A value != nbytes indicates an error + * (errno != 0) or end of file (errno == 0). */ -ssize_t safe_write(int fd, const void *buf, size_t nbytes); +size_t xread(int fd, void *buf, size_t nbytes); /** - * A safe version of write() that handles interrupted system calls and partial writes. + * A safe version of write() that handles interrupted system calls and partial + * writes. + * + * @return + The number of bytes written. A value != nbytes indicates an error. */ -ssize_t safe_write_all(int fd, const void *buf, size_t nbytes); +size_t xwrite(int fd, const void *buf, size_t nbytes); #endif // BFS_UTIL_H |