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

I want to use signal handler on NT. I wrote the following code:
#!/usr/bin/perl $saw_sig = 0; $SIG{INT} = \&my_sig; sub my_sig{ print "I am catching the signals\n"; $saw_sig = 1; die; } while (1){ print "I am here\n"; }
This works on unix when I hit "CTRL_C", it print the message " I am catching the signals"; but on NT, when I hit "CTRL_C", the program just stop, but I couldn't see the message, that means the program didn't go to the signal handler.

So how can I handle the signals on WIN32?

Edit by dws to add <code> tags

Replies are listed 'Best First'.
Re: signal handler on NT
by BrowserUk (Patriarch) on Sep 17, 2002 at 19:19 UTC

    From the ActiveState documentation for Perl 5.6.1

    Why doesn't signal handling work on Windows? Signals are unsupported by the Win32 API. The C Runtime provides crude + support for signals, but there are serious caveats, such as inabilit +y to die() or exit() from a signal handler. Perl itself does not guar +antee that signal handlers will not interrupt critical operations suc +h as memory allocation, which means signal invocation may throw perl +internals into disarray. For these reasons, signals are unsupported a +t this time.

    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
      i can't see the need to "implement" the unix signal handlers on the win32 platform. asynchronous messages are AFAIK "events", so why not use this mechanism?
      (x) yes, i am probably writing nonsense ;)

        Note: I wasn't asking for them, just passing along some relevent information that might help the original poster.

        However, I think the answer to your question is cross-systems compatability. I agree that the Win32 event model is very powerful and useful, but it only works on Win32.

        The unix style signals are implemented pretty much everywhere else, and whilst (IMHO) the are less powerful, they are a) ubiquitous. b) there are many, many algorithms and a wide codebase of applications that use them to good effect. So, unless and until the Unix world adopts the Win32 event model, (and hell will freeze over before they do:), having signals available on Win32 is the pragmatic solution to portability for cross-platform event driven programming.

        It seems however that as with many of the cross-compatibility features implemented in Win32, it is little more than bullet-point programming. Which is to say, it was only included, and only barely implemented in order that it could be listed on presentation slides when MS salesfolk where trying to sell it into large corporate accounts.

        Yes, of course we can take your existing legacy applications and run them on our platform. Look here at this slide showing all the compatibility points.

        {Chairmen of the board ticks box on a 7 line distillation of the 20,000 line report authored by the IT department as to why moving to Win32 would be a major headache>}


        Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
Re: signal handler on NT
by charnos (Friar) on Sep 17, 2002 at 19:24 UTC
    As fglock said, the die() inside the sub is causing ActiveState's version to cause Windows errors (at least for me..though I did originally get the signal trap message). So I used the $saw_sig var in your code to tell it when to die:
    #!/usr/bin/perl $saw_sig = 0; $SIG{INT} = \&my_sig; sub my_sig{ print "I am catching the signals\n"; $saw_sig = 1; } while (1){ $saw_sig==0?print "I am here\n":die; }
      In fact, for the reasons BrowserUk posted and more (similar caveats exist on almost all OSs), I'd do even less inside the signal handler:
      #!/usr/bin/perl -w use strict; my $got_int = 0; $SIG{INT} = sub { $got_int++ }; while (1){ print "Signal caught", exit if $got_int; print "I am here\n"; }
      Of course you can't always set up quite as minimalistic signal handlers, but don't use them for any more work than absolutely necessary.

      Makeshifts last the longest.

Re: signal handler on NT
by DigitalKitty (Parson) on Sep 18, 2002 at 14:07 UTC
    Hi all.
    To circumvent this ( hopefully temporary ) shortcoming, I usually just write the signal handler in this fashion:

    #!c:\perl\perl.exe -w use strict; my $num = 5; $| = 1; $SIG{ 'INT' } = \&stop; while( $num ) { print "I'm waiting...\n"; sleep 2; } sub stop { $SIG{ 'INT' } = \&stop; $num--; print "$num\n"; }

    You have to override the signal handler on win32 machines because after the signal handler is called, it's value ( which is stored in %SIG ), will revert back to the default. Since 'Control-c' is the same as SIG{ 'INT' }, the program will stop executing immediately.

    Hope this helps,

    -Katie.
Re: signal handler on NT
by fglock (Vicar) on Sep 17, 2002 at 19:12 UTC

    It didn't work for me either. Looks like it can't die inside the sub. Try this instead (tested under Activestate build 633) :

    #!/usr/bin/perl $saw_sig = 0; $SIG{INT} = \&my_sig; sub my_sig{ print "I am catching the signals\n"; $saw_sig = 1; # die; } while (not $saw_sig){ print "I am here\n"; }
Re: signal handler on NT
by perrin (Chancellor) on Sep 17, 2002 at 19:10 UTC
    It works with the Cygwin version of Perl but not with the ActiveState one. I'd suggest switching or sending a bug report to ActiveState.