about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2022-12-15 20:52:50 +0000
committerEric Wong <mwrap-perl@80x24.org>2022-12-16 09:27:46 +0000
commit2893718d16b1c10832d5d3c52db5472274cf35d0 (patch)
tree02990a452866ea63728bcc747e2f3bedf8ebe736
parent715e016a6736c81a0b2a7f19d964dd5db945e056 (diff)
downloadmwrap-2893718d16b1c10832d5d3c52db5472274cf35d0.tar.gz
Instead, we'll leak memory if the pthread_atfork handlers can't
stop httpd at fork due to resource limitations.
-rw-r--r--mwrap_httpd.h23
1 files changed, 16 insertions, 7 deletions
diff --git a/mwrap_httpd.h b/mwrap_httpd.h
index f484bdd..fc096c0 100644
--- a/mwrap_httpd.h
+++ b/mwrap_httpd.h
@@ -1094,6 +1094,12 @@ static int h1d_init(struct mw_h1d *h1d, const char *menv)
         memcpy(h1d->pid_str, p, h1d->pid_len);
         if (unlink(sa.un.sun_path) < 0 && errno != ENOENT)
                 return fprintf(stderr, "unlink(%s): %m\n", sa.un.sun_path);
+        /*
+         * lfd may be >=0 if h1d_stop_join failed in parent and we're now
+         * running in a forked child
+         */
+        if (h1d->lfd >= 0)
+                (void)close(h1d->lfd);
         h1d->lfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
         if (h1d->lfd < 0)
                 return fprintf(stderr, "socket: %m\n");
@@ -1204,25 +1210,28 @@ static void h1d_stop_join(struct mw_h1d *h1d)
         socklen_t len = (socklen_t)sizeof(sa);
         int e, sfd;
         void *ret;
+#define ERR ": %m (can't stop mwrap-httpd before fork)\n"
 
         mwrap_assert(uatomic_read(&h1d->alive) == 0);
         if (getsockname(h1d->lfd, &sa.any, &len) < 0) {
-                fprintf(stderr, "getsockname: %m\n");
-                abort(); /* TODO: graceful fallback (ENOBUFS) */
+                fprintf(stderr, "getsockname"ERR);
+                return;
         }
         sfd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
         if (sfd < 0) {
-                fprintf(stderr, "socket: %m\n");
-                abort(); /* TODO: graceful fallback (ENOMEM, EMFILE, ...) */
+                fprintf(stderr, "socket"ERR);
+                return;
         }
         if (connect(sfd, &sa.any, len) < 0) {
-                fprintf(stderr, "connect: %m\n");
-                /* TODO: graceful fallback (EAGAIN, ...) */
+                fprintf(stderr, "connect"ERR);
+                close(sfd);
+                return;
         }
+#undef ERR
         (void)close(sfd);
         e = pthread_join(h1d->tid, &ret);
         if (e) {
-                fprintf(stderr, "pthread_join: %s\n", strerror(e));
+                fprintf(stderr, "BUG? pthread_join: %s\n", strerror(e));
                 abort();
         }
         (void)close(h1d->lfd);