]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
spawn: add run_wait to simplify spawn+waitpid use
authorEric Wong <e@80x24.org>
Tue, 26 Sep 2023 07:44:40 +0000 (07:44 +0000)
committerEric Wong <e@80x24.org>
Tue, 26 Sep 2023 21:02:48 +0000 (21:02 +0000)
It's basically the `system' perlop with support for env overrides,
redirects, chdir, rlimits, and setpgid support.

lib/PublicInbox/Fetch.pm
lib/PublicInbox/LEI.pm
lib/PublicInbox/LeiBlob.pm
lib/PublicInbox/LeiMailDiff.pm
lib/PublicInbox/LeiMirror.pm
lib/PublicInbox/LeiRediff.pm
lib/PublicInbox/SearchIdx.pm
lib/PublicInbox/Spamcheck/Spamc.pm
lib/PublicInbox/Spawn.pm
lib/PublicInbox/TestCommon.pm

index 8f3a87e22d799f74971fbd617f1772f0b94118e8..6e9b1e94ef53cb2ef47c9087ee919dee1b02f84b 100644 (file)
@@ -5,7 +5,7 @@ package PublicInbox::Fetch;
 use v5.12;
 use parent qw(PublicInbox::IPC);
 use URI ();
-use PublicInbox::Spawn qw(popen_rd run_die spawn);
+use PublicInbox::Spawn qw(popen_rd run_wait);
 use PublicInbox::Admin;
 use PublicInbox::LEI;
 use PublicInbox::LeiCurl;
@@ -133,9 +133,8 @@ sub do_fetch { # main entry point
                                warn "W: $edir missing remote.*.url\n";
                                my $o = { -C => $edir };
                                $o->{1} = $o->{2} = $lei->{2};
-                               my $pid = spawn([qw(git config -l)], undef, $o);
-                               waitpid($pid, 0);
-                               $lei->child_error($?) if $?;
+                               run_wait([qw(git config -l)], undef, $o) and
+                                       $lei->child_error($?);
                        }
                }
                @epochs = grep { !$skip->{$_} } @epochs if $skip;
index 432ae61ea887a8784ae225e5eab0bf48e0b589b0..2f8d7a96aa8a107ac2a90ba340025b91a779f6a6 100644 (file)
@@ -18,7 +18,7 @@ use IO::Handle ();
 use Fcntl qw(SEEK_SET);
 use PublicInbox::Config;
 use PublicInbox::Syscall qw(EPOLLIN);
-use PublicInbox::Spawn qw(spawn popen_rd);
+use PublicInbox::Spawn qw(run_wait popen_rd);
 use PublicInbox::Lock;
 use PublicInbox::Eml;
 use PublicInbox::Import;
@@ -905,8 +905,7 @@ sub _config {
        }
        my $cmd = $cfg->config_cmd(\%env, \%opt);
        push @$cmd, @file_arg, @argv;
-       waitpid(spawn($cmd, \%env, \%opt), 0);
-       $? == 0 ? 1 : ($err_ok ? undef : fail($self, $?));
+       run_wait($cmd, \%env, \%opt) ? ($err_ok ? undef : fail($self, $?)) : 1;
 }
 
 sub lei_daemon_pid { puts shift, $$ }
index 1d8267c86261fe55ce5cef02ecb9c4628b07084d..8df83b1dfa520fe1bbd319771e49491f6bb468cd 100644 (file)
@@ -7,7 +7,7 @@ package PublicInbox::LeiBlob;
 use strict;
 use v5.10.1;
 use parent qw(PublicInbox::IPC);
-use PublicInbox::Spawn qw(spawn popen_rd which);
+use PublicInbox::Spawn qw(run_wait popen_rd which);
 use PublicInbox::DS;
 
 sub get_git_dir ($$) {
@@ -43,8 +43,7 @@ sub solver_user_cb { # called by solver when done
 
        my $cmd = [ 'git', "--git-dir=$gd", 'show', $oid ];
        my $rdr = { 1 => $lei->{1}, 2 => $lei->{2} };
-       waitpid(spawn($cmd, $lei->{env}, $rdr), 0);
-       $lei->child_error($?) if $?;
+       run_wait($cmd, $lei->{env}, $rdr) and $lei->child_error($?);
 }
 
 sub do_solve_blob { # via wq_do
@@ -125,12 +124,9 @@ sub lei_blob {
                        require PublicInbox::Eml;
                        my $buf = do { local $/; <$fh> };
                        return extract_attach($lei, $blob, \$buf) if close($fh);
-               } else {
-                       $rdr->{1} = $lei->{1};
-                       waitpid(spawn($cmd, $lei->{env}, $rdr), 0);
                }
-               my $ce = $?;
-               return if $ce == 0;
+               $rdr->{1} = $lei->{1};
+               my $cerr = run_wait($cmd, $lei->{env}, $rdr) or return;
                my $lms = $lei->lms;
                if (my $bref = $lms ? $lms->local_blob($blob, 1) : undef) {
                        defined($lei->{-attach_idx}) and
@@ -139,7 +135,7 @@ sub lei_blob {
                } elsif ($opt->{mail}) {
                        my $eh = $rdr->{2};
                        seek($eh, 0, 0);
-                       return $lei->child_error($ce, do { local $/; <$eh> });
+                       return $lei->child_error($cerr, do { local $/; <$eh> });
                } # else: fall through to solver below
        }
 
index c813144fb3af02f33c121caaa552e9676389abc2..5e2e4b0b1468f0178600319cbecf8f0c60c6bee2 100644 (file)
@@ -6,7 +6,7 @@
 package PublicInbox::LeiMailDiff;
 use v5.12;
 use parent qw(PublicInbox::IPC PublicInbox::LeiInput PublicInbox::MailDiff);
-use PublicInbox::Spawn qw(spawn which);
+use PublicInbox::Spawn qw(run_wait);
 use File::Path ();
 require PublicInbox::LeiRediff;
 
@@ -20,9 +20,7 @@ sub diff_a ($$) {
        push @$cmd, qw(-- a), "N$self->{nr}";
        my $rdr = { -C => "$self->{tmp}" };
        @$rdr{1, 2} = @$lei{1, 2};
-       my $pid = spawn($cmd, $lei->{env}, $rdr);
-       waitpid($pid, 0);
-       $lei->child_error($?) if $?; # for git diff --exit-code
+       run_wait($cmd, $lei->{env}, $rdr) and $lei->child_error($?);
        File::Path::remove_tree($self->{curdir});
 }
 
index fed6b66814368ee087a1069947ca20f955a4183a..c99bafc36fed30cb3410dd7d5c71373c93a25124 100644 (file)
@@ -7,7 +7,7 @@ use v5.12;
 use parent qw(PublicInbox::IPC);
 use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
 use IO::Compress::Gzip qw(gzip $GzipError);
-use PublicInbox::Spawn qw(popen_rd spawn run_die);
+use PublicInbox::Spawn qw(popen_rd spawn run_wait run_die);
 use File::Path ();
 use File::Temp ();
 use File::Spec ();
@@ -251,8 +251,7 @@ sub index_cloned_inbox {
 sub run_reap {
        my ($lei, $cmd, $opt) = @_;
        $lei->qerr("# @$cmd");
-       waitpid(spawn($cmd, undef, $opt), 0) // die "waitpid: $!";
-       my $ret = $?;
+       my $ret = run_wait($cmd, undef, $opt);
        $? = 0; # don't let it influence normal exit
        $ret;
 }
@@ -424,8 +423,7 @@ sub fgrp_fetch_all {
                        my $c = [ @$cmd, '--unset-all', $_ ];
                        $self->{lei}->qerr("# @$c");
                        next if $self->{dry_run};
-                       my $pid = spawn($c, undef, $opt);
-                       waitpid($pid, 0) // die "waitpid: $!";
+                       run_wait($c, undef, $opt);
                        die "E: @$c \$?=$?" if ($? && ($? >> 8) != 5);
                }
 
index 9cf95c080bf380f39d97ed6bcb97fd7fe2b8984d..824289d60b6e8c6dcd0109ed30ae190804687d8b 100644 (file)
@@ -7,7 +7,7 @@ use strict;
 use v5.10.1;
 use parent qw(PublicInbox::IPC PublicInbox::LeiInput);
 use File::Temp 0.19 (); # 0.19 for ->newdir
-use PublicInbox::Spawn qw(spawn which);
+use PublicInbox::Spawn qw(run_wait spawn which);
 use PublicInbox::MsgIter qw(msg_part_text);
 use PublicInbox::ViewDiff;
 use PublicInbox::LeiBlob;
@@ -136,9 +136,8 @@ EOM
        $lei->qerr("# git @$cmd");
        push @$cmd, qw(A B);
        unshift @$cmd, 'git', "--git-dir=$rw->{git_dir}";
-       $pid = spawn($cmd, $lei->{env}, { 2 => $lei->{2}, 1 => $lei->{1} });
-       waitpid($pid, 0);
-       $lei->child_error($?) if $?; # for git diff --exit-code
+       run_wait($cmd, $lei->{env}, { 2 => $lei->{2}, 1 => $lei->{1} }) and
+               $lei->child_error($?); # for git diff --exit-code
        undef;
 }
 
index 61dc7ce3a3d51cbdf9f51e62110a06017b356186..2a0e06d12a3065fd0773f7877b7e6286af88b1cd 100644 (file)
@@ -22,7 +22,7 @@ use POSIX qw(strftime);
 use Fcntl qw(SEEK_SET);
 use Time::Local qw(timegm);
 use PublicInbox::OverIdx;
-use PublicInbox::Spawn qw(spawn);
+use PublicInbox::Spawn qw(run_wait);
 use PublicInbox::Git qw(git_unquote);
 use PublicInbox::MsgTime qw(msg_timestamp msg_datestamp);
 use PublicInbox::Address;
@@ -1010,9 +1010,7 @@ sub is_ancestor ($$$) {
        return 0 unless $git->check($cur);
        my $cmd = [ 'git', "--git-dir=$git->{git_dir}",
                qw(merge-base --is-ancestor), $cur, $tip ];
-       my $pid = spawn($cmd);
-       waitpid($pid, 0) == $pid or die join(' ', @$cmd) .' did not finish';
-       $? == 0;
+       run_wait($cmd) == 0;
 }
 
 sub need_update ($$$$) {
index 672789172463f43c0cb862c11adcdc9d2ae1bf40..726866c8577e2f4da24c65eaa8a57161d0b8e202 100644 (file)
@@ -4,7 +4,7 @@
 # Default spam filter class for wrapping spamc(1)
 package PublicInbox::Spamcheck::Spamc;
 use v5.12;
-use PublicInbox::Spawn qw(popen_rd spawn);
+use PublicInbox::Spawn qw(popen_rd run_wait);
 use IO::Handle;
 use Fcntl qw(SEEK_SET);
 
@@ -47,9 +47,7 @@ sub _learn {
        $rdr->{0} = _msg_to_fh($self, $msg);
        $rdr->{1} ||= $self->_devnull;
        $rdr->{2} ||= $self->_devnull;
-       my $pid = spawn($self->{$field}, undef, $rdr);
-       waitpid($pid, 0);
-       !$?;
+       0 == run_wait($self->{$field}, undef, $rdr);
 }
 
 sub _devnull {
index 2b84e2d5fea4acced623871348b123a56269a4fe..38619fc2c3ecaf33ccc31a2f1b943c9a0df548e6 100644 (file)
@@ -20,8 +20,9 @@ use parent qw(Exporter);
 use Symbol qw(gensym);
 use Fcntl qw(LOCK_EX SEEK_SET);
 use IO::Handle ();
+use Carp qw(croak);
 use PublicInbox::ProcessPipe;
-our @EXPORT_OK = qw(which spawn popen_rd run_die);
+our @EXPORT_OK = qw(which spawn popen_rd run_die run_wait);
 our @RLIMITS = qw(RLIMIT_CPU RLIMIT_CORE RLIMIT_DATA);
 
 BEGIN {
@@ -375,11 +376,15 @@ sub popen_rd {
        $s;
 }
 
+sub run_wait ($;$$) {
+       my ($cmd, $env, $opt) = @_;
+       waitpid(spawn($cmd, $env, $opt), 0);
+       $?
+}
+
 sub run_die ($;$$) {
        my ($cmd, $env, $rdr) = @_;
-       my $pid = spawn($cmd, $env, $rdr);
-       waitpid($pid, 0) == $pid or die "@$cmd did not finish";
-       $? == 0 or die "@$cmd failed: \$?=$?\n";
+       run_wait($cmd, $env, $rdr) and croak "E: @$cmd failed: \$?=$?";
 }
 
 1;
index 7b628769d4ad46b1721bcf67c70007b320a0a45b..2c38500cdf1e32d6a40ba2e24938f9fe81f4a1e3 100644 (file)
@@ -367,11 +367,7 @@ sub run_script ($;$$) {
                        $cmd->[0] = File::Spec->rel2abs($cmd->[0]);
                        $spawn_opt->{'-C'} = $d;
                }
-               my $pid = PublicInbox::Spawn::spawn($cmd, $env, $spawn_opt);
-               if (defined $pid) {
-                       my $r = waitpid($pid, 0) // die "waitpid: $!";
-                       $r == $pid or die "waitpid: expected $pid, got $r";
-               }
+               PublicInbox::Spawn::run_wait($cmd, $env, $spawn_opt);
        } else { # localize and run everything in the same process:
                # note: "local *STDIN = *STDIN;" and so forth did not work in
                # old versions of perl