X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FRESTEnvironment.pm;h=64c622f479c3543af3bf47025f39774e4f110a35;hp=3155aac849de59a2f9f7eb1fb028c97422a66b84;hb=c7a7aa4d931365dbe4d9dece67d495966e578a4e;hpb=e97f807c388c10250f442b1f16c5315df2ffc2af diff --git a/src/PVE/RESTEnvironment.pm b/src/PVE/RESTEnvironment.pm index 3155aac..64c622f 100644 --- a/src/PVE/RESTEnvironment.pm +++ b/src/PVE/RESTEnvironment.pm @@ -26,7 +26,7 @@ my $rest_env; # and register forked processes with &$register_worker(pid) # Note: using $SIG{CHLD} = 'IGNORE' or $SIG{CHLD} = sub { wait (); } or ... # has serious side effects, because perls built in system() and open() -# functions can't get the correct exit status of a child. So we cant use +# functions can't get the correct exit status of a child. So we can't use # that (also see perlipc) my $WORKER_PIDS; @@ -217,6 +217,34 @@ sub get_user { die "user name not set\n"; } +sub set_u2f_challenge { + my ($self, $challenge) = @_; + + $self->{u2f_challenge} = $challenge; +} + +sub get_u2f_challenge { + my ($self, $noerr) = @_; + + return $self->{u2f_challenge} if defined($self->{u2f_challenge}) || $noerr; + + die "no active u2f challenge\n"; +} + +sub set_request_host { + my ($self, $host) = @_; + + $self->{request_host} = $host; +} + +sub get_request_host { + my ($self, $noerr) = @_; + + return $self->{request_host} if defined($self->{request_host}) || $noerr; + + die "no hostname available in current environment\n"; +} + sub is_worker { my ($class) = @_; @@ -496,10 +524,13 @@ sub fork_worker { $SIG{CHLD} = $SIG{PIPE} = 'DEFAULT'; $SIG{TTOU} = 'IGNORE'; - # set sess/process group - we want to be able to kill the - # whole process group + my $ppgid; + # set session/process group allows to kill the process group if ($sync && -t STDIN) { - POSIX::setpgid(0,0) or die "failed to setpgid: $!\n";; + # some sync'ed workers operate on the tty but setsid sessions lose + # the tty, so just create a new pgroup and give it the tty + $ppgid = POSIX::getpgrp() or die "failed to get old pgid: $!\n"; + POSIX::setpgid(0, 0) or die "failed to setpgid: $!\n"; POSIX::tcsetpgrp(fileno(STDIN), $$) or die "failed to tcsetpgrp: $!\n"; } else { POSIX::setsid(); @@ -519,7 +550,7 @@ sub fork_worker { &$atfork(); } - # same algorythm as used inside SA + # same algorithm as used inside SA # STDIN = /dev/null my $fd = fileno (STDIN); @@ -578,22 +609,29 @@ sub fork_worker { } &$function($upid); }; + my ($msg, $exitcode); my $err = $@; if ($err) { chomp $err; $err =~ s/\n/ /mg; syslog('err', $err); - my $msg = "TASK ERROR: $err\n"; - POSIX::write($resfh, $msg, length($msg)); - POSIX::close($resfh) if $sync; - POSIX::_exit(-1); + $msg = "TASK ERROR: $err\n"; + $exitcode = -1; } else { - my $msg = "TASK OK\n"; - POSIX::write($resfh, $msg, length($msg)); - POSIX::close($resfh) if $sync; - POSIX::_exit(0); + $msg = "TASK OK\n"; + $exitcode = 0; + } + POSIX::write($resfh, $msg, length($msg)); + + if ($sync) { + POSIX::close($resfh); + if ( -t STDIN) { + POSIX::tcsetpgrp(fileno(STDIN), $ppgid) or + die "failed to tcsetpgrp to parent: $!\n"; + } } - kill(-9, $$); + POSIX::_exit($exitcode); + kill(-9, $$); # not really needed, just to be sure } # parent