Skip to content

Commit d44997d

Browse files
committed
os: start processes with posix_spawn
Use posix_spawn on hosted Linux and Darwin. Map process files, apply the working directory and process group, and clear the child signal mask. Use wait4 for process status and support Kill and Signal. Mark Darwin pipes close-on-exec under ForkLock. Darwin also needs the fcntl wrapper in PR #5612 and the libSystem symbols in PR #5636. Concurrent spawn and pipe creation need the RWMutex fix in PR #5630. Keep the process stubs on other targets and add process regression tests.
1 parent 21718dc commit d44997d

10 files changed

Lines changed: 879 additions & 283 deletions

src/os/exec.go

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import (
55
"syscall"
66
)
77

8+
// Errors StartProcess returns for a ProcAttr that it cannot honour. On a
9+
// hosted OS only ErrNotImplementedSys is reachable. The other two stay because
10+
// they are part of the exported API of this package.
811
var (
912
ErrNotImplementedDir = errors.New("directory setting not implemented")
1013
ErrNotImplementedSys = errors.New("sys setting not implemented")
@@ -36,35 +39,12 @@ type ProcAttr struct {
3639
// ErrProcessDone indicates a Process has finished.
3740
var ErrProcessDone = errors.New("os: process already finished")
3841

39-
type ProcessState struct {
40-
}
41-
42-
func (p *ProcessState) String() string {
43-
return "" // TODO
44-
}
45-
func (p *ProcessState) Success() bool {
46-
return false // TODO
47-
}
48-
49-
// Sys returns system-dependent exit information about
50-
// the process. Convert it to the appropriate underlying
51-
// type, such as syscall.WaitStatus on Unix, to access its contents.
52-
func (p *ProcessState) Sys() interface{} {
53-
return nil // TODO
54-
}
55-
56-
func (p *ProcessState) Exited() bool {
57-
return false // TODO
58-
}
59-
60-
// ExitCode returns the exit code of the exited process, or -1
61-
// if the process hasn't exited or was terminated by a signal.
62-
func (p *ProcessState) ExitCode() int {
63-
return -1 // TODO
64-
}
65-
6642
type Process struct {
6743
Pid int
44+
45+
// done reports whether Wait reaped this process. A signal to a reaped pid
46+
// is unsafe, because the number can belong to an unrelated process.
47+
done int32
6848
}
6949

7050
// StartProcess starts a new process with the program, arguments and attributes specified by name, argv and attr.
@@ -73,21 +53,6 @@ func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error)
7353
return startProcess(name, argv, attr)
7454
}
7555

76-
func (p *Process) Wait() (*ProcessState, error) {
77-
if p.Pid == -1 {
78-
return nil, syscall.EINVAL
79-
}
80-
return nil, ErrNotImplemented
81-
}
82-
83-
func (p *Process) Kill() error {
84-
return ErrNotImplemented
85-
}
86-
87-
func (p *Process) Signal(sig Signal) error {
88-
return ErrNotImplemented
89-
}
90-
9156
func Ignore(sig ...Signal) {
9257
// leave all the signals unaltered
9358
return

src/os/exec_linux.go

Lines changed: 0 additions & 103 deletions
This file was deleted.

src/os/exec_linux_test.go

Lines changed: 0 additions & 78 deletions
This file was deleted.

src/os/exec_other.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build (!aix && !android && !freebsd && !linux && !netbsd && !openbsd && !plan9 && !solaris) || baremetal || tinygo.wasm || nintendoswitch
1+
//go:build (!aix && !android && !darwin && !freebsd && !linux && !netbsd && !openbsd && !plan9 && !solaris) || baremetal || tinygo.wasm || nintendoswitch
22

33
package os
44

@@ -18,6 +18,49 @@ func (p *Process) release() error {
1818
return nil
1919
}
2020

21+
// ProcessState is a placeholder on targets that have no process model.
22+
type ProcessState struct {
23+
}
24+
25+
func (p *ProcessState) String() string {
26+
return "" // TODO
27+
}
28+
func (p *ProcessState) Success() bool {
29+
return false // TODO
30+
}
31+
32+
// Sys returns system-dependent exit information about
33+
// the process. Convert it to the appropriate underlying
34+
// type, such as syscall.WaitStatus on Unix, to access its contents.
35+
func (p *ProcessState) Sys() interface{} {
36+
return nil // TODO
37+
}
38+
39+
func (p *ProcessState) Exited() bool {
40+
return false // TODO
41+
}
42+
43+
// ExitCode returns the exit code of the exited process, or -1
44+
// if the process hasn't exited or was terminated by a signal.
45+
func (p *ProcessState) ExitCode() int {
46+
return -1 // TODO
47+
}
48+
49+
func (p *Process) Wait() (*ProcessState, error) {
50+
if p.Pid == -1 {
51+
return nil, syscall.EINVAL
52+
}
53+
return nil, ErrNotImplemented
54+
}
55+
56+
func (p *Process) Kill() error {
57+
return ErrNotImplemented
58+
}
59+
60+
func (p *Process) Signal(sig Signal) error {
61+
return ErrNotImplemented
62+
}
63+
2164
func forkExec(_ string, _ []string, _ *ProcAttr) (pid int, err error) {
2265
return 0, ErrNotImplemented
2366
}

0 commit comments

Comments
 (0)