Commit 2d53d6b5 authored by Russ Cox's avatar Russ Cox Committed by Ian Lance Taylor

undo CL 131750044 / 2d6d44ceb80e

Breaks reading from stdin in parent after exec with SysProcAttr{Setpgid: true}.

package main

import (
        "fmt"
        "os"
        "os/exec"
        "syscall"
)

func main() {
        cmd := exec.Command("true")
        cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
        cmd.Run()

        fmt.Printf("Hit enter:")
        os.Stdin.Read(make([]byte, 100))
        fmt.Printf("Bye\n")
}

In go1.3, I type enter at the prompt and the program exits.
With the CL being rolled back, the program wedges at the
prompt.

««« original CL description
syscall: SysProcAttr job control changes

Making the child's process group the foreground process group and
placing the child in a specific process group involves co-ordination
between the parent and child that must be done post-fork but pre-exec.

LGTM=iant
R=golang-codereviews, gobot, iant, mikioh.mikioh
CC=golang-codereviews
https://golang.org/cl/131750044

»»»

LGTM=minux, dneil
R=dneil, minux
CC=golang-codereviews, iant, michael.p.macinnis
https://golang.org/cl/174450043
parent f03f0cba
......@@ -19,8 +19,6 @@ type SysProcAttr struct {
Setpgid bool // Set process group ID to new pid (SYSV setpgrp)
Setctty bool // Set controlling terminal to fd 0
Noctty bool // Detach fd 0 from controlling terminal
Foreground bool // Set foreground process group to child's pid. (Implies Setpgid. Stdin should be a TTY)
Joinpgrp int // If != 0, child's process group ID. (Setpgid must not be set)
}
// Implemented in runtime package.
......@@ -81,22 +79,7 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if r1 != 0 {
// parent; return PID
runtime_AfterFork()
pid = int(r1)
if sys.Joinpgrp != 0 {
// Place the child in the specified process group.
RawSyscall(SYS_SETPGID, r1, uintptr(sys.Joinpgrp), 0)
} else if sys.Foreground || sys.Setpgid {
// Place the child in a new process group.
RawSyscall(SYS_SETPGID, 0, 0, 0)
if sys.Foreground {
// Set new foreground process group.
RawSyscall(SYS_IOCTL, uintptr(Stdin), TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
}
}
return pid, 0
return int(r1), 0
}
// Fork succeeded, now in child.
......@@ -118,30 +101,11 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// Set process group
if sys.Joinpgrp != 0 {
// Place the child in the specified process group.
_, _, err1 = RawSyscall(SYS_SETPGID, r1, uintptr(sys.Joinpgrp), 0)
if err1 != 0 {
goto childerror
}
} else if sys.Foreground || sys.Setpgid {
// Place the child in a new process group.
if sys.Setpgid {
_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
if err1 != 0 {
goto childerror
}
if sys.Foreground {
r1, _, _ = RawSyscall(SYS_GETPID, 0, 0, 0)
pid := int(r1)
// Set new foreground process group.
_, _, err1 = RawSyscall(SYS_IOCTL, uintptr(Stdin), TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
if err1 != 0 {
goto childerror
}
}
}
// Chroot
......
......@@ -29,8 +29,6 @@ type SysProcAttr struct {
Ctty int // Controlling TTY fd (Linux only)
Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only)
Cloneflags uintptr // Flags for clone calls (Linux only)
Foreground bool // Set foreground process group to child's pid. (Implies Setpgid. Stdin should be a TTY)
Joinpgrp int // If != 0, child's process group ID. (Setpgid must not be set)
UidMappings []SysProcIDMap // User ID mappings for user namespaces.
GidMappings []SysProcIDMap // Group ID mappings for user namespaces.
}
......@@ -105,19 +103,6 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
Close(p[1])
}
if sys.Joinpgrp != 0 {
// Place the child in the specified process group.
RawSyscall(SYS_SETPGID, r1, uintptr(sys.Joinpgrp), 0)
} else if sys.Foreground || sys.Setpgid {
// Place the child in a new process group.
RawSyscall(SYS_SETPGID, 0, 0, 0)
if sys.Foreground {
// Set new foreground process group.
RawSyscall(SYS_IOCTL, uintptr(Stdin), TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
}
}
return pid, 0
}
......@@ -179,30 +164,11 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// Set process group
if sys.Joinpgrp != 0 {
// Place the child in the specified process group.
_, _, err1 = RawSyscall(SYS_SETPGID, r1, uintptr(sys.Joinpgrp), 0)
if err1 != 0 {
goto childerror
}
} else if sys.Foreground || sys.Setpgid {
// Place the child in a new process group.
if sys.Setpgid {
_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
if err1 != 0 {
goto childerror
}
if sys.Foreground {
r1, _, _ = RawSyscall(SYS_GETPID, 0, 0, 0)
pid := int(r1)
// Set new foreground process group.
_, _, err1 = RawSyscall(SYS_IOCTL, uintptr(Stdin), TIOCSPGRP, uintptr(unsafe.Pointer(&pid)))
if err1 != 0 {
goto childerror
}
}
}
// Chroot
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment