diff options
Diffstat (limited to 'src/syscall/syscall_darwin.go')
-rw-r--r-- | src/syscall/syscall_darwin.go | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go index 902d6e77e1..346e6862cd 100644 --- a/src/syscall/syscall_darwin.go +++ b/src/syscall/syscall_darwin.go @@ -17,6 +17,34 @@ import ( "unsafe" ) +// These are called from exec_libc2.go in the child of fork. +// The names differ between macOS and OpenBSD, so we need +// to declare the specific ones used here to keep the exec_libc2.go +// code portable. +// +// We use __fork and __exit, not fork and exit, to avoid the libc atfork +// and atexit handlers. The atfork handlers have caused fork child +// hangs in the past (see #33565, #56784). The atexit handlers have +// not, but the non-libc ports all invoke the system call, so doing +// the same here makes sense. In general we wouldn't expect +// atexit handlers to work terribly well in a fork child anyway. +// (Also, perhaps the atfork handlers clear the atexit handlers, +// in which case we definitely need to avoid calling the libc exit +// if we bypass the libc fork.) +// +// Other calls that are made in the child after the fork are +// ptrace, setsid, setpgid, getpid, ioctl, chroot, setgroups, +// setgid, setuid, chdir, dup2, fcntl, close, execve, and write. +// Those are all simple kernel wrappers that should be safe +// to be called directly. The fcntl and ioctl functions do run +// some code around the kernel call, but they don't call any +// other functions, so for now we keep using them instead of +// calling the lower-level __fcntl and __ioctl functions. +var ( + exitTrampoline = abi.FuncPCABI0(libc___exit_trampoline) + forkTrampoline = abi.FuncPCABI0(libc___fork_trampoline) +) + type SockaddrDatalink struct { Len uint8 Family uint8 @@ -202,11 +230,12 @@ func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1) //sys writev(fd int, iovecs []Iovec) (cnt uintptr, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sysnb fork() (pid int, err error) +//sysnb __fork() (pid int, err error) //sysnb ioctl(fd int, req int, arg int) (err error) //sysnb ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) = SYS_ioctl //sysnb execve(path *byte, argv **byte, envp **byte) (err error) //sysnb exit(res int) (err error) +//sysnb __exit(res int) (err error) //sys sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) //sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_fcntl //sys unlinkat(fd int, path string, flags int) (err error) |