]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/ProcessPipe.pm
sigfd: simplify loop and improve documentation
[public-inbox.git] / lib / PublicInbox / ProcessPipe.pm
1 # Copyright (C) 2016-2019 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3
4 # a tied handle for auto reaping of children tied to a pipe, see perltie(1)
5 package PublicInbox::ProcessPipe;
6 use strict;
7 use warnings;
8
9 sub TIEHANDLE {
10         my ($class, $pid, $fh) = @_;
11         bless { pid => $pid, fh => $fh }, $class;
12 }
13
14 sub READ { read($_[0]->{fh}, $_[1], $_[2], $_[3] || 0) }
15
16 sub READLINE { readline($_[0]->{fh}) }
17
18 sub CLOSE {
19         my $fh = delete($_[0]->{fh});
20         my $ret = defined $fh ? close($fh) : '';
21         my $pid = delete $_[0]->{pid};
22         if (defined $pid) {
23                 # PublicInbox::DS may not be loaded
24                 eval { PublicInbox::DS::dwaitpid($pid, undef, undef) };
25
26                 if ($@) { # ok, not in the event loop, work synchronously
27                         waitpid($pid, 0);
28                         $ret = '' if $?;
29                 }
30         }
31         $ret;
32 }
33
34 sub FILENO { fileno($_[0]->{fh}) }
35
36 sub DESTROY {
37         CLOSE(@_);
38         undef;
39 }
40
41 sub pid { $_[0]->{pid} }
42
43 1;