1- package syscall
1+ //go: build !darwin && !nintendoswitch && !wasip1 && !wasip2
22
3- func Exec ( argv0 string , argv [] string , envv [] string ) ( err error )
3+ package syscall
44
55// The two SockaddrInet* structs have been copied from the Go source tree.
6-
76type SockaddrInet4 struct {
87 Port int
98 Addr [4 ]byte
@@ -16,3 +15,56 @@ type SockaddrInet6 struct {
1615 Addr [16 ]byte
1716 raw RawSockaddrInet6
1817}
18+
19+ /*
20+ func Fork() (err error) {
21+ fail := int(libc_fork())
22+ if fail < 0 {
23+ // TODO: parse the syscall return codes
24+ return errors.New("fork failed")
25+ }
26+ return
27+ }
28+
29+ // the golang standard library does not expose interfaces for execve and fork, so we define them here the same way via the libc wrapper
30+ func Execve(pathname string, argv []string, envv []string) (err error) {
31+ argv0 := cstring(pathname)
32+
33+ // transform argv and envv into the format expected by execve
34+ argv1 := make([]*byte, len(argv)+1)
35+ for i, arg := range argv {
36+ argv1[i] = &cstring(arg)[0]
37+ }
38+ argv1[len(argv)] = nil
39+
40+ env1 := make([]*byte, len(envv)+1)
41+ for i, env := range envv {
42+ env1[i] = &cstring(env)[0]
43+ }
44+ env1[len(envv)] = nil
45+
46+ fail := int(libc_execve(&argv0[0], &argv1[0], &env1[0]))
47+ if fail < 0 {
48+ // TODO: parse the syscall return codes
49+ return errors.New("fork failed")
50+ }
51+ return
52+ }
53+
54+ func cstring(s string) []byte {
55+ data := make([]byte, len(s)+1)
56+ copy(data, s)
57+ // final byte should be zero from the initial allocation
58+ return data
59+ }
60+
61+ // pid_t fork(void);
62+ //
63+ //export fork
64+ func libc_fork() int32
65+
66+ // int execve(const char *filename, char *const argv[], char *const envp[]);
67+ //
68+ //export execve
69+ func libc_execve(filename *byte, argv **byte, envp **byte) int
70+ */
0 commit comments