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 linux netbsd openbsd solaris
26 func (c
*command
) Info() (pid
, pgrp
int) {
27 pid
= c
.proc
.Process
.Pid
29 pgrp
, err
:= syscall
.Getpgid(pid
)
37 func (c
*command
) Start() {
38 if err
:= c
.proc
.Start(); err
!= nil {
43 func (c
*command
) Stop() {
45 if err
:= c
.proc
.Wait(); err
!= nil {
50 func create(t
*testing
.T
) *command
{
51 testenv
.MustHaveExec(t
)
53 proc
:= exec
.Command("cat")
54 stdin
, err
:= proc
.StdinPipe()
59 return &command
{stdin
, proc
, t
}
62 func parent() (pid
, pgrp
int) {
63 return syscall
.Getpid(), syscall
.Getpgrp()
66 func TestZeroSysProcAttr(t
*testing
.T
) {
67 ppid
, ppgrp
:= parent()
74 cpid
, cpgrp
:= cmd
.Info()
77 t
.Fatalf("Parent and child have the same process ID")
81 t
.Fatalf("Child is not in parent's process group")
85 func TestSetpgid(t
*testing
.T
) {
86 ppid
, ppgrp
:= parent()
90 cmd
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{Setpgid
: true}
94 cpid
, cpgrp
:= cmd
.Info()
97 t
.Fatalf("Parent and child have the same process ID")
101 t
.Fatalf("Parent and child are in the same process group")
105 t
.Fatalf("Child's process group is not the child's process ID")
109 func TestPgid(t
*testing
.T
) {
110 ppid
, ppgrp
:= parent()
114 cmd1
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{Setpgid
: true}
118 cpid1
, cpgrp1
:= cmd1
.Info()
121 t
.Fatalf("Parent and child 1 have the same process ID")
125 t
.Fatalf("Parent and child 1 are in the same process group")
129 t
.Fatalf("Child 1's process group is not its process ID")
134 cmd2
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{
141 cpid2
, cpgrp2
:= cmd2
.Info()
144 t
.Fatalf("Parent and child 2 have the same process ID")
148 t
.Fatalf("Parent and child 2 are in the same process group")
152 t
.Fatalf("Child 2's process group is its process ID")
156 t
.Fatalf("Child 1 and 2 have the same process ID")
159 if cpgrp1
!= cpgrp2
{
160 t
.Fatalf("Child 1 and 2 are not in the same process group")
164 func TestForeground(t
*testing
.T
) {
165 signal
.Ignore(syscall
.SIGTTIN
, syscall
.SIGTTOU
)
167 tty
, err
:= os
.OpenFile("/dev/tty", os
.O_RDWR
, 0)
169 t
.Skipf("Can't test Foreground. Couldn't open /dev/tty: %s", err
)
172 fpgrp
:= syscall
.Pid_t(0)
174 errno
:= syscall
.Ioctl(tty
.Fd(), syscall
.TIOCGPGRP
, uintptr(unsafe
.Pointer(&fpgrp
)))
176 t
.Fatalf("TIOCGPGRP failed with error code: %s", errno
)
180 t
.Fatalf("Foreground process group is zero")
183 ppid
, ppgrp
:= parent()
187 cmd
.proc
.SysProcAttr
= &syscall
.SysProcAttr
{
193 cpid
, cpgrp
:= cmd
.Info()
196 t
.Fatalf("Parent and child have the same process ID")
200 t
.Fatalf("Parent and child are in the same process group")
204 t
.Fatalf("Child's process group is not the child's process ID")
209 errno
= syscall
.Ioctl(tty
.Fd(), syscall
.TIOCSPGRP
, uintptr(unsafe
.Pointer(&fpgrp
)))
211 t
.Fatalf("TIOCSPGRP failed with error code: %s", errno
)