]> git.proxmox.com Git - pve-installer.git/commitdiff
sys: command: handle EINTR in run_command()
authorChristoph Heiss <c.heiss@proxmox.com>
Tue, 13 Feb 2024 15:14:00 +0000 (16:14 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 23 Feb 2024 13:19:56 +0000 (14:19 +0100)
Previously, the I/O loop would continue endlessly until the subprocess
exited.
This explicit handling allows run_command() to be used with e.g.
alarm().

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
Proxmox/Sys/Command.pm
test/run-command.pl

index e64e0ee6cda8f0d7fea822ef34accd9e85913ea4..6389b17e196aa2a908812522a14d9a9b278f7292 100644 (file)
@@ -134,10 +134,17 @@ sub run_command {
     $select->add($error);
 
     my ($ostream, $logout) = ('', '', '');
+    my $caught_sig;
 
     while ($select->count) {
        my @handles = $select->can_read (0.2);
 
+       # If we catch a signal, stop processing & clean up
+       if ($!{EINTR}) {
+           $caught_sig = 1;
+           last;
+       }
+
        Proxmox::UI::process_events();
 
        next if !scalar (@handles); # timeout
@@ -170,7 +177,7 @@ sub run_command {
 
     &$func($logout) if $func;
 
-    my $ec = wait_for_process($pid);
+    my $ec = wait_for_process($pid, kill => $caught_sig);
 
     # behave like standard system(); returns -1 in case of errors too
     return ($ec // -1) if $noout;
index 7d5805e155258f0565e70c6bc1de8bc62a1f0ba4..19bdce0bb44bfa06b41d898deae8ea3de8f57c53 100755 (executable)
@@ -27,6 +27,17 @@ my $ret = run_command('bash -c "echo test; sleep 1000; echo test"', sub {
 });
 is($ret, '', 'using CMD_FINISHED');
 
+# https://bugzilla.proxmox.com/show_bug.cgi?id=4872
+my $prev;
+eval {
+    local $SIG{ALRM} = sub { die "timed out!\n" };
+    $prev = alarm(1);
+    $ret = run_command('sleep 5');
+};
+alarm($prev);
+
+is($@, "timed out!\n", 'SIGALRM interaction');
+
 # Check the log for errors/warnings
 my $log = file_read_all($log_file->filename);
 ok($log !~ m/(WARN|ERROR): /, 'no warnings or errors logged');