http://www.perlmonks.org?node_id=1034517

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

Problem: My Perl application has signal handlers installed, which logs (if possible) the signal received, and reacts accordingly. Recently I found one case in our logs showing that a SIGHUP was delivered. The application is running using ActiveState Perl 5.14 on (64bit-)Windows 7. I wonder which event might possibly cause the SIGHUP handler being called (aside from the obvious possibility that my application is doing suicide using this signal).

I am aware that on Windows, signal handling is simulated by turning Windows messages are turned into signals. Looking at the source code of Perl, I found indeed 1 case where SIGHUP seems to be generated. I don't understand much about the Windows API, but the code says:

BOOL WINAPI win32_ctrlhandler(DWORD dwCtrlType) ... switch(dwCtrlType) { case CTRL_CLOSE_EVENT: /* A signal that the system sends to all processes attached to a + console when the user closes the console (either by choosing the Close com +mand from the console window's System menu, or by choosing the End Task com +mand from the Task List */ if (do_raise(aTHX_ 1)) /* SIGHUP */ sig_terminate(aTHX_ 1); return TRUE;
I roughly (and maybe uncorrectly) understand the comment in that closing the console corresponds to SIGHUP. Trying to verify this, I wrote the following small program:
use strict; use warnings; use Config; BEGIN { open(LOG,">","what_happens.log") or die "$!"; my $ofh = select LOG; $|=1; select $ofh; print LOG "Unbuffered Log\n"; } sub pout { print {$_} @_,"\n" for (*LOG, *STDERR); } END { pout("end handler called"); close LOG; } pout "Started"; my $signum = 0; foreach my $signame (split(' ', $Config{sig_name})) { if ($signum) { pout("Establishing $signame $signum"); $SIG{$signame} = $signame =~ /^KILL|STOP$/ ? 'IGNORE' # According to perldoc perlipc, they + can be ignored, but not trapped : sub { $SIG{$signame} = 'DEFAULT'; + pout("Murdered by signal $signame, default han +dler established"); if ($signame eq 'INT') { pout("This seems to be Keyboard interrupt" +); exit; } else { pout("Suicide"); kill($signum, $$); # proceed with norma +l handling of signal } }; } ++$signum; } pout("Interrupt handlers registered"); sleep(6); pout("Normal exit");
For example, if I start the program in a console, and type Control-C while the application is sleeping, I see message This seems to be Keyboard interrupt in my logfile. However, if I close instead the console window, the last message in the log is Interrupt handlers registered. I conclude that closing the window, is invoking either SIGKILL or SIGSTOP - different from what I expected.

I guess that I misunderstood the meaning of SIGHUP on Windows. Could someone help me here?
-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: SIGHUP delivered on Windows
by BrowserUk (Patriarch) on May 21, 2013 at 13:11 UTC
    I found indeed 1 case where SIGHUP seems to be generated.

    I've never heard of SIGHUP ever being generated on windows, nor can I reproduce it.

    #! perl -slw use strict; use Data::Dump qw[ pp ]; use Config; $|++; my @signames = split ' ', $Config{ sig_name }; eval qq[ \$SIG{ $signames[ $_ ] } = sub{ warn qq[SIG $_ received\n] }; + ] for 1 .. 21; pp \%SIG; 1 while sleep 1; __END__ c:\test>sigtest 2>log ## typed ^C and then ^break and then closed the console C:\test>type ..\log do { my $a = { ABRT => undef, ALRM => sub { ... }, BREAK => sub { ... }, CHLD => sub { ... }, CLD => 'fix', CONT => undef, FPE => sub { ... }, HUP => sub { ... }, ILL => sub { ... }, INT => sub { ... }, KILL => sub { ... }, NUM05 => sub { ... }, NUM06 => sub { ... }, NUM07 => sub { ... }, NUM10 => sub { ... }, NUM12 => sub { ... }, NUM16 => sub { ... }, NUM17 => sub { ... }, NUM18 => sub { ... }, NUM19 => sub { ... }, NUM24 => undef, PIPE => sub { ... }, QUIT => 'fix', SEGV => sub { ... }, STOP => undef, TERM => sub { ... }, }; $a->{CLD} = $a->{CHLD}; $a->{QUIT} = $a->{BREAK}; $a; } SIG 2 received SIG 21 received ^C

    And if you trace the guts snippet you posted through, you'll find that do_raise() effectively return false for SIGCLD & SIGCHLD and true otherwise; and when it returns true, (as it will for the CTRL_CLOSE_EVENT|), sig_terminate() simple calls exit(sig) with sig == 1.

    Basically, I don't think that there is any way perl on windows will ever receive or trap a SIGHUP, so any message you get to that effect must be a mistaken user message.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      any message you get to that effect must be a mistaken user message.
      What exactly is meant by "user message" here?

      -- 
      Ronald Fischer <ynnor@mm.st>

        Something not generated by Perl or the OS.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.