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 2/2] spawn: better error handling
Date: Mon, 30 Dec 2019 05:04:16 +0000	[thread overview]
Message-ID: <20191230050416.6351-3-e@80x24.org> (raw)
In-Reply-To: <20191230050416.6351-1-e@80x24.org>

Since vfork always shares memory between the child and parent,
we can propagate errors to the parent errno using shared memory
instead of just dumping to stderr and hoping somebody sees it.
---
 lib/PublicInbox/Spawn.pm | 42 +++++++++++++++-------------------------
 1 file changed, 16 insertions(+), 26 deletions(-)

diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm
index d624c521..6eea2b9c 100644
--- a/lib/PublicInbox/Spawn.pm
+++ b/lib/PublicInbox/Spawn.pm
@@ -56,26 +56,10 @@ my $vfork_spawn = <<'VFORK_SPAWN';
 	dst[real_len] = 0; \
 } while (0)
 
-static void *deconst(const char *s)
-{
-	union { const char *in; void *out; } u;
-	u.in = s;
-	return u.out;
-}
-
 /* needs to be safe inside a vfork'ed process */
-static void xerr(const char *msg)
+static void exit_err(int *cerrnum)
 {
-	struct iovec iov[3];
-	const char *err = strerror(errno); /* should be safe in practice */
-
-	iov[0].iov_base = deconst(msg);
-	iov[0].iov_len = strlen(msg);
-	iov[1].iov_base = deconst(err);
-	iov[1].iov_len = strlen(err);
-	iov[2].iov_base = deconst("\n");
-	iov[2].iov_len = 1;
-	writev(2, iov, 3);
+	*cerrnum = errno;
 	_exit(1);
 }
 
@@ -95,7 +79,7 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref,
 	pid_t pid;
 	char **argv, **envp;
 	sigset_t set, old;
-	int ret, errnum;
+	int ret, perrnum, cerrnum = 0;
 
 	AV2C_COPY(argv, cmd);
 	AV2C_COPY(envp, env);
@@ -115,12 +99,12 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref,
 			if (parent_fd == child_fd)
 				continue;
 			if (dup2(parent_fd, child_fd) < 0)
-				xerr("dup2");
+				exit_err(&cerrnum);
 		}
 		for (sig = 1; sig < NSIG; sig++)
 			signal(sig, SIG_DFL); /* ignore errors on signals */
 		if (*cd && chdir(cd) < 0)
-			xerr("chdir");
+			exit_err(&cerrnum);
 
 		max = av_len(rlim);
 		for (i = 0; i < max; i += 3) {
@@ -132,7 +116,7 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref,
 			rl.rlim_cur = SvIV(*soft);
 			rl.rlim_max = SvIV(*hard);
 			if (setrlimit(SvIV(*res), &rl) < 0)
-				xerr("sertlimit");
+				exit_err(&cerrnum);
 		}
 
 		/*
@@ -140,13 +124,19 @@ int pi_fork_exec(SV *redirref, SV *file, SV *cmdref, SV *envref, SV *rlimref,
 		 * to the group taking out a subprocess
 		 */
 		execve(filename, argv, envp);
-		xerr("execve failed");
+		exit_err(&cerrnum);
 	}
-	errnum = errno;
+	perrnum = errno;
 	ret = sigprocmask(SIG_SETMASK, &old, NULL);
 	assert(ret == 0 && "BUG calling sigprocmask to restore");
-	errno = errnum;
-
+	if (cerrnum) {
+		if (pid > 0)
+			waitpid(pid, NULL, 0);
+		pid = -1;
+		errno = cerrnum;
+	} else if (perrnum) {
+		errno = perrnum;
+	}
 	return (int)pid;
 }
 VFORK_SPAWN

      parent reply	other threads:[~2019-12-30  5:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-30  5:04 [PATCH 0/2] more spawn improvements Eric Wong
2019-12-30  5:04 ` [PATCH 1/2] spawn: support chdir via -C option Eric Wong
2019-12-30  5:04 ` Eric Wong [this message]

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=20191230050416.6351-3-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).