1// Copyright 2024 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.
4
5package os_test
6
7import (
8	"internal/testenv"
9	"os"
10	"os/signal"
11	"runtime"
12	"syscall"
13	"testing"
14	"time"
15)
16
17func TestProcessLiteral(t *testing.T) {
18	if runtime.GOOS == "windows" {
19		t.Skip("Process literals do not work on Windows. FindProcess/etc must initialize the process handle")
20	}
21	if runtime.GOARCH == "wasm" {
22		t.Skip("Signals send + notify not fully supported om wasm port")
23	}
24
25	c := make(chan os.Signal, 1)
26	signal.Notify(c, os.Interrupt)
27	defer signal.Stop(c)
28
29	p := &os.Process{Pid: os.Getpid()}
30	if err := p.Signal(os.Interrupt); err != nil {
31		t.Fatalf("Signal got err %v, want nil", err)
32	}
33
34	// Verify we actually received the signal.
35	select {
36	case <-time.After(1 * time.Second):
37		t.Error("timeout waiting for signal")
38	case <-c:
39		// Good
40	}
41}
42
43func TestProcessReleaseTwice(t *testing.T) {
44	testenv.MustHaveGoBuild(t)
45	t.Parallel()
46
47	r, w, err := os.Pipe()
48	if err != nil {
49		t.Fatalf("Pipe() got err %v, want nil", err)
50	}
51	defer r.Close()
52	defer w.Close()
53
54	p, err := os.StartProcess(testenv.GoToolPath(t), []string{"go"}, &os.ProcAttr{
55		// N.B. On Windows, StartProcess requires exactly 3 Files. Pass
56		// in a dummy pipe to avoid irrelevant output on the test stdout.
57		Files: []*os.File{r, w, w},
58	})
59	if err != nil {
60		t.Fatalf("starting test process: %v", err)
61	}
62	if err := p.Release(); err != nil {
63		t.Fatalf("first Release: got err %v, want nil", err)
64	}
65
66	err = p.Release()
67
68	// We want EINVAL from a second Release call only on Windows.
69	var want error
70	if runtime.GOOS == "windows" {
71		want = syscall.EINVAL
72	}
73
74	if err != want {
75		t.Fatalf("second Release: got err %v, want %v", err, want)
76	}
77}
78