17.5. How do you fork on System V (HP)?

Kraegeloh Martin <mkr@dm-server.cv.com> originally asked:


! Subj: signal handling difference on HP vs. SUN
!
! the following code will fork an xterm with vi in it, and it
! will refuse to do so while the first xterm is still running.
! works fine on my sun.
! On HP however, the second time an xterm is started, NO handler
! is called when the child dies.
!
! the code:
! ===================== 8< ===============================
! $SIG{CHLD}=\&w;
!
! sub w{
!    $pid=wait;
!    print STDERR "died: $pid\n";
!    if ( $have == $pid ) { $have = 0; }
! }
To which a part of Nick Ing-Simmons' response was:

I suspect HPUX is SysV-ish not BSD or POSIX. So every time a signal fires, it removes the handler - you need to reset it in the handler:
    sub w{
        $SIG{CHLD}=\&w;
        $pid=wait;
        print STDERR "died: $pid\n";
        if ( $have == $pid ) { $have = 0; }
     }
 
Whether you reset it before/after the wait may be very important ...

Then Bjarne Steinsbo <bjarne@hsr.no> followed up with:

That's not the whole story... Another problem is that SIGCLD interrupts the read system call on SysV-ish (I like that word! :-) systems. This means that you have to test why "" fails, and act accodingly. A program that works on both Sun and HP is:
    $SIG{CHLD}=\&w;
    while(1){
       $_ = ;
       $! = 0, next if $! =~ /Interrupted/;
       last if $! or !defined $_;
       if($have){
            print STDERR "child still alive\n";
       }
       else{
            if(($pid=fork()) != 0){
               $have=$pid;
               print STDERR "forked $pid\n";
            }
            else {
               exec("xterm -e vi") 
            }
       }
    }

    sub w{
       $pid=wait;
       print STDERR "died: $pid\n";
       if ( $have == $pid ) { $have = 0; }
       $SIG{CHLD}=\&w;
    }

Previous | Return to table of contents | Next