]> git.proxmox.com Git - pve-common.git/blobdiff - src/PVE/RESTEnvironment.pm
add request host to RESTEnvironment
[pve-common.git] / src / PVE / RESTEnvironment.pm
index 32ffdd157f48a898697f77f7b582df471c5f6f64..64c622f479c3543af3bf47025f39774e4f110a35 100644 (file)
@@ -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) = @_;
 
@@ -494,10 +522,19 @@ sub fork_worker {
        $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { die "received interrupt\n"; };
 
        $SIG{CHLD} = $SIG{PIPE} = 'DEFAULT';
-
-       # set sess/process group - we want to be able to kill the
-       # whole process group
-       POSIX::setsid();
+       $SIG{TTOU} = 'IGNORE';
+
+       my $ppgid;
+       # set session/process group allows to kill the process group
+       if ($sync && -t STDIN) {
+           # 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();
+       }
 
        POSIX::close ($psync[0]);
        POSIX::close ($ctrlfd[0]) if $sync;
@@ -513,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);
 
@@ -572,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