diff options
author | Eric Wong <e@80x24.org> | 2023-09-11 09:41:26 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-09-11 18:51:13 +0000 |
commit | 9231d2e7b93f2739c215c51164569347c90c646a (patch) | |
tree | f04a1744128ba9b4e53f99b7513588df6de689e2 | |
parent | 22c5b815cc4105228fd34cdaa2826dca70552a3e (diff) | |
download | public-inbox-9231d2e7b93f2739c215c51164569347c90c646a.tar.gz |
tests: map CLOFORK->FD_CLOEXEC temporarily for `tail -f'
This fixes `TAIL="tail -F" prove -bvw t/lei-refresh-mail-sync.t' since that test relies on lacking FD_CLOEXEC to detect dead lei-daemons, but we still want FD_CLOEXEC when when relying on tail(1) to check -imapd output.
-rw-r--r-- | lib/PublicInbox/TestCommon.pm | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/PublicInbox/TestCommon.pm b/lib/PublicInbox/TestCommon.pm index ec300b3f..b7f1eb57 100644 --- a/lib/PublicInbox/TestCommon.pm +++ b/lib/PublicInbox/TestCommon.pm @@ -6,7 +6,7 @@ package PublicInbox::TestCommon; use strict; use parent qw(Exporter); use v5.10.1; -use Fcntl qw(F_SETFD :seek); +use Fcntl qw(F_SETFD F_GETFD FD_CLOEXEC :seek); use POSIX qw(dup2); use IO::Socket::INET; use File::Spec; @@ -326,7 +326,7 @@ sub run_script ($;$$) { die "unable to deal with $ref $redir"; } } - my $tail = @tail_paths ? tail_f(@tail_paths) : undef; + my $tail = @tail_paths ? tail_f(@tail_paths, $opt) : undef; if ($key =~ /-(index|cindex|extindex|convert|xcpdb)\z/) { unshift @argv, '--no-fsync'; } @@ -442,11 +442,23 @@ sub xqx { } sub tail_f (@) { + my @f = grep(defined, @_); $tail_cmd or return; # "tail -F" or "tail -f" - for (@_) { open(my $fh, '>>', $_) or die $! }; - my $cmd = [ split(/ /, $tail_cmd), @_ ]; + my $opt = (ref($f[-1]) eq 'HASH') ? pop(@f) : {}; + my $clofork = $opt->{-CLOFORK} // []; + use autodie qw(fcntl open); + my @cfmap = map { + my $fl = fcntl($_, F_GETFD, 0); + fcntl($_, F_SETFD, $fl | FD_CLOEXEC) unless $fl & FD_CLOEXEC; + ($_, $fl); + } @$clofork; + for (@f) { open(my $fh, '>>', $_) }; + my $cmd = [ split(/ /, $tail_cmd), @f ]; require PublicInbox::Spawn; my $pid = PublicInbox::Spawn::spawn($cmd, undef, { 1 => 2 }); + while (my ($io, $fl) = splice(@cfmap, 0, 2)) { + fcntl($io, F_SETFD, $fl); + } wait_for_tail($pid, scalar @_); require PublicInbox::AutoReap; PublicInbox::AutoReap->new($pid, \&wait_for_tail); @@ -476,7 +488,7 @@ sub start_script { } } } - $tail = tail_f(@paths); + $tail = tail_f(@paths, $opt); } my $oset = PublicInbox::DS::block_signals(); require PublicInbox::OnDestroy; |