about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/PublicInbox/Config.pm2
-rw-r--r--lib/PublicInbox/Git.pm5
-rw-r--r--lib/PublicInbox/Qspawn.pm2
-rw-r--r--lib/PublicInbox/Spawn.pm8
-rw-r--r--lib/PublicInbox/SpawnPP.pm6
-rwxr-xr-xscript/public-inbox-mda1
6 files changed, 19 insertions, 5 deletions
diff --git a/lib/PublicInbox/Config.pm b/lib/PublicInbox/Config.pm
index ea84da35..ddb4f6b1 100644
--- a/lib/PublicInbox/Config.pm
+++ b/lib/PublicInbox/Config.pm
@@ -94,7 +94,7 @@ sub git_config_dump {
         my ($in, $out);
         my @cmd = (qw/git config/, "--file=$file", '-l');
         my $cmd = join(' ', @cmd);
-        my $fh = popen_rd(\@cmd);
+        my $fh = popen_rd(\@cmd) or die "popen_rd failed for $file: $!\n";
         my %rv;
         local $/ = "\n";
         foreach my $line (<$fh>) {
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index bc0e5064..f47bc439 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -28,7 +28,9 @@ sub _bidi_pipe {
 
         my @cmd = ('git', "--git-dir=$self->{git_dir}", qw(cat-file), $batch);
         my $redir = { 0 => fileno($out_r), 1 => fileno($in_w) };
-        $self->{$pid} = spawn(\@cmd, undef, $redir);
+        my $p = spawn(\@cmd, undef, $redir);
+        defined $p or fail($self, "spawn failed: $!");
+        $self->{$pid} = $p;
         $out_w->autoflush(1);
         $self->{$out} = $out_w;
         $self->{$in} = $in_r;
@@ -122,6 +124,7 @@ sub popen {
 sub qx {
         my ($self, @cmd) = @_;
         my $fh = $self->popen(@cmd);
+        defined $fh or return;
         local $/ = "\n";
         return <$fh> if wantarray;
         local $/;
diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm
index 9e4c8e08..9299096a 100644
--- a/lib/PublicInbox/Qspawn.pm
+++ b/lib/PublicInbox/Qspawn.pm
@@ -17,7 +17,7 @@ sub _do_spawn {
         my ($self, $cb) = @_;
         my $err;
         ($self->{rpipe}, $self->{pid}) = popen_rd(@{$self->{args}});
-        if ($self->{pid}) {
+        if (defined $self->{pid}) {
                 $running++;
         } else {
                 $self->{err} = $!;
diff --git a/lib/PublicInbox/Spawn.pm b/lib/PublicInbox/Spawn.pm
index 83730302..41b08a33 100644
--- a/lib/PublicInbox/Spawn.pm
+++ b/lib/PublicInbox/Spawn.pm
@@ -84,7 +84,7 @@ int public_inbox_fork_exec(int in, int out, int err,
         char **argv, **envp;
         I32 max;
         sigset_t set, old;
-        int ret;
+        int ret, errnum;
 
         argv = AV_ALLOCA(cmd, max);
         av2c_copy(argv, cmd, max);
@@ -112,8 +112,10 @@ int public_inbox_fork_exec(int in, int out, int err,
                 execve(filename, argv, envp);
                 xerr("execve failed");
         }
+        errnum = errno;
         ret = sigprocmask(SIG_SETMASK, &old, NULL);
         assert(ret == 0 && "BUG calling sigprocmask to restore");
+        errno = errnum;
 
         return (int)pid;
 }
@@ -180,7 +182,8 @@ sub spawn ($;$$) {
         my $in = $opts->{0} || 0;
         my $out = $opts->{1} || 1;
         my $err = $opts->{2} || 2;
-        public_inbox_fork_exec($in, $out, $err, $f, $cmd, \@env);
+        my $pid = public_inbox_fork_exec($in, $out, $err, $f, $cmd, \@env);
+        $pid < 0 ? undef : $pid;
 }
 
 sub popen_rd {
@@ -191,6 +194,7 @@ sub popen_rd {
         IO::Handle::blocking($r, $blocking) if defined $blocking;
         $opts->{1} = fileno($w);
         my $pid = spawn($cmd, $env, $opts);
+        return unless defined $pid;
         return ($r, $pid) if wantarray;
         my $ret = gensym;
         tie *$ret, 'PublicInbox::ProcessPipe', $pid, $r;
diff --git a/lib/PublicInbox/SpawnPP.pm b/lib/PublicInbox/SpawnPP.pm
index 36223e81..179aba5e 100644
--- a/lib/PublicInbox/SpawnPP.pm
+++ b/lib/PublicInbox/SpawnPP.pm
@@ -12,7 +12,12 @@ sub public_inbox_fork_exec ($$$$$$) {
         my $set = POSIX::SigSet->new();
         $set->fillset or die "fillset failed: $!";
         sigprocmask(SIG_SETMASK, $set, $old) or die "can't block signals: $!";
+        my $syserr;
         my $pid = fork;
+        unless (defined $pid) { # compat with Inline::C version
+                $syserr = $!;
+                $pid = -1;
+        }
         if ($pid == 0) {
                 if ($in != 0) {
                         dup2($in, 0) or die "dup2 failed for stdin: $!";
@@ -34,6 +39,7 @@ sub public_inbox_fork_exec ($$$$$$) {
                 }
         }
         sigprocmask(SIG_SETMASK, $old) or die "can't unblock signals: $!";
+        $! = $syserr;
         $pid;
 }
 
diff --git a/script/public-inbox-mda b/script/public-inbox-mda
index 145aa710..013642d0 100755
--- a/script/public-inbox-mda
+++ b/script/public-inbox-mda
@@ -97,6 +97,7 @@ sub do_spamc {
         my ($in, $out) = @_;
         my $rdr = { 0 => fileno($in) };
         my ($fh, $pid) = popen_rd([qw/spamc -E --headers/], undef, $rdr);
+        defined $pid or die "failed to popen_rd spamc: $!\n";
         my $r;
         do {
                 $r = sysread($fh, $$out, 65536, length($$out));