- push @{$wq->{-ipc_atfork_child_close}}, @TO_CLOSE_ATFORK_CHILD,
- grep { defined } @$self{qw(0 1 2 sock)}
+ my $tcafc = $wq->{-ipc_atfork_child_close} //= [ $listener // () ];
+ if (my $sock = $self->{sock}) {
+ push @$tcafc, @$self{qw(0 1 2 3)}, $sock;
+ }
+ if (my $pgr = $self->{pgr}) {
+ push @$tcafc, @$pgr[1,2];
+ }
+ if (my $old_1 = $self->{old_1}) {
+ push @$tcafc, $old_1;
+ }
+ for my $f (qw(lxs l2m)) {
+ my $ipc = $self->{$f} or next;
+ push @$tcafc, grep { defined }
+ @$ipc{qw(-wq_s1 -wq_s2 -ipc_req -ipc_res)};
+ }
+}
+
+sub io_restore ($$) {
+ my ($dst, $src) = @_;
+ for my $i (0..2) { # standard FDs
+ my $io = delete $src->{$i} or next;
+ $dst->{$i} = $io;
+ }
+ for my $i (3..9) { # named (non-standard) FDs
+ my $io = $src->{$i} or next;
+ my @st = stat($io) or die "stat $src.$i ($io): $!";
+ my $f = delete $dst->{"dev=$st[0],ino=$st[1]"} // next;
+ $dst->{$f} = $io;
+ delete $src->{$i};
+ }
+}
+
+sub note_sigpipe { # triggers sigpipe_handler
+ my ($self, $fd) = @_;
+ close(delete($self->{$fd})); # explicit close silences Perl warning
+ send($self->{pkt_op}, '|', MSG_EOR) if $self->{pkt_op};
+ x_it($self, 13);