mirror of
https://git.proxmox.com/git/pve-installer
synced 2025-04-28 12:51:31 +00:00
sys: command: handle EINTR in run_command()
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>
This commit is contained in:
parent
152bbef439
commit
7a95f3873f
@ -134,10 +134,17 @@ sub run_command {
|
|||||||
$select->add($error);
|
$select->add($error);
|
||||||
|
|
||||||
my ($ostream, $logout) = ('', '', '');
|
my ($ostream, $logout) = ('', '', '');
|
||||||
|
my $caught_sig;
|
||||||
|
|
||||||
while ($select->count) {
|
while ($select->count) {
|
||||||
my @handles = $select->can_read (0.2);
|
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();
|
Proxmox::UI::process_events();
|
||||||
|
|
||||||
next if !scalar (@handles); # timeout
|
next if !scalar (@handles); # timeout
|
||||||
@ -170,7 +177,7 @@ sub run_command {
|
|||||||
|
|
||||||
&$func($logout) if $func;
|
&$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
|
# behave like standard system(); returns -1 in case of errors too
|
||||||
return ($ec // -1) if $noout;
|
return ($ec // -1) if $noout;
|
||||||
|
@ -27,6 +27,17 @@ my $ret = run_command('bash -c "echo test; sleep 1000; echo test"', sub {
|
|||||||
});
|
});
|
||||||
is($ret, '', 'using CMD_FINISHED');
|
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
|
# Check the log for errors/warnings
|
||||||
my $log = file_read_all($log_file->filename);
|
my $log = file_read_all($log_file->filename);
|
||||||
ok($log !~ m/(WARN|ERROR): /, 'no warnings or errors logged');
|
ok($log !~ m/(WARN|ERROR): /, 'no warnings or errors logged');
|
||||||
|
Loading…
Reference in New Issue
Block a user