summaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorMichael MacInnis <Michael.P.MacInnis@gmail.com>2014-09-11 18:39:51 -0700
committerMichael MacInnis <Michael.P.MacInnis@gmail.com>2014-09-11 18:39:51 -0700
commit6a22ebd3880e3f551720c518a5850535c601453b (patch)
treeb9a027c09cf6e7b71161cf932080d332191369cc /src/syscall
parent90f083350fdc100ed6482df5883d1f358c3c16b5 (diff)
downloadgo-6a22ebd3880e3f551720c518a5850535c601453b.tar.gz
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://codereview.appspot.com/131750044 Committer: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/exec_bsd.go40
-rw-r--r--src/syscall/exec_linux.go40
2 files changed, 76 insertions, 4 deletions
diff --git a/src/syscall/exec_bsd.go b/src/syscall/exec_bsd.go
index ff78f197f..7c2c1f707 100644
--- a/src/syscall/exec_bsd.go
+++ b/src/syscall/exec_bsd.go
@@ -19,6 +19,8 @@ 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.
@@ -79,7 +81,22 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if r1 != 0 {
// parent; return PID
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.
@@ -101,11 +118,30 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// 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)
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
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index f27950f73..f61dfc424 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -21,6 +21,8 @@ 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)
}
// Implemented in runtime package.
@@ -71,7 +73,22 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
if r1 != 0 {
// parent; return PID
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.
@@ -113,11 +130,30 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
}
// 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)
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