syscall(linux):use clone as go instead fork

This commit is contained in:
luoliwoshang
2025-01-17 08:42:38 +00:00
parent ce26637410
commit 1b536bf5f8
2 changed files with 33 additions and 23 deletions

View File

@@ -276,6 +276,20 @@ func Getpid() PidT
//go:linkname Getppid C.getppid //go:linkname Getppid C.getppid
func Getppid() PidT func Getppid() PidT
// Invoke `system call' number SYSNO, passing it the remaining arguments.
// This is completely system-dependent, and not often useful.
// In Unix, `syscall' sets `errno' for all errors and most calls return -1
// for errors; in many systems you cannot pass arguments or get return
// values for all system calls (`pipe', `fork', and `getppid' typically
// among them).
// In Mach, all system calls take normal arguments and always return an
// error code (zero for success).
//
//go:linkname Syscall C.syscall
func Syscall(sysno c.Long, __llgo_va_list ...any) c.Long
//go:linkname Kill C.kill //go:linkname Kill C.kill
func Kill(pid PidT, sig c.Int) c.Int func Kill(pid PidT, sig c.Int) c.Int

View File

@@ -132,13 +132,12 @@ func runtime_AfterForkInChild()
func forkAndExecInChild(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) { func forkAndExecInChild(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
// Set up and fork. This returns immediately in the parent or // Set up and fork. This returns immediately in the parent or
// if there's an error. // if there's an error.
upid, err, _, locked := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe) upid, err, _, _ := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe)
/**
if locked { if locked {
/**
runtime_AfterFork() runtime_AfterFork()
*/
panic("todo: syscall.forkAndExecInChild - locked")
} }
*/
if err != 0 { if err != 0 {
return 0, err return 0, err
} }
@@ -283,7 +282,7 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
// Record parent PID so child can test if it has died. // Record parent PID so child can test if it has died.
/** /**
ppid, _ := rawSyscallNoError(syscall.SYS_GETPID, 0, 0, 0) ppid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
*/ */
// Guard against side effects of shuffling fds below. // Guard against side effects of shuffling fds below.
@@ -313,7 +312,11 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
flags = sys.Cloneflags flags = sys.Cloneflags
if sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0 { if sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0 {
flags |= CLONE_VFORK | CLONE_VM // The Go origin implement is:
// flags |= CLONE_VFORK | CLONE_VM
// llgo use CLONE_VFORK only.
// https://www.man7.org/linux/man-pages/man2/clone.2.html
flags |= CLONE_VFORK
} }
// Whether to use clone3. // Whether to use clone3.
if sys.UseCgroupFD { if sys.UseCgroupFD {
@@ -332,19 +335,6 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
// About to call fork. // About to call fork.
// No more allocation or calls of non-assembly functions. // No more allocation or calls of non-assembly functions.
// runtime_BeforeFork() // runtime_BeforeFork()
var r1 uintptr
r1, err1 = fork()
if err1 != 0 {
// runtime_AfterFork()
return 0, err1, mapPipe, locked
}
if r1 != 0 {
// parent; return PID
// runtime_AfterFork()
return r1, 0, mapPipe, locked
}
locked = true locked = true
if clone3 != nil { if clone3 != nil {
/** /**
@@ -356,8 +346,16 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
if runtime.GOARCH == "s390x" { if runtime.GOARCH == "s390x" {
// On Linux/s390, the first two arguments of clone(2) are swapped. // On Linux/s390, the first two arguments of clone(2) are swapped.
// pid, err1 = rawVforkSyscall(syscall.SYS_CLONE, 0, flags) // pid, err1 = rawVforkSyscall(syscall.SYS_CLONE, 0, flags)
panic("todo: syscall.forkAndExecInChild1 - GOARCH == s390x")
} else { } else {
// pid, err1 = rawVforkSyscall(syscall.SYS_CLONE, flags, 0) ret := os.Syscall(syscall.SYS_CLONE, flags, 0)
if ret >= 0 {
pid = uintptr(ret)
err1 = Errno(0)
} else {
pid = 0
err1 = Errno(os.Errno())
}
} }
} }
if err1 != 0 || pid != 0 { if err1 != 0 || pid != 0 {
@@ -671,11 +669,9 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
// started with, so if len(fd) < 3, close 0, 1, 2 as needed. // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
// Programs that know they inherit fds >= 3 will need // Programs that know they inherit fds >= 3 will need
// to set them close-on-exec. // to set them close-on-exec.
/**
for i = len(fd); i < 3; i++ { for i = len(fd); i < 3; i++ {
RawSyscall(syscall.SYS_CLOSE, uintptr(i), 0, 0) os.Close(c.Int(i))
} }
*/
// Detach fd 0 from tty // Detach fd 0 from tty
if sys.Noctty { if sys.Noctty {