l1ve2love has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I need enlightenment to a problem:
Spawning a child, and allowing the parent process to finish (which it does) and return (seems to hung) while the child runs on his own.
I have the following code:
my $pid = fork; if ( defined $pid ) { unless ($pid) { # Detach from parent setsid or print("Can't detach from parent. notify cvs admin: $ +!"); exec "perl ${script_dir}/check_and_auto_merge.pl $gUSER $lBranc +h"; die "Failed exec auto_merge.pl\n copy log and notify cvs admin\ +n\nExec failed: $!\n"; exit 1; } } print("Parent ended");

The parent somehow finish but does not return, and the the cvs client command hangs. Only after the child finish the client command ends. This on a longer process is not acceptable to the users.
Could you suggest a solution?
Live

Replies are listed 'Best First'.
Re: Child keeps parent from returning...?
by Bloodnok (Vicar) on Apr 08, 2009 at 09:40 UTC
    Have you tried implementing something along the lines suggested in man -S 2 setsid - where it says the parent should call _exit() in order for a completely successful call to setsid() ... unless it's being run in a thread. Have a look at POSIX + the appropriate man(1) pages for further details

    A user level that continues to overstate my experience :-))
      Hi,
      thanks for your reply. I do call exit 0; at end of parent.
      live
Re: Child keeps parent from returning...?
by almut (Canon) on Apr 08, 2009 at 10:25 UTC

    Try redirecting/closing the standard file handles (STDOUT, STDERR, and maybe also STDIN) in the child before you call exec.

      I'm not very proficient with perl.
      Could you give me the commands to close stdin, out and err ?

      I'm not using them at least explicitly in the child program.
      thanks
      live
        # close close STDOUT; # redirect open STDOUT, '>', "/some/path/to/file" or die "Can't redirect STDOUT: +$!";

        (see open)

        Whether to close or redirect depends on how the child program is using them. Simply closing might not always work.

        I'm not using them at least explicitly in the child program.

        ...but cvs might be. They're 'inherited' across the fork/exec.

Re: Child keeps parent from returning...?
by l1ve2love (Novice) on Apr 08, 2009 at 12:16 UTC
    Dear Bloodnok and Almut,

    Thanks to your help.

    The code that works after using setsid and closing the std* as suggested is the following returning immediately.
    my $pid = fork; if ( defined $pid ) { unless ($pid) { # Detach from parent setsid or print("Can't detach from parent. Copy log and notify + cvs admin: $!"); close STDOUT; close STDERR; close STDIN; exec "perl ${script_dir}/auto_merge.pl $gUSER $lBranch"; die "Failed exec auto_merge.pl\nPlease copy log and notify cvs +admin\n\nExec failed: $!\n"; exit 1; } } .. .. exit 0;

    Thanks a lot for your shared wisdom :)
    live

      There's only one problem left: if the close STDERR succeeds (which it usually does), but the exec fails, the die "..." (which outputs to STDERR) won't have anywhere to write...  In other words, you probably want to redirect STDERR instead of closing it, in order to take care of this case. Or save and restore the original STDERR before/after the exec (see open for how to do the latter).