$SIG{INT}='IGNORE' not working with Net::OpenSSH

扶醉桌前 提交于 2019-12-05 14:11:51
salva

The problem is that when you press CTRL-C on the console, the kernel sends a signal to all the processes on the process group (see Prevent control-c from sending SIGINT to all process group children).

I think the difference you see in behavior is actually caused by differences on the child processes, some reset the signal flags while others don't.

Anyway, I will add support for running the SSH process in a different process group. Add a bug report on the module RT so I don't forget about it, please.

Update: The following experiment shows that OpenSSH system method and the builtin behave in the same way:

my @cmd = $SSH->make_remote_command("sleep 3 && echo hello");
warn "running command @cmd\n";
local $SIG{INT} = 'IGNORE';
system @cmd;

If you run it you will see that the signal reaches and aborts the ssh process even if the INT signal handler is set to IGNORE.

Update 2: After some experimentation I have found that the problem actually lays on the master SSH process running on the background. Unless you use password authentication, it also hangs in the process group and so gets the INT signal.

I am adding a new option to explicitly ask for running the master as a new process group but that part of the code is quite convoluted due to the large number of options, so it is not an easy task.

Update 3: I have released a new development version (0.61_15) of the module.

Now, you can do...

my $ssh = Net::OpenSSH->new($host, master_setpgrp => 1, ...);
$ssh->system({setpgrp => 1}, "sleep 10; echo uninterruptible");

... and hopefully, no SIGINT would arrive into the master or slave SSH processes.

Report any issue you may find, please!

ap0calypse

In your case, it would be better to get pre-Perl-5.8 signal behaviour, by setting the environment var of PERL_SIGNALS to 'unsafe'.

Since Perl 5.8.1 the normal approach of signals is described here: perlipc: Deferred Signals (Safe Signals)

But what you maybe want is immediate behaviour, like here: perlrun: PERL_SIGNALS

so, the solution to your problem might be to put this:

 $ENV{'PERL_SIGNALS'} = 'unsafe';

in your code :)

I tried it here, worked so far. But there may be a downside of this approach since I don't know if your program will face different problems due to that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!