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