spawnbinary.mx raw
1 //go:build linux || darwin
2
3 package runtime
4
5 import "unsafe"
6
7 // SpawnBinary forks and execs an installed binary as a new domain.
8 // binPath is the absolute path to the binary in the mxinstall cache.
9 // hash is the .mxh content hash embedded at compile time for this spawn site,
10 // verified by SpawnHandshake on both sides.
11 // Returns the parent's IPC fd on success, -1 on error.
12 //
13 // Child stderr/stdout are inherited from the parent. Child panic traces and
14 // debug output will appear on the parent's terminal. This is intentional.
15 func SpawnBinary(binPath string, hash string) int32 {
16 var fds [2]int32
17 r := moxie_socketpair(1, 1, 0, unsafe.Pointer(&fds[0])) // AF_UNIX=1, SOCK_STREAM=1
18 if r < 0 {
19 println("spawn: socketpair failed for", binPath)
20 return -1
21 }
22 moxie_set_spawn_bufs(fds[0], fds[1])
23
24 pid := moxie_fork()
25 if pid < 0 {
26 moxie_close(fds[0])
27 moxie_close(fds[1])
28 println("spawn: fork failed for", binPath)
29 return -1
30 }
31
32 if pid == 0 {
33 // Child: moxie_exec_binary closes all fds except fds[1] (IPC fd),
34 // sets MOXIE_IPC_FD, then execs the binary. Does not return on success.
35 moxie_close(fds[0]) // close parent's end before exec
36 moxie_exec_binary(binPath, fds[1])
37 println("spawn: exec failed for", binPath)
38 exit(1)
39 }
40
41 // Parent: close child's fd.
42 moxie_close(fds[1])
43
44 // Perform handshake over the parent's fd.
45 if errMsg := SpawnHandshake(fds[0], []string{hash}); errMsg != "" {
46 println("spawn:", errMsg)
47 moxie_close(fds[0])
48 moxie_kill(pid, 9)
49 var status int32
50 moxie_waitpid(pid, unsafe.Pointer(&status), 0)
51 return -1
52 }
53
54 // Register with domain list so domainReapChildren handles cleanup.
55 domainRegister(pid, fds[0], -1)
56 return fds[0]
57 }
58
59 //export moxie_exec_binary
60 func moxie_exec_binary(path string, ipcFd int32) int32
61