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