PR target/82112
[official-gcc.git] / libgo / go / syscall / exec_unix_test.go
blob58708da19ddc7e50f218596912f2ceadea5a7b06
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
7 package syscall_test
9 import (
10 "internal/testenv"
11 "io"
12 "os"
13 "os/exec"
14 "os/signal"
15 "syscall"
16 "testing"
17 "unsafe"
20 type command struct {
21 pipe io.WriteCloser
22 proc *exec.Cmd
23 test *testing.T
26 func (c *command) Info() (pid, pgrp int) {
27 pid = c.proc.Process.Pid
29 pgrp, err := syscall.Getpgid(pid)
30 if err != nil {
31 c.test.Fatal(err)
34 return
37 func (c *command) Start() {
38 if err := c.proc.Start(); err != nil {
39 c.test.Fatal(err)
43 func (c *command) Stop() {
44 c.pipe.Close()
45 if err := c.proc.Wait(); err != nil {
46 c.test.Fatal(err)
50 func create(t *testing.T) *command {
51 testenv.MustHaveExec(t)
53 proc := exec.Command("cat")
54 stdin, err := proc.StdinPipe()
55 if err != nil {
56 t.Fatal(err)
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()
69 cmd := create(t)
71 cmd.Start()
72 defer cmd.Stop()
74 cpid, cpgrp := cmd.Info()
76 if cpid == ppid {
77 t.Fatalf("Parent and child have the same process ID")
80 if cpgrp != ppgrp {
81 t.Fatalf("Child is not in parent's process group")
85 func TestSetpgid(t *testing.T) {
86 ppid, ppgrp := parent()
88 cmd := create(t)
90 cmd.proc.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
91 cmd.Start()
92 defer cmd.Stop()
94 cpid, cpgrp := cmd.Info()
96 if cpid == ppid {
97 t.Fatalf("Parent and child have the same process ID")
100 if cpgrp == ppgrp {
101 t.Fatalf("Parent and child are in the same process group")
104 if cpid != cpgrp {
105 t.Fatalf("Child's process group is not the child's process ID")
109 func TestPgid(t *testing.T) {
110 ppid, ppgrp := parent()
112 cmd1 := create(t)
114 cmd1.proc.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
115 cmd1.Start()
116 defer cmd1.Stop()
118 cpid1, cpgrp1 := cmd1.Info()
120 if cpid1 == ppid {
121 t.Fatalf("Parent and child 1 have the same process ID")
124 if cpgrp1 == ppgrp {
125 t.Fatalf("Parent and child 1 are in the same process group")
128 if cpid1 != cpgrp1 {
129 t.Fatalf("Child 1's process group is not its process ID")
132 cmd2 := create(t)
134 cmd2.proc.SysProcAttr = &syscall.SysProcAttr{
135 Setpgid: true,
136 Pgid: cpgrp1,
138 cmd2.Start()
139 defer cmd2.Stop()
141 cpid2, cpgrp2 := cmd2.Info()
143 if cpid2 == ppid {
144 t.Fatalf("Parent and child 2 have the same process ID")
147 if cpgrp2 == ppgrp {
148 t.Fatalf("Parent and child 2 are in the same process group")
151 if cpid2 == cpgrp2 {
152 t.Fatalf("Child 2's process group is its process ID")
155 if cpid1 == cpid2 {
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)
168 if err != nil {
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)))
175 if errno != 0 {
176 t.Fatalf("TIOCGPGRP failed with error code: %s", errno)
179 if fpgrp == 0 {
180 t.Fatalf("Foreground process group is zero")
183 ppid, ppgrp := parent()
185 cmd := create(t)
187 cmd.proc.SysProcAttr = &syscall.SysProcAttr{
188 Ctty: int(tty.Fd()),
189 Foreground: true,
191 cmd.Start()
193 cpid, cpgrp := cmd.Info()
195 if cpid == ppid {
196 t.Fatalf("Parent and child have the same process ID")
199 if cpgrp == ppgrp {
200 t.Fatalf("Parent and child are in the same process group")
203 if cpid != cpgrp {
204 t.Fatalf("Child's process group is not the child's process ID")
207 cmd.Stop()
209 errno = syscall.Ioctl(tty.Fd(), syscall.TIOCSPGRP, uintptr(unsafe.Pointer(&fpgrp)))
210 if errno != 0 {
211 t.Fatalf("TIOCSPGRP failed with error code: %s", errno)
214 signal.Reset()