Why doesnt SIGINT get caught here?

Whats going on here? I thought SIGINT would be sent to the foreground process group.

(I think, maybe, that system() is running a shell which is creating a new process group for the child process? Can anyone confirm this?)

% perl
local $SIG{INT} = sub { print "caught signaln"; };
system('sleep', '10');

Then hit ctrl+d then ctrl+c immediately and notice that "caught signal" is never printed.

I feel like this is a simple thing... anyway to work around this? The problem is that when running a bunch of commands via system results in holding ctrl+c until all iterations are completed (because perl never gets the SIGINT) and is rather annoying...

How can this be worked around? (I already tested using fork() directly and understand that this works... this is not an acceptable solution at this time)

UPDATE : please note, this has nothing to do with "sleeping", only the fact that the command takes some arbitrary long amount of time to run which is considerably more than that of the perl around it. So much so that pressing ctrl+c gets sent to the command (as its in the foreground process group?) and somehow manages to never be sent to perl.


from perldoc system:

Since SIGINT and SIGQUIT are ignored during the execution of system, if you expect your program to terminate on receipt of these signals you will need to arrange to do so yourself based on the return value.

@args = ("command", "arg1", "arg2");
system(@args) == 0
   or die "system @args failed: $?"

If you'd like to manually inspect system's failure, you can check all possible failure modes by inspecting $? like this:

if ($? == -1) {
    print "failed to execute: $!n";
}
elsif ($? & 127) {
    printf "child died with signal %d, %s coredumpn",
       ($? & 127),  ($? & 128) ? 'with' : 'without';
}
else {
    printf "child exited with value %dn", $? >> 8;
}

Alternatively, you may inspect the value of ${^CHILD_ERROR_NATIVE} with the W*() calls from the POSIX module


I don't quite get what you're trying to achieve here... but have you tried simply comparing to:

perl -wle'local $SIG{INT} = sub { print "caught signal"; }; sleep 10;'

Can you explain what effect you're trying to go for, and why you are invoking the shell? Can you simply call into the external program directly without involving the shell?

链接地址: http://www.djcxy.com/p/46904.html

上一篇: 如何添加事件处理程序到表适配器中的RowUpdated事件

下一篇: 为什么SIGINT在这里被抓到?