SIGINT (and other signals) trap on Windows

Why is this simple script:

#! perl -w use strict; use warnings; $| = 1; my $LOCKFILE = "$0.lock"; sub mklock { open my $lf, ">", $LOCKFILE; print $lf $$; close $lf; } sub rmlock { unlink $LOCKFILE; } sub clean_exit { rmlock; exit 0; } sub work { print "working..."; sleep 10; # although `sleep 1 foreach (1..10);` # *does* interrupt---between `sleep`s--see my answer print "done.\n" } $SIG{INT} = "clean_exit"; mklock; work; rmlock; 

works on Debian but not Windows?

  • on Windows, Ctrl + C is ignored when running the script
  • on Debian, clean output is performed as expected
  • with $SIG{INT} = \&clean_exit; the behavior seems the same
  • (if I do the same with SIGHUP ( $SIG{HUP} = "clean_exit"; ), the window closes, but the clean exit fails anyway)

(Well, I admit that this is Strawberry perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread on Windows 7 amd64 -vs- perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi in the Debian 6.0.4 field, but I doubt it is important for such basic material Edit: I just checked it on a similar box with ActiveState perl 5.12, and this is the same, so apparently the problem is not isolated from Strawberry.)

I know perlport says it's clear

Do not count on signals or% SIG for anything.

but there must be a way ... (Plus, I would like to understand.)

So what needs to be done differently?

+4
source share
3 answers

After adding a few more print ing, I found that the code actually works, except that it does not interrupt during sleep .

Thus, just changing sleep 60 to a more "realistic" sleep 1 foreach (1..10); leads to much more acceptable behavior.

It still works differently on Windows than on * nix, of course.

+1
source

You can use sigtrap pragma:

 use sigtrap 'handler', \&cleanup, 'normal-signals'; 

This will call the cleanup method when the signal is caught and the signal is identified as a parameter.

+4
source

Submitting to the discipline of unix line in a DOS application is a luxury, not a right.

It obeys Ctrl+Break , which is the equivalent of Windows Ctrl + C

Change Changed to Ctrl + Break - this is what I get to use the Mac keyboard.

In order to test the processing of interruptions, you should use the following loop in your working part, because otherwise it waits until all sleep completes before the handler starts:

 sub work { print "working..."; my $i = 0; while ($i < 10) { sleep(1); $i--; } say "done." } 

Thus, it is easier to detect keystrokes - interrupt handling is not detected during sleep.

Color confused me - the INT handler works now!

Change The source code for perl claims that it should support HUP as a window close event, but the event does not seem to get delivered when I click on the close CMD window

+1
source

Source: https://habr.com/ru/post/1416333/


All Articles