user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH 6/7] xap_helper.h: limit stderr assignment to glibc+FreeBSD
Date: Wed, 30 Aug 2023 05:10:44 +0000	[thread overview]
Message-ID: <20230830051045.330641-7-e@80x24.org> (raw)
In-Reply-To: <20230830051045.330641-1-e@80x24.org>

This fixes the C++ xap_helper compilation on OpenBSD.
Assignable `FILE *' pointers appear to only be supported on
FreeBSD and glibc.  Based on my reading of musl and NetBSD
source code, this should also fix builds on those platforms.
---
 lib/PublicInbox/xap_helper.h | 55 ++++++++++++++++++++++++++++++++----
 1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/lib/PublicInbox/xap_helper.h b/lib/PublicInbox/xap_helper.h
index e10527d1..92210511 100644
--- a/lib/PublicInbox/xap_helper.h
+++ b/lib/PublicInbox/xap_helper.h
@@ -50,9 +50,18 @@
 #	define SET_MAX_EXPANSION set_max_wildcard_expansion
 #endif
 
+#if defined(__FreeBSD__) || defined(__GLIBC__)
+#	define STDERR_ASSIGNABLE (1)
+#else
+#	define STDERR_ASSIGNABLE (0)
+#endif
+
 static const int sock_fd = 0; // SOCK_SEQPACKET as stdin :P
 static pid_t parent_pid;
+#if STDERR_ASSIGNABLE
 static FILE *orig_err = stderr;
+#endif
+static int orig_err_fd = -1;
 static void *srch_tree; // tsearch + tdelete + twalk
 static pid_t *worker_pids; // nr => pid
 static unsigned long nworker;
@@ -820,6 +829,37 @@ static void cleanup_pids(void)
 	worker_pids = NULL;
 }
 
+static void stderr_set(FILE *tmp_err)
+{
+#if STDERR_ASSIGNABLE
+	if (my_setlinebuf(tmp_err))
+		perror("W: setlinebuf(tmp_err)");
+	stderr = tmp_err;
+	return;
+#endif
+	int fd = fileno(tmp_err);
+	if (fd < 0) err(EXIT_FAILURE, "BUG: fileno(tmp_err)");
+	while (dup2(fd, STDERR_FILENO) < 0) {
+		if (errno != EINTR)
+			err(EXIT_FAILURE, "dup2(%d => 2)", fd);
+	}
+}
+
+static void stderr_restore(FILE *tmp_err)
+{
+#if STDERR_ASSIGNABLE
+	stderr = orig_err;
+	return;
+#endif
+	if (ferror(stderr) | fflush(stderr))
+		perror("ferror|fflush stderr");
+	while (dup2(orig_err_fd, STDERR_FILENO) < 0) {
+		if (errno != EINTR)
+			err(EXIT_FAILURE, "dup2(%d => 2)", orig_err_fd);
+	}
+	clearerr(stderr);
+}
+
 static void recv_loop(void) // worker process loop
 {
 	static char rbuf[4096 * 33]; // per-process
@@ -828,18 +868,15 @@ static void recv_loop(void) // worker process loop
 		struct req req = {};
 		if (!recv_req(&req, rbuf, &len))
 			continue;
-		if (req.fp[1]) {
-			if (my_setlinebuf(req.fp[1]))
-				perror("W: setlinebuf(req.fp[1])");
-			stderr = req.fp[1];
-		}
+		if (req.fp[1])
+			stderr_set(req.fp[1]);
 		req.argc = (int)SPLIT2ARGV(req.argv, rbuf, len);
 		if (req.argc > 0)
 			dispatch(&req);
 		if (ferror(req.fp[0]) | fclose(req.fp[0]))
 			perror("ferror|fclose fp[0]");
 		if (req.fp[1]) {
-			stderr = orig_err;
+			stderr_restore(req.fp[1]);
 			if (ferror(req.fp[1]) | fclose(req.fp[1]))
 				perror("ferror|fclose fp[1]");
 		}
@@ -895,6 +932,12 @@ int main(int argc, char *argv[])
 	code_nrp_init();
 	atexit(cleanup_all);
 
+	if (!STDERR_ASSIGNABLE) {
+		orig_err_fd = dup(STDERR_FILENO);
+		if (orig_err_fd < 0)
+			err(EXIT_FAILURE, "dup(2)");
+	}
+
 	nworker = 0;
 #ifdef _SC_NPROCESSORS_ONLN
 	long j = sysconf(_SC_NPROCESSORS_ONLN);

  parent reply	other threads:[~2023-08-30  5:10 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-30  5:10 [PATCH 0/7] various build fixes + OpenBSD compat Eric Wong
2023-08-30  5:10 ` [PATCH 1/7] treewide: drop MSG_EOR with AF_UNIX+SOCK_SEQPACKET Eric Wong
2023-08-30  5:10 ` [PATCH 2/7] Makefile.PL: fix syntax for ASan and valgrind targets Eric Wong
2023-08-30  5:10 ` [PATCH 3/7] Makefile.PL: depend on autodie, at least for tests Eric Wong
2023-08-30  5:10 ` [PATCH 4/7] t/kqnotify: improve test reliability on OpenBSD Eric Wong
2023-08-30  5:10 ` [PATCH 5/7] xap_helper.h: don't compress debug sections " Eric Wong
2023-08-30  5:10 ` Eric Wong [this message]
2023-08-30  5:10 ` [PATCH 7/7] xap_helper.h: fix double-free on OpenBSD hdestroy Eric Wong
2023-08-30 12:34 ` [PATCH 0/7] various build fixes + OpenBSD compat, " Štěpán Němec
2023-08-30 21:18   ` Eric Wong
2023-08-31  9:11     ` Štěpán Němec
2023-08-31 17:26       ` Štěpán Němec
2023-09-01 11:09         ` Eric Wong
2023-09-02 10:54           ` Štěpán Němec
2023-09-02 11:07             ` [PATCH v2] Clarify Inline::C dependency (optional on Linux, required elsewhere) Štěpán Němec
2023-09-02 18:50               ` Eric Wong
2023-09-02 19:08                 ` Štěpán Němec
2023-09-02 19:44                   ` Eric Wong
2023-09-02 20:45                     ` Štěpán Němec
2023-09-02 20:56                       ` Eric Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230830051045.330641-7-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).