Skip to content

Commit

Permalink
syscall(linux):use clone as go instead fork
Browse files Browse the repository at this point in the history
  • Loading branch information
luoliwoshang committed Jan 17, 2025
1 parent adde0ab commit 08fd9c1
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
14 changes: 14 additions & 0 deletions runtime/internal/clite/os/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,20 @@ func Getpid() PidT
//go:linkname Getppid C.getppid
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
func Kill(pid PidT, sig c.Int) c.Int

Expand Down
36 changes: 14 additions & 22 deletions runtime/internal/lib/syscall/exec_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
// Set up and fork. This returns immediately in the parent or
// 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 {
/**
runtime_AfterFork()
*/
panic("todo: syscall.forkAndExecInChild - locked")
}
*/
if err != 0 {
return 0, err
}
Expand Down Expand Up @@ -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.
/**
ppid, _ := rawSyscallNoError(syscall.SYS_GETPID, 0, 0, 0)
ppid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
*/

// Guard against side effects of shuffling fds below.
Expand Down Expand Up @@ -332,19 +331,6 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
// About to call fork.
// No more allocation or calls of non-assembly functions.
// 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
if clone3 != nil {
/**
Expand All @@ -356,8 +342,16 @@ func forkAndExecInChild1(argv0 *c.Char, argv, envv **c.Char, chroot, dir *c.Char
if runtime.GOARCH == "s390x" {
// On Linux/s390, the first two arguments of clone(2) are swapped.
// pid, err1 = rawVforkSyscall(syscall.SYS_CLONE, 0, flags)
panic("todo: syscall.forkAndExecInChild1 - GOARCH == s390x")
} 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 {
Expand Down Expand Up @@ -671,11 +665,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.
// Programs that know they inherit fds >= 3 will need
// to set them close-on-exec.
/**
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
if sys.Noctty {
Expand Down

0 comments on commit 08fd9c1

Please sign in to comment.