in reply to What happens to a '-|' (pipe) file handle across a fork()?

elsif ($pid > 0) { # write $pid to .pid file cleanup(); exit(0); ## problem happens HERE }

If $pid is defined here, you are in the parent process. The child doesn't get a PID from fork().

## now in sub-process

Right; but the parent is gone. What are you trying to do? This is a daemon exiting after fork. Lousy parent, I'd say.

perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Replies are listed 'Best First'.
Re^2: What happens to a '-|' (pipe) file handle across a fork()?
by pprindeville (Novice) on Nov 08, 2015 at 21:08 UTC
    Right; but the parent is gone. What are you trying to do? This is a daemon exiting after fork. Lousy parent, I'd say.
    That's exactly what a daemon parent is supposed to do: fork() a child into a detached state (see Paul Barry's "Programming the Network with Perl" for examples, i.e. p. 125-126). Otherwise, the process call it would also block forever. But more to the point, I'm referring to the other child, then child resulting from the open($pipe, '-|', 'ip -o xfrm monitor')—that child.
      That's exactly what a daemon parent is supposed to do: fork() a child into a detached state

      Yes of course, a daemon closes all unnecessary file descriptors and forks itself and terminates, to detach from any terminal or I/O lines whatsoever. But in my book, the daemon does this right up front, before doing any other tasks.

      But more to the point, I'm referring to the other child, then child resulting from the open($pipe, '-|', 'ip -o xfrm monitor')—that child.

      Well, that child is kid of the daemons parent, so it might get reaped if grandfather exits. Perhaps reordering would help:

      my $pipe; my $pid = fork(); if (! defined $pid) { die "couldn't fork"; elsif ($pid > 0) { # write $pid to .pid file cleanup(); exit(0); ## problem happens HERE } ## now in sub-process close(STDIN); close(STDOUT); close(STDERR); ... # open the pipe in the child only after daemonizing open($pipe, '-|', 'ip -o xfrm monitor') || die "couldn't start sub-com +mand"; while (my $line = <$pipe>) { ... } close($pipe); cleanup2(); exit(0);
      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
        Yes of course, a daemon closes all unnecessary file descriptors and forks itself and terminates, to detach from any terminal or I/O lines whatsoever. But in my book, the daemon does this right up front, before doing any other tasks.
        It is usually desirable to have the parent do initialization and validation before forking, so it can report failure to the command-line at launch; otherwise, success or failure are indistinguishable without digging through the logs.