Skip to content

Commit 70bfa96

Browse files
committed
replace raw syscall implementation with musl wrapper
Signed-off-by: leongross <[email protected]>
1 parent 61267ad commit 70bfa96

File tree

4 files changed

+73
-12
lines changed

4 files changed

+73
-12
lines changed

builder/musl.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ var libMusl = Library{
136136
"thread/*.c",
137137
"time/*.c",
138138
"unistd/*.c",
139+
"process/*.c",
139140
}
140141
if arch == "arm" {
141142
// These files need to be added to the start for some reason.

src/os/exec_linux.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ var (
2222
Kill Signal = syscall.SIGKILL
2323
)
2424

25+
var (
26+
ErrNotImplementedDir = errors.New("directory setting not implemented")
27+
ErrNotImplementedSys = errors.New("sys setting not implemented")
28+
ErrNotImplementedFiles = errors.New("files setting not implemented")
29+
)
30+
2531
// Keep compatible with golang and always succeed and return new proc with pid on Linux.
2632
func findProcess(pid int) (*Process, error) {
2733
return &Process{Pid: pid}, nil
@@ -57,7 +63,9 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
5763
attr = new(ProcAttr)
5864
}
5965

60-
pid, err = fork()
66+
p, err := fork()
67+
pid = int(p)
68+
6169
if err != nil {
6270
return 0, err
6371
} else {
@@ -78,6 +86,20 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
7886
// The StartProcess function creates a new process by forking the current process and then calling execve to replace the current process with the new process.
7987
// It thereby replaces the newly created process with the specified command and arguments.
8088
func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
89+
if attr != nil {
90+
if attr.Dir != "" {
91+
return nil, ErrNotImplementedDir
92+
}
93+
94+
if attr.Sys != nil {
95+
return nil, ErrNotImplementedSys
96+
}
97+
98+
if len(attr.Files) != 0 {
99+
return nil, ErrNotImplementedFiles
100+
}
101+
}
102+
81103
pid, err := forkExec(name, argv, attr)
82104
if err != nil {
83105
return nil, err

src/os/exec_linux_test.go

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"errors"
77
. "os"
88
"runtime"
9+
"syscall"
910
"testing"
1011
)
1112

@@ -27,10 +28,9 @@ func TestForkExec(t *testing.T) {
2728
t.Fatalf("forkExec failed: new process has pid 0")
2829
}
2930
t.Logf("forkExec succeeded: new process has pid %d", proc)
30-
3131
}
3232

33-
func TestForkExecInvalid(t *testing.T) {
33+
func TestForkExecErrNotExist(t *testing.T) {
3434
proc, err := StartProcess("invalid", []string{"invalid"}, &ProcAttr{})
3535
if !errors.Is(err, ErrNotExist) {
3636
t.Fatalf("wanted ErrNotExist, got %s\n", err)
@@ -40,3 +40,36 @@ func TestForkExecInvalid(t *testing.T) {
4040
t.Fatalf("wanted nil, got %v\n", proc)
4141
}
4242
}
43+
44+
func TestForkExecProcDir(t *testing.T) {
45+
proc, err := StartProcess("/bin/echo", []string{"hello", "world"}, &ProcAttr{Dir: "dir"})
46+
if !errors.Is(err, ErrNotImplementedDir) {
47+
t.Fatalf("wanted ErrNotImplementedDir, got %v\n", err)
48+
}
49+
50+
if proc != nil {
51+
t.Fatalf("wanted nil, got %v\n", proc)
52+
}
53+
}
54+
55+
func TestForkExecProcSys(t *testing.T) {
56+
proc, err := StartProcess("/bin/echo", []string{"hello", "world"}, &ProcAttr{Sys: &syscall.SysProcAttr{}})
57+
if !errors.Is(err, ErrNotImplementedSys) {
58+
t.Fatalf("wanted ErrNotImplementedSys, got %v\n", err)
59+
}
60+
61+
if proc != nil {
62+
t.Fatalf("wanted nil, got %v\n", proc)
63+
}
64+
}
65+
66+
func TestForkExecProcFiles(t *testing.T) {
67+
proc, err := StartProcess("/bin/echo", []string{"hello", "world"}, &ProcAttr{Files: []*File{}})
68+
if !errors.Is(err, ErrNotImplementedFiles) {
69+
t.Fatalf("wanted ErrNotImplementedFiles, got %v\n", err)
70+
}
71+
72+
if proc != nil {
73+
t.Fatalf("wanted nil, got %v\n", proc)
74+
}
75+
}

src/os/osexec.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//go:build linux && !baremetal && !darwin && !tinygo.wasm && !arm64
1+
//go:build linux && !baremetal && !tinygo.wasm && !arm64
22

33
// arm64 does not have a fork syscall, so ignore it for now
44
// TODO: add support for arm64 with clone or use musl implementation
@@ -10,15 +10,12 @@ import (
1010
"unsafe"
1111
)
1212

13-
func fork() (pid int, err error) {
14-
ret, _, err := syscall.Syscall(syscall.SYS_FORK, 0, 0, 0)
15-
if int(ret) != 0 {
16-
errno := err.(syscall.Errno)
17-
if int(errno) != 0 {
18-
return -1, errno
19-
}
13+
func fork() (pid int32, err error) {
14+
pid = libc_fork()
15+
if pid != 0 {
16+
err = syscall.Errno(*libc_errno())
2017
}
21-
return int(ret), nil
18+
return
2219
}
2320

2421
// the golang standard library does not expose interfaces for execve and fork, so we define them here the same way via the libc wrapper
@@ -52,3 +49,11 @@ func cstring(s string) []byte {
5249
// final byte should be zero from the initial allocation
5350
return data
5451
}
52+
53+
//export fork
54+
func libc_fork() int32
55+
56+
// Internal musl function to get the C errno pointer.
57+
//
58+
//export __errno_location
59+
func libc_errno() *int32

0 commit comments

Comments
 (0)