+static void errpipe_readable(void) {
+ static char buf[1024];
+ static int pending;
+
+ /* %: does not contain newlines
+ * _: empty (garbage)
+ */
+
+ /* %%%%%%%%%%%__________________ */
+ /* ^ pending */
+
+ for (;;) {
+ int avail = sizeof(buf) - pending;
+ ssize_t got = read(errpipe, buf+pending, avail);
+ if (got==-1) {
+ if (errno==EINTR) continue;
+ else if (errno==EWOULDBLOCK || errno==EAGAIN) return;
+ else diee("(stage2) errpipe read");
+ got = 0;
+ } else if (got==0) {
+ warning("program closed its stderr fd");
+ errpipe = -1;
+ return;
+ }
+ int scanned = pending;
+ pending += got;
+ int eaten = 0;
+ for (;;) {
+ const char *newline = memchr(buf+scanned, '\n', pending-scanned);
+ int printupto, eat;
+ if (newline) {
+ printupto = newline-buf;
+ eat = printupto + 1;
+ } else if (!eaten && pending==sizeof(buf)) { /* overflow */
+ printupto = pending;
+ eat = printupto;
+ } else {
+ break;
+ }
+ syslog(LOG_ERR,"stderr: %.*s", printupto-eaten, buf+eaten);
+ eaten += eat;
+ scanned = eaten;
+ }
+ pending -= eaten;
+ memmove(buf, buf+eaten, pending);
+ }
+}
+