spawn_unix.c raw
1 //go:build none
2
3 // spawn_unix.c - C helpers for spawn that call libc functions.
4 // These avoid duplicate //export declarations in Go.
5
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <signal.h>
9 #include <unistd.h>
10
11 int moxie_fork(void) {
12 return (int)fork();
13 }
14
15 int moxie_close(int fd) {
16 return close(fd);
17 }
18
19 // socketpair implementation: use libc on Darwin, raw syscall on Linux.
20
21 #ifdef __APPLE__
22
23 #include <sys/socket.h>
24 int moxie_socketpair(int domain, int type, int protocol, int fds[2]) {
25 return socketpair(domain, type, protocol, fds);
26 }
27
28 #else // Linux — raw syscall to avoid musl networking deps.
29
30 #if defined(__x86_64__)
31
32 #define SYS_SOCKETPAIR 53
33
34 long __moxie_syscall4(long n, long a, long b, long c, long d);
35 __asm__(
36 ".global __moxie_syscall4\n"
37 "__moxie_syscall4:\n"
38 " mov %rdi, %rax\n" // syscall number
39 " mov %rsi, %rdi\n" // arg1
40 " mov %rdx, %rsi\n" // arg2
41 " mov %rcx, %rdx\n" // arg3
42 " mov %r8, %r10\n" // arg4 (syscall uses r10 not rcx)
43 " syscall\n"
44 " ret\n"
45 );
46
47 #elif defined(__aarch64__)
48
49 #define SYS_SOCKETPAIR 199
50
51 long __moxie_syscall4(long n, long a, long b, long c, long d);
52 __asm__(
53 ".global __moxie_syscall4\n"
54 "__moxie_syscall4:\n"
55 " mov x8, x0\n" // syscall number
56 " mov x0, x1\n" // arg1
57 " mov x1, x2\n" // arg2
58 " mov x2, x3\n" // arg3
59 " mov x3, x4\n" // arg4
60 " svc #0\n"
61 " ret\n"
62 );
63
64 #else
65 #error "Unsupported architecture for moxie spawn syscall"
66 #endif
67
68 int moxie_socketpair(int domain, int type, int protocol, int fds[2]) {
69 return (int)__moxie_syscall4(SYS_SOCKETPAIR, domain, type, protocol, (long)fds);
70 }
71
72 #endif // __APPLE__
73
74 // Pipe I/O — wraps read/write for the IPC channel bridge.
75 // Uses libc on all platforms since these are standard POSIX.
76
77 int moxie_write(int fd, const void *buf, int count) {
78 return (int)write(fd, buf, (size_t)count);
79 }
80
81 int moxie_read(int fd, void *buf, int count) {
82 return (int)read(fd, buf, (size_t)count);
83 }
84
85 int moxie_waitpid(int pid, int *status, int options) {
86 return (int)waitpid((pid_t)pid, status, options);
87 }
88
89 int moxie_kill(int pid, int sig) {
90 return kill((pid_t)pid, sig);
91 }
92