+static ssize_t sread (int fd, void *buffer_void, size_t buffer_size) /* {{{ */
+{
+ char *buffer;
+ size_t buffer_used;
+ size_t buffer_free;
+ ssize_t status;
+
+ buffer = (char *) buffer_void;
+ buffer_used = 0;
+ buffer_free = buffer_size;
+
+ while (buffer_free > 0)
+ {
+ status = read (fd, buffer + buffer_used, buffer_free);
+ if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+ continue;
+
+ if (status < 0)
+ return (-1);
+
+ if (status == 0)
+ return (0);
+
+ assert ((0 > status) || (buffer_free >= (size_t) status));
+
+ buffer_free = buffer_free - status;
+ buffer_used = buffer_used + status;
+
+ if (buffer[buffer_used - 1] == '\n')
+ break;
+ }
+
+ assert (buffer_used > 0);
+
+ if (buffer[buffer_used - 1] != '\n')
+ {
+ errno = ENOBUFS;
+ return (-1);
+ }
+
+ buffer[buffer_used - 1] = 0;
+
+ /* Fix network line endings. */
+ if ((buffer_used > 1) && (buffer[buffer_used - 2] == '\r'))
+ {
+ buffer_used--;
+ buffer[buffer_used - 1] = 0;
+ }
+
+ return (buffer_used);
+} /* }}} ssize_t sread */
+
+static ssize_t swrite (int fd, const void *buf, size_t count) /* {{{ */
+{
+ const char *ptr;
+ size_t nleft;
+ ssize_t status;
+
+ ptr = (const char *) buf;
+ nleft = count;
+
+ while (nleft > 0)
+ {
+ status = write (fd, (const void *) ptr, nleft);
+
+ if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR)))
+ continue;
+
+ if (status < 0)
+ return (status);
+
+ nleft = nleft - status;
+ ptr = ptr + status;
+ }
+
+ return (0);
+} /* }}} ssize_t swrite */
+