1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
27 func (c
*command
) Info() (pid
, pgrp
int) {
28 pid
= c
.proc
.Process
.Pid
30 pgrp
, err
:= syscall
.Getpgid(pid
)
38 func (c
*command
) Start() {
39 if err
:= c
.proc
.Start(); err
!= nil {
44 func (c
*command
) Stop() {
46 if err
:= c
.proc
.Wait(); err
!= nil {
51 func create(t
*testing
.T
) *command
{
52 testenv
.MustHaveExec(t
)
54 proc
:= exec
.Command("cat")
55 stdin
, err
:= proc
.StdinPipe()
60 return &command
{stdin
, proc
, t
}
63 func parent() (pid
, pgrp
int) {
64 return syscall
.Getpid(), syscall
.Getpgrp()
67 func TestZeroSysProcAttr(t
*testing
.T
) {
68 ppid
, ppgrp
:= parent()
75 cpid
, cpgrp
:= cmd
.Info()
78 t
.Fatalf("Parent and child have the same process ID")
82 t
.Fatalf("Child is not in parent's process group")
86 func TestSetpgid(t
*testing
.T
) {
87 ppid
, ppgrp
:= parent()
91 cmd
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{Setpgid
: true}
95 cpid
, cpgrp
:= cmd
.Info()
98 t
.Fatalf("Parent and child have the same process ID")
102 t
.Fatalf("Parent and child are in the same process group")
106 t
.Fatalf("Child's process group is not the child's process ID")
110 func TestPgid(t
*testing
.T
) {
111 ppid
, ppgrp
:= parent()
115 cmd1
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{Setpgid
: true}
119 cpid1
, cpgrp1
:= cmd1
.Info()
122 t
.Fatalf("Parent and child 1 have the same process ID")
126 t
.Fatalf("Parent and child 1 are in the same process group")
130 t
.Fatalf("Child 1's process group is not its process ID")
135 cmd2
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{
142 cpid2
, cpgrp2
:= cmd2
.Info()
145 t
.Fatalf("Parent and child 2 have the same process ID")
149 t
.Fatalf("Parent and child 2 are in the same process group")
153 t
.Fatalf("Child 2's process group is its process ID")
157 t
.Fatalf("Child 1 and 2 have the same process ID")
160 if cpgrp1
!= cpgrp2
{
161 t
.Fatalf("Child 1 and 2 are not in the same process group")
165 func TestForeground(t
*testing
.T
) {
166 if runtime
.GOOS
== "hurd" {
167 t
.Skip("skipping; TestForeground: fails on GNU/Hurd")
169 signal
.Ignore(syscall
.SIGTTIN
, syscall
.SIGTTOU
)
171 tty
, err
:= os
.OpenFile("/dev/tty", os
.O_RDWR
, 0)
173 t
.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err
)
176 fpgrp
:= syscall
.Pid_t(0)
178 errno
:= syscall
.Ioctl(tty
.Fd(), syscall
.TIOCGPGRP
, uintptr(unsafe
.Pointer(&fpgrp
)))
180 t
.Fatalf("TIOCGPGRP failed with error code: %s", errno
)
184 t
.Fatalf("Foreground process group is zero")
187 ppid
, ppgrp
:= parent()
191 cmd
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{
197 cpid
, cpgrp
:= cmd
.Info()
200 t
.Fatalf("Parent and child have the same process ID")
204 t
.Fatalf("Parent and child are in the same process group")
208 t
.Fatalf("Child's process group is not the child's process ID")
213 errno
= syscall
.Ioctl(tty
.Fd(), syscall
.TIOCSPGRP
, uintptr(unsafe
.Pointer(&fpgrp
)))
215 t
.Fatalf("TIOCSPGRP failed with error code: %s", errno
)