commit: 6bcd7b2f7d9c1075df6ff103c4328ccddfb71c29 Author: Sam James <sam <AT> gentoo <DOT> org> AuthorDate: Sun Mar 16 18:15:12 2025 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Sun Mar 16 18:15:53 2025 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=6bcd7b2f
www-misc/fcgiwrap: add further fixes (for cleanup on start/exit) >From pending PRs. Signed-off-by: Sam James <sam <AT> gentoo.org> .../fcgiwrap/fcgiwrap-1.1.0_p20150419-r1.ebuild | 66 +++++ .../files/fcgiwrap-1.1.0-cleanup-startup.patch | 62 +++++ .../fcgiwrap/files/fcgiwrap-1.1.0-cleanup.patch | 269 +++++++++++++++++++++ 3 files changed, 397 insertions(+) diff --git a/www-misc/fcgiwrap/fcgiwrap-1.1.0_p20150419-r1.ebuild b/www-misc/fcgiwrap/fcgiwrap-1.1.0_p20150419-r1.ebuild new file mode 100644 index 000000000000..3704d9498fb8 --- /dev/null +++ b/www-misc/fcgiwrap/fcgiwrap-1.1.0_p20150419-r1.ebuild @@ -0,0 +1,66 @@ +# Copyright 1999-2025 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=8 + +inherit autotools systemd toolchain-funcs + +DESCRIPTION="Simple FastCGI wrapper for CGI scripts (CGI support for nginx)" +HOMEPAGE="https://github.com/gnosek/fcgiwrap" +if [[ ${PV} == *_p* ]] ; then + FCGIWRAP_COMMIT="99c942c90063c73734e56bacaa65f947772d9186" + SRC_URI="https://github.com/gnosek/fcgiwrap/archive/${FCGIWRAP_COMMIT}.tar.gz -> ${P}.gh.tar.gz" + S="${WORKDIR}"/${PN}-${FCGIWRAP_COMMIT} +else + # https://github.com/gnosek/fcgiwrap/issues/31 + SRC_URI="https://github.com/gnosek/${PN}/archive/refs/tags/${PV}.tar.gz -> ${P}.tar.gz" +fi + +LICENSE="BSD" +SLOT="0" +KEYWORDS="~amd64 ~arm ~x86" +IUSE="systemd" + +RDEPEND=" + dev-libs/fcgi + systemd? ( sys-apps/systemd:= ) +" +DEPEND="${RDEPEND}" +BDEPEND="virtual/pkgconfig" + +DOCS=( README.rst ) + +PATCHES=( + "${FILESDIR}"/${PN}-1.1.0-kill.patch + "${FILESDIR}"/${PN}-1.1.0-systemd.patch + "${FILESDIR}"/${PN}-1.1.0-uninit-ipv6.patch + "${FILESDIR}"/${PN}-1.1.0-cleanup.patch + "${FILESDIR}"/${PN}-1.1.0-cleanup-startup.patch +) + +src_prepare() { + default + + sed -e "s/-Werror//" \ + -i configure.ac || die "sed failed" + sed -e '/man8dir = $(DESTDIR)/s/@prefix@//' \ + -i Makefile.in || die "sed failed" + + tc-export CC + + # Fix systemd units for Gentoo + sed -i -e '/User/d' systemd/fcgiwrap.service || die + sed -i -e '/Group/d' systemd/fcgiwrap.service || die + + eautoreconf +} + +src_configure() { + econf \ + $(use_with systemd) \ + --with-systemdsystemunitdir="$(systemd_get_systemunitdir)" +} + +pkg_postinst() { + einfo "You may want to install www-servers/spawn-fcgi to use with fcgiwrap." +} diff --git a/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup-startup.patch b/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup-startup.patch new file mode 100644 index 000000000000..a354219af016 --- /dev/null +++ b/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup-startup.patch @@ -0,0 +1,62 @@ +https://github.com/gnosek/fcgiwrap/pull/52 + +From 1d8bacb3145cf1aed2d6b7f7e725db5b424eb8ec Mon Sep 17 00:00:00 2001 +From: Andy Fiddaman <[email protected]> +Date: Fri, 17 Apr 2020 13:41:46 +0000 +Subject: [PATCH] Clean up any stale UNIX domain socket on start + +--- + fcgiwrap.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/fcgiwrap.c b/fcgiwrap.c +index b44d8aa..5ee2327 100644 +--- a/fcgiwrap.c ++++ b/fcgiwrap.c +@@ -727,6 +727,8 @@ static int setup_socket(char *url) { + } sa; + + if (!strncmp(p, "unix:", sizeof("unix:") - 1)) { ++ struct stat st; ++ + p += sizeof("unix:") - 1; + + if (strlen(p) >= UNIX_PATH_MAX) { +@@ -738,6 +740,36 @@ static int setup_socket(char *url) { + sockaddr_size = sizeof sa.sa_un; + sa.sa_un.sun_family = AF_UNIX; + strcpy(sa.sa_un.sun_path, p); ++ ++ if (stat(p, &st) != -1) { ++ /* Socket already exists. See if it is still alive. */ ++ struct sockaddr_un server; ++ int fd; ++ ++ memset((char *)&server, '\0', ++ sizeof(struct sockaddr_un)); ++ server.sun_family = AF_UNIX; ++ strlcpy(server.sun_path, p, sizeof(server.sun_path)); ++ ++ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) != -1) { ++ if (connect(fd, (struct sockaddr *)&server, ++ sizeof(struct sockaddr_un)) >= 0) { ++ close(fd); ++ fprintf(stderr, ++ "Socket %s is in use by " ++ "another process.\n", p); ++ return -1; ++ } ++ close(fd); ++ } ++ ++ fprintf(stderr, "Removing stale socket %s.\n", p); ++ if (unlink(p) == -1) { ++ fprintf(stderr, ++ "Could not unlink stale socket %s\n", p); ++ return -1; ++ } ++ } + } else if (!strncmp(p, "tcp:", sizeof("tcp:") - 1)) { + p += sizeof("tcp:") - 1; + + diff --git a/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup.patch b/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup.patch new file mode 100644 index 000000000000..3e5179aee4cc --- /dev/null +++ b/www-misc/fcgiwrap/files/fcgiwrap-1.1.0-cleanup.patch @@ -0,0 +1,269 @@ +https://github.com/gnosek/fcgiwrap/pull/60 + +From 93ce8e8489bda4a7ebe5161020c83a68f744481f Mon Sep 17 00:00:00 2001 +From: flu0r1ne <[email protected]> +Date: Sat, 9 Sep 2023 22:56:05 -0500 +Subject: [PATCH 1/4] Fix implicit fallthrough false positive, noreturn + +With warnings and pedantic mode enabled, `gcc (GCC) 13.2.1` returns +an implicit fall through warning. This can be fixed by annotating +the error function with NORETURN. +--- + fcgiwrap.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fcgiwrap.c b/fcgiwrap.c +index b44d8aa..8310284 100644 +--- a/fcgiwrap.c ++++ b/fcgiwrap.c +@@ -56,6 +56,12 @@ + #define UNIX_PATH_MAX 108 + #endif + ++#if defined(__GNUC__) || defined(__clang__) ++# define NORETURN __attribute__((__noreturn__)) ++#else ++# define NORETURN ++#endif ++ + extern char **environ; + static char * const * inherited_environ; + static const char **allowed_programs; +@@ -500,7 +506,7 @@ static bool is_allowed_program(const char *program) { + return false; + } + +-static void cgi_error(const char *message, const char *reason, const char *filename) ++static void NORETURN cgi_error(const char *message, const char *reason, const char *filename) + { + printf("Status: %s\r\nContent-Type: text/plain\r\n\r\n%s\r\n", + message, message); + +From 8b8aae2ac99bc91a72a32ca2040302f785e10e2b Mon Sep 17 00:00:00 2001 +From: flu0r1ne <[email protected]> +Date: Sun, 10 Sep 2023 03:50:27 -0500 +Subject: [PATCH 2/4] close() always results in a duplicate call + +Remove close as it always results in a duplicated call, simplify logic +--- + fcgiwrap.c | 27 ++++++++++++++++----------- + 1 file changed, 16 insertions(+), 11 deletions(-) + +diff --git a/fcgiwrap.c b/fcgiwrap.c +index 8310284..cfb7797 100644 +--- a/fcgiwrap.c ++++ b/fcgiwrap.c +@@ -62,6 +62,8 @@ + # define NORETURN + #endif + ++#define FCGI_FD 0 ++ + extern char **environ; + static char * const * inherited_environ; + static const char **allowed_programs; +@@ -706,8 +708,8 @@ static int listen_on_fd(int fd) { + perror("Failed to enable SO_REUSEADDR"); + return -1; + } +- if (dup2(fd, 0) < 0) { +- perror("Failed to move socket to fd 0"); ++ if (dup2(fd, FCGI_FD) < 0) { ++ fprintf(stderr, "Failed to move socket to fd %d", FCGI_FD); + return -1; + } + if (close(fd) < 0) { +@@ -809,7 +811,7 @@ int main(int argc, char **argv) + { + int nchildren = 1; + char *socket_url = NULL; +- int fd = 0; ++ int fd = FCGI_FD; + int c; + + while ((c = getopt(argc, argv, "c:hfs:p:")) != -1) { +@@ -860,6 +862,10 @@ int main(int argc, char **argv) + + #ifdef HAVE_SYSTEMD + if (sd_listen_fds(true) > 0) { ++ if(socket_url) { ++ perror("warning: a systemd socket has been provding, ignoring '-s'\n"); ++ } ++ + /* systemd woke us up. we should never see more than one FD passed to us. */ + if (listen_on_fd(SD_LISTEN_FDS_START) < 0) { + return 1; +@@ -876,16 +882,15 @@ int main(int argc, char **argv) + prefork(nchildren); + fcgiwrap_main(); + +- if (fd) { +- const char *p = socket_url; +- close(fd); ++ close(FCGI_FD); + +- if (socket_url) { +- if (!strncmp(p, "unix:", sizeof("unix:") - 1)) { +- p += sizeof("unix:") - 1; +- unlink(p); +- } ++ if (fd && socket_url) { // fd > 0 indicates a socket was setup by us ++ const char *p = socket_url; ++ if (!strncmp(p, "unix:", sizeof("unix:") - 1)) { ++ p += sizeof("unix:") - 1; ++ unlink(p); + } + } ++ + return 0; + } + +From b4f2469369960fb914c1d1eb4942feebf648835a Mon Sep 17 00:00:00 2001 +From: flu0r1ne <[email protected]> +Date: Sun, 10 Sep 2023 04:14:17 -0500 +Subject: [PATCH 3/4] Add better error handling for socket setup + +--- + fcgiwrap.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/fcgiwrap.c b/fcgiwrap.c +index cfb7797..5b8af47 100644 +--- a/fcgiwrap.c ++++ b/fcgiwrap.c +@@ -793,18 +793,30 @@ static int setup_socket(char *url) { + fd = socket(sa.sa.sa_family, SOCK_STREAM, 0); + if (fd < 0) { + perror("Failed to create socket"); +- return -1; ++ goto cleanup_socket; + } + if (bind(fd, &sa.sa, sockaddr_size) < 0) { + perror("Failed to bind"); +- return -1; ++ goto cleanup_fd; + } + + if (listen_on_fd(fd) < 0) { +- return -1; ++ goto cleanup_fd; + } + + return fd; ++ ++cleanup_fd: ++ ++ close(fd); ++ ++cleanup_socket: ++ ++ if(sa.sa.sa_family == AF_UNIX) { ++ unlink(sa.sa_un.sun_path); ++ } ++ ++ return -1; + } + + int main(int argc, char **argv) + +From 2870d2729a3930988f0041e2d78fec672e69afac Mon Sep 17 00:00:00 2001 +From: flu0r1ne <[email protected]> +Date: Sun, 10 Sep 2023 04:36:16 -0500 +Subject: [PATCH 4/4] Kill all child processes on parent SIGTERM + +When attached to a terminal, a SIGINT signal is sent to the parent +and all children, instructing them to exit. In some environments including +docker, only the parent receives the SIGTERM and is responsible for +propagating it to the children. This patch kills all child processes +when the parent receives a SIGTERM or a SIGINT. +--- + fcgiwrap.c | 38 ++++++++++++++++++++++++++++---------- + 1 file changed, 28 insertions(+), 10 deletions(-) + +diff --git a/fcgiwrap.c b/fcgiwrap.c +index 5b8af47..123d279 100644 +--- a/fcgiwrap.c ++++ b/fcgiwrap.c +@@ -62,6 +62,12 @@ + # define NORETURN + #endif + ++#if defined(__GNUC__) ++# define UNUSED __attribute__((__unused__)) ++#else ++# define UNUSED ++#endif ++ + #define FCGI_FD 0 + + extern char **environ; +@@ -646,6 +652,8 @@ static void fcgiwrap_main(void) + while (FCGI_Accept() >= 0 && !sigint_received) { + handle_fcgi_request(); + } ++ ++ close(FCGI_FD); + } + + static volatile sig_atomic_t nrunning; +@@ -665,21 +673,26 @@ static void sigchld_handler(int dummy) + } + } + ++static volatile sig_atomic_t stop_requested; ++ ++static void stop_request_handler(int UNUSED signum) { ++ stop_requested = 1; ++} ++ + static void prefork(int nchildren) + { + int startup = 1; + +- if (nchildren == 1) { +- return; +- } +- + signal(SIGCHLD, sigchld_handler); ++ signal(SIGINT, stop_request_handler); ++ signal(SIGTERM, stop_request_handler); + +- while (1) { ++ while (!stop_requested) { + while (nrunning < nchildren) { + pid_t pid = fork(); + if (pid == 0) { +- return; ++ fcgiwrap_main(); ++ exit(0); + } else if (pid != -1) { + nrunning++; + } else { +@@ -695,6 +708,10 @@ static void prefork(int nchildren) + startup = 0; + pause(); + } ++ ++ if(killpg(0, SIGTERM) != 0) { ++ fprintf(stderr, "killpg() encountered an error, child processes may have to be killed"); ++ } + } + + static int listen_on_fd(int fd) { +@@ -891,10 +908,11 @@ int main(int argc, char **argv) + } + } + +- prefork(nchildren); +- fcgiwrap_main(); +- +- close(FCGI_FD); ++ if(nchildren > 1) { ++ prefork(nchildren); ++ } else { ++ fcgiwrap_main(); ++ } + + if (fd && socket_url) { // fd > 0 indicates a socket was setup by us + const char *p = socket_url; +
