From 67135ca8e041ac922d1045fe833c8052e652e5e7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 27 Jun 2018 10:47:09 -0400 Subject: [PATCH] Split read_all and write_all into separate functions --- src/common/util.c | 71 ++++++++++++++++++++++++++++++++------------ src/common/util.h | 13 ++++++-- src/lib/fdio/fdio.c | 2 +- src/lib/fdio/fdio.h | 2 +- src/lib/log/torlog.c | 4 +-- 5 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/common/util.c b/src/common/util.c index 8334dd7ae0..2d426bb136 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1076,22 +1076,17 @@ format_time_interval(char *out, size_t out_len, long interval) * File helpers * ===== */ -/** Write count bytes from buf to fd. isSocket - * must be 1 if fd was returned by socket() or accept(), and 0 if fd - * was returned by open(). Return the number of bytes written, or -1 - * on error. Only use if fd is a blocking fd. */ +/** Write count bytes from buf to fd. Return the number + * of bytes written, or -1 on error. Only use if fd is a blocking fd. */ ssize_t -write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket) +write_all_to_fd(int fd, const char *buf, size_t count) { size_t written = 0; ssize_t result; raw_assert(count < SSIZE_MAX); while (written != count) { - if (isSocket) - result = tor_socket_send(fd, buf+written, count-written, 0); - else - result = write((int)fd, buf+written, count-written); + result = write(fd, buf+written, count-written); if (result<0) return -1; written += result; @@ -1099,13 +1094,29 @@ write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket) return (ssize_t)count; } -/** Read from fd to buf, until we get count bytes - * or reach the end of the file. isSocket must be 1 if fd - * was returned by socket() or accept(), and 0 if fd was returned by - * open(). Return the number of bytes read, or -1 on error. Only use - * if fd is a blocking fd. */ +/** Write count bytes from buf to sock. Return the number + * of bytes written, or -1 on error. Only use if fd is a blocking fd. */ ssize_t -read_all(tor_socket_t fd, char *buf, size_t count, int isSocket) +write_all_to_socket(tor_socket_t fd, const char *buf, size_t count) +{ + size_t written = 0; + ssize_t result; + raw_assert(count < SSIZE_MAX); + + while (written != count) { + result = tor_socket_send(fd, buf+written, count-written, 0); + if (result<0) + return -1; + written += result; + } + return (ssize_t)count; +} + +/** Read from fd to buf, until we get count bytes or + * reach the end of the file. Return the number of bytes read, or -1 on + * error. Only use if fd is a blocking fd. */ +ssize_t +read_all_from_fd(int fd, char *buf, size_t count) { size_t numread = 0; ssize_t result; @@ -1116,10 +1127,32 @@ read_all(tor_socket_t fd, char *buf, size_t count, int isSocket) } while (numread < count) { - if (isSocket) - result = tor_socket_recv(fd, buf+numread, count-numread, 0); - else - result = read((int)fd, buf+numread, count-numread); + result = read(fd, buf+numread, count-numread); + if (result<0) + return -1; + else if (result == 0) + break; + numread += result; + } + return (ssize_t)numread; +} + +/** Read from sock to buf, until we get count bytes or + * reach the end of the file. Return the number of bytes read, or -1 on + * error. Only use if fd is a blocking fd. */ +ssize_t +read_all_from_socket(tor_socket_t sock, char *buf, size_t count) +{ + size_t numread = 0; + ssize_t result; + + if (count > SIZE_T_CEILING || count > SSIZE_MAX) { + errno = EINVAL; + return -1; + } + + while (numread < count) { + result = tor_socket_recv(sock, buf+numread, count-numread, 0); if (result<0) return -1; else if (result == 0) diff --git a/src/common/util.h b/src/common/util.h index 26ee2d75a9..1cb3e73b32 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -117,8 +117,17 @@ int parse_http_time(const char *buf, struct tm *tm); int format_time_interval(char *out, size_t out_len, long interval); /* File helpers */ -ssize_t write_all(tor_socket_t fd, const char *buf, size_t count,int isSocket); -ssize_t read_all(tor_socket_t fd, char *buf, size_t count, int isSocket); +ssize_t write_all_to_fd(int fd, const char *buf, size_t count); +ssize_t write_all_to_socket(tor_socket_t fd, const char *buf, size_t count); +ssize_t read_all_from_fd(int fd, char *buf, size_t count); +ssize_t read_all_from_socket(tor_socket_t fd, char *buf, size_t count); + +#define write_all(fd, buf, count, isSock) \ + ((isSock) ? write_all_to_socket((fd), (buf), (count)) \ + : write_all_to_fd((int)(fd), (buf), (count))) +#define read_all(fd, buf, count, isSock) \ + ((isSock) ? read_all_from_socket((fd), (buf), (count)) \ + : read_all_from_fd((int)(fd), (buf), (count))) /** Status of an I/O stream. */ enum stream_status { diff --git a/src/lib/fdio/fdio.c b/src/lib/fdio/fdio.c index b622074329..21577e1845 100644 --- a/src/lib/fdio/fdio.c +++ b/src/lib/fdio/fdio.c @@ -94,7 +94,7 @@ tor_ftruncate(int fd) /** Minimal version of write_all, for use by logging. */ int -write_all_to_fd(int fd, const char *buf, size_t count) +write_all_to_fd_minimal(int fd, const char *buf, size_t count) { size_t written = 0; raw_assert(count < SSIZE_MAX); diff --git a/src/lib/fdio/fdio.h b/src/lib/fdio/fdio.h index 8cc4a04658..0fb3ed1e62 100644 --- a/src/lib/fdio/fdio.h +++ b/src/lib/fdio/fdio.h @@ -12,6 +12,6 @@ off_t tor_fd_getpos(int fd); int tor_fd_setpos(int fd, off_t pos); int tor_fd_seekend(int fd); int tor_ftruncate(int fd); -int write_all_to_fd(int fd, const char *buf, size_t count); +int write_all_to_fd_minimal(int fd, const char *buf, size_t count); #endif /* !defined(TOR_FDIO_H) */ diff --git a/src/lib/log/torlog.c b/src/lib/log/torlog.c index 5709dd8199..b6088d3ebd 100644 --- a/src/lib/log/torlog.c +++ b/src/lib/log/torlog.c @@ -346,7 +346,7 @@ log_tor_version(logfile_t *lf, int reset) tor_snprintf(buf+n, sizeof(buf)-n, "Tor %s opening %slog file.\n", VERSION, is_new?"new ":""); } - if (write_all_to_fd(lf->fd, buf, strlen(buf)) < 0) /* error */ + if (write_all_to_fd_minimal(lf->fd, buf, strlen(buf)) < 0) /* error */ return -1; /* failed */ return 0; } @@ -560,7 +560,7 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, lf->callback(severity, domain, msg_after_prefix); } } else { - if (write_all_to_fd(lf->fd, buf, msg_len) < 0) { /* error */ + if (write_all_to_fd_minimal(lf->fd, buf, msg_len) < 0) { /* error */ /* don't log the error! mark this log entry to be blown away, and * continue. */ lf->seems_dead = 1;