fix #1956: return controlling terminal to parent
authorStoiko Ivanov <s.ivanov@proxmox.com>
Tue, 20 Nov 2018 08:46:32 +0000 (09:46 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 20 Nov 2018 08:50:38 +0000 (09:50 +0100)
The changes introduced in e97f807c388c10250f442b1f16c5315df2ffc2af let the
child in fork_worker take the controlling terminal of the session, without
returning it after finishing.
This breaks using/reading from the terminal after both parent and child exit
- e.g. when the code is called from within a shellscript.

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
src/PVE/RESTEnvironment.pm

index c2fea2b..cba062d 100644 (file)
@@ -496,10 +496,12 @@ sub fork_worker {
        $SIG{CHLD} = $SIG{PIPE} = 'DEFAULT';
        $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 {
@@ -592,7 +594,14 @@ sub fork_worker {
            $exitcode = 0;
        }
        POSIX::write($resfh, $msg, length($msg));
-       POSIX::close($resfh) if $sync;
+
+       if ($sync) {
+           POSIX::close($resfh);
+           if ( -t STDIN) {
+               POSIX::tcsetpgrp(fileno(STDIN), $ppgid) or
+                   die "failed to tcsetpgrp to parent: $!\n";
+           }
+       }
        POSIX::_exit($exitcode);
     }