1
0
mirror of https://github.com/golang/go synced 2024-11-23 15:30:05 -07:00

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
This commit is contained in:
Michael MacInnis 2014-09-11 18:39:51 -07:00 committed by Ian Lance Taylor
parent df1c2310f3
commit aa168ed2cd
2 changed files with 76 additions and 4 deletions

View File

@ -19,6 +19,8 @@ type SysProcAttr struct {
Setpgid bool // Set process group ID to new pid (SYSV setpgrp) Setpgid bool // Set process group ID to new pid (SYSV setpgrp)
Setctty bool // Set controlling terminal to fd 0 Setctty bool // Set controlling terminal to fd 0
Noctty bool // Detach fd 0 from controlling terminal 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. // Implemented in runtime package.
@ -79,7 +81,22 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if r1 != 0 { if r1 != 0 {
// parent; return PID // parent; return PID
runtime_AfterFork() runtime_AfterFork()
return int(r1), 0 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
} }
// Fork succeeded, now in child. // Fork succeeded, now in child.
@ -101,11 +118,30 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
} }
// Set process group // Set process group
if sys.Setpgid { 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.
_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0) _, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
if err1 != 0 { if err1 != 0 {
goto childerror 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 // Chroot

View File

@ -21,6 +21,8 @@ type SysProcAttr struct {
Ctty int // Controlling TTY fd (Linux only) Ctty int // Controlling TTY fd (Linux only)
Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only) Pdeathsig Signal // Signal that the process will get when its parent dies (Linux only)
Cloneflags uintptr // Flags for clone calls (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)
} }
// Implemented in runtime package. // Implemented in runtime package.
@ -71,7 +73,22 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if r1 != 0 { if r1 != 0 {
// parent; return PID // parent; return PID
runtime_AfterFork() runtime_AfterFork()
return int(r1), 0 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
} }
// Fork succeeded, now in child. // Fork succeeded, now in child.
@ -113,11 +130,30 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
} }
// Set process group // Set process group
if sys.Setpgid { 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.
_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0) _, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
if err1 != 0 { if err1 != 0 {
goto childerror 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 // Chroot