From 12d41759bc835d895bdd03cb3e1987b3c2b541d2 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 30 Dec 2017 03:26:12 +0100 Subject: Initial import --- safe_rw.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 safe_rw.c (limited to 'safe_rw.c') diff --git a/safe_rw.c b/safe_rw.c new file mode 100644 index 0000000..683d8b5 --- /dev/null +++ b/safe_rw.c @@ -0,0 +1,81 @@ + +#include +#include + +#include +#include +#include +#include +#include + +#ifndef SSIZE_MAX +#define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif + +#include "safe_rw.h" + +ssize_t +safe_write(const int fd, const void *const buf_, size_t count, + const int timeout) +{ + struct pollfd pfd; + const char * buf = (const char *) buf_; + ssize_t written; + + pfd.fd = fd; + pfd.events = POLLOUT; + + assert(count <= SSIZE_MAX); + while (count > (size_t) 0) { + while ((written = write(fd, buf, count)) <= (ssize_t) 0) { + if (errno == EAGAIN) { + if (poll(&pfd, (nfds_t) 1, timeout) == 0) { + errno = ETIMEDOUT; + goto ret; + } + } else if (errno != EINTR) { + goto ret; + } + } + buf += written; + count -= (size_t) written; + } +ret: + return (ssize_t)(buf - (const char *) buf_); +} + +ssize_t +safe_read(const int fd, void *const buf_, size_t count) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(count <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, count)) < (ssize_t) 0 && errno == EINTR) + ; + if (readnb < (ssize_t) 0) { + return readnb; + } + if (readnb == (ssize_t) 0) { + break; + } + count -= (size_t) readnb; + buf += readnb; + } while (count > (ssize_t) 0); + + return (ssize_t)(buf - (unsigned char *) buf_); +} + +ssize_t +safe_read_partial(const int fd, void *const buf_, const size_t max_count) +{ + unsigned char *const buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(max_count <= SSIZE_MAX); + while ((readnb = read(fd, buf, max_count)) < (ssize_t) 0 && errno == EINTR) + ; + + return readnb; +} -- cgit v1.2.3-70-g09d2