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!