// Fork succeeded, now in child.
- runtime_AfterForkInChild()
-
// Enable tracing if requested.
if sys.Ptrace {
_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
}
}
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
// Chroot
if chroot != nil {
_, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
// Fork succeeded, now in child.
- runtime_AfterForkInChild()
-
// Session ID
if sys.Setsid {
_, err1 = setsid()
}
}
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
// Chroot
if chroot != nil {
err1 = chroot1(uintptr(unsafe.Pointer(chroot)))
// Fork succeeded, now in child.
- runtime_AfterForkInChild()
-
// Enable tracing if requested.
if sys.Ptrace {
if err := ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
}
}
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
// Chroot
if chroot != nil {
_, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
// Fork succeeded, now in child.
- runtime_AfterForkInChild()
-
// Enable the "keep capabilities" flag to set ambient capabilities later.
if len(sys.AmbientCaps) > 0 {
_, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_KEEPCAPS, 1, 0, 0, 0, 0)
}
}
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
// Unshare
if sys.Unshareflags != 0 {
_, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0)
func TestForeground(t *testing.T) {
signal.Ignore(syscall.SIGTTIN, syscall.SIGTTOU)
+ defer signal.Reset()
tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
if err != nil {
t.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err)
}
+ defer tty.Close()
// This should really be pid_t, however _C_int (aka int32) is generally
// equivalent.
if errno != 0 {
t.Fatalf("TIOCSPGRP failed with error code: %s", errno)
}
+}
+
+func TestForegroundSignal(t *testing.T) {
+ tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0)
+ if err != nil {
+ t.Skipf("couldn't open /dev/tty: %s", err)
+ }
+ defer tty.Close()
+
+ ch1 := make(chan os.Signal, 1)
+ ch2 := make(chan bool)
+
+ signal.Notify(ch1, syscall.SIGTTIN, syscall.SIGTTOU)
+ defer signal.Stop(ch1)
- signal.Reset()
+ go func() {
+ cmd := create(t)
+ cmd.proc.SysProcAttr = &syscall.SysProcAttr{
+ Ctty: int(tty.Fd()),
+ Foreground: true,
+ }
+ cmd.Start()
+ cmd.Stop()
+ close(ch2)
+ }()
+
+ timer := time.NewTimer(30 * time.Second)
+ defer timer.Stop()
+ for {
+ select {
+ case sig := <-ch1:
+ t.Errorf("unexpected signal %v", sig)
+ case <-ch2:
+ // Success.
+ return
+ case <-timer.C:
+ t.Fatal("timed out waiting for child process")
+ }
+ }
}
// Test a couple of cases that SysProcAttr can't handle. Issue 29458.