in reply to Re^2: signals after exec
in thread signals after exec

I decided to go with using fork to invoke the reloadable code. In my final implementation the child will use require to load a bunch of code that the parent doesn't need so that when the child process terminates, that code gets unloaded. I wanted a simple way for the child to send a message on its deathbed to the parent. I considered various IPC options, but in the end decided it would be simplest to just write a message to a file. The sample code below includes verbose messaging to easily follow what's happening:

./sigsuccess.pl
test> sig
INT: sigInt
test> loop
^C
child 38021: INT
child 38021: Reloading sigsuccess.pl
parent 38020: ignore INT
parent 38020: CHLD (reload)
parent 38020: Reloading...
test> loop
^C
child 38023: INT
child 38023: Reloading sigsuccess.pl
parent 38020: ignore INT
parent 38020: CHLD (reload)
parent 38020: Reloading...
test> exit
child 38024: Child exiting
parent 38020: CHLD ()
parent 38020: exiting after waitpid

use B; use Term::ReadLine; $SIG{INT} = sub { print "parent $$: ignore INT\n" }; my $comm = "message.$$"; reload: if ($pid = fork()) { my $reload = 0; local $SIG{CHLD} = sub { my $request = ""; if (open(my $fh,$comm)) { $request = <$fh>; chomp $request; close $fh; unlink $comm; $reload = 1 if $request =~ m/^reload$/; } print "parent $$: CHLD ($request)\n"; }; waitpid($pid,0); if ($reload) { print "parent $$: Reloading...\n"; goto reload; } print "parent $$: exiting after waitpid\n"; } else { $SIG{INT} = \&sigInt; $term = Term::ReadLine->new("sigsuccess"); while ($resp = $term->readline("test> ")) { if ($resp =~ m/^exit/) { last; } elsif ($resp =~ m/^loop/) { loop: goto loop; } elsif ($resp =~ m/^reload/) { reload(); last; } elsif ($resp =~ m/sig/) { sig() } else { print "What?\n"; } } print "child $$: Child exiting\n"; exit; } sub codeToName { my ($coderef) = @_; my $cv = B::svref_2object($coderef); return "" unless defined($cv) && defined($cv->GV); return $cv->GV->NAME; } sub reload { print "child $$: Reloading sigsuccess.pl\n"; open my $fh, ">$comm"; print $fh "reload\n"; close $fh; exit(0); } sub sigInt { print "\nchild $$: INT\n"; reload() } sub sig { map { print "$_: ",codeToName($SIG{$_}),"\n" if defined($SIG{$_}) && ref($SIG{$_}) eq "CODE" } sort { $a cmp $b } keys %SIG; }