about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-11-26 20:07:45 +0000
committerEric Wong <e@80x24.org>2023-11-27 03:51:09 +0000
commit77dfab7bd3d8e503d3ba196480f3ffa96bedcd48 (patch)
treefaddfaeea38cd2a17c321bdb5c48f458f68dff06 /lib/PublicInbox
parent13a7f10e585b0816e375f134f00a1d2fe9af4bd3 (diff)
downloadpublic-inbox-77dfab7bd3d8e503d3ba196480f3ffa96bedcd48.tar.gz
It's not async-signal-safe and the glibc implementation uses
malloc via asnprintf.  Practically it's not a problem unless the
kernel OOMs and the write(2) fails to the self-pipe.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/xap_helper.h29
1 files changed, 12 insertions, 17 deletions
diff --git a/lib/PublicInbox/xap_helper.h b/lib/PublicInbox/xap_helper.h
index b6b517d5..1d8437c9 100644
--- a/lib/PublicInbox/xap_helper.h
+++ b/lib/PublicInbox/xap_helper.h
@@ -980,7 +980,8 @@ static void sigp(int sig) // parent signal handler
 {
         static const char eagain[] = "signals coming in too fast";
         static const char bad_sig[] = "BUG: bad sig\n";
-        static const char write_err[] = "BUG: sigp write: ";
+        static const char write_errno[] = "BUG: sigp write (errno)";
+        static const char write_zero[] = "BUG: sigp write wrote zero bytes";
         char c = 0;
 
         switch (sig) {
@@ -992,23 +993,17 @@ static void sigp(int sig) // parent signal handler
                 _exit(EXIT_FAILURE);
         }
         ssize_t w = write(pipefds[1], &c, 1);
-        if (w == sizeof(c)) return;
-        int e = 0;
-        if (w < 0) {
-                e = errno;
-                if (e == EAGAIN) {
-                        write(STDERR_FILENO, eagain, sizeof(eagain) - 1);
-                        return;
-                }
+        if (w > 0) return;
+        if (w < 0 && errno == EAGAIN) {
+                write(STDERR_FILENO, eagain, sizeof(eagain) - 1);
+                return;
+        } else if (w == 0) {
+                write(STDERR_FILENO, write_zero, sizeof(write_zero) - 1);
+        } else {
+                // strerror isn't technically async-signal-safe, and
+                // strerrordesc_np+strerrorname_np isn't portable
+                write(STDERR_FILENO, write_errno, sizeof(write_errno) - 1);
         }
-        struct iovec iov[3];
-        iov[0].iov_base = (void *)write_err;
-        iov[0].iov_len = sizeof(write_err) - 1;
-        iov[1].iov_base = (void *)(e ? strerror(e) : "zero write");
-        iov[1].iov_len = strlen((const char *)iov[1].iov_base);
-        iov[2].iov_base = (void *)"\n";
-        iov[2].iov_len = 1;
-        (void)writev(STDERR_FILENO, iov, MY_ARRAY_SIZE(iov));
         _exit(EXIT_FAILURE);
 }