package syscall
import (
"unsafe"
)
type SysProcAttr struct {
Chroot string
Credential *Credential
Ptrace bool
Setsid bool
Setpgid bool
Setctty bool
Noctty bool
Ctty int
Foreground bool
Pgid int
}
func runtime_BeforeFork ()
func runtime_AfterFork ()
func runtime_AfterForkInChild ()
func forkAndExecInChild (argv0 *byte , argv , envv []*byte , chroot , dir *byte , attr *ProcAttr , sys *SysProcAttr , pipe int ) (pid int , err Errno ) {
var (
r1 uintptr
err1 Errno
nextfd int
i int
)
fd := make ([]int , len (attr .Files ))
nextfd = len (attr .Files )
for i , ufd := range attr .Files {
if nextfd < int (ufd ) {
nextfd = int (ufd )
}
fd [i ] = int (ufd )
}
nextfd ++
runtime_BeforeFork ()
r1 , _, err1 = rawSyscall (funcPC (libc_fork_trampoline ), 0 , 0 , 0 )
if err1 != 0 {
runtime_AfterFork ()
return 0 , err1
}
if r1 != 0 {
runtime_AfterFork ()
return int (r1 ), 0
}
runtime_AfterForkInChild ()
if sys .Ptrace {
if err := ptrace (PTRACE_TRACEME , 0 , 0 , 0 ); err != nil {
err1 = err .(Errno )
goto childerror
}
}
if sys .Setsid {
_, _, err1 = rawSyscall (funcPC (libc_setsid_trampoline ), 0 , 0 , 0 )
if err1 != 0 {
goto childerror
}
}
if sys .Setpgid || sys .Foreground {
_, _, err1 = rawSyscall (funcPC (libc_setpgid_trampoline ), 0 , uintptr (sys .Pgid ), 0 )
if err1 != 0 {
goto childerror
}
}
if sys .Foreground {
pgrp := sys .Pgid
if pgrp == 0 {
r1 , _, err1 = rawSyscall (funcPC (libc_getpid_trampoline ), 0 , 0 , 0 )
if err1 != 0 {
goto childerror
}
pgrp = int (r1 )
}
_, _, err1 = rawSyscall (funcPC (libc_ioctl_trampoline ), uintptr (sys .Ctty ), uintptr (TIOCSPGRP ), uintptr (unsafe .Pointer (&pgrp )))
if err1 != 0 {
goto childerror
}
}
if chroot != nil {
_, _, err1 = rawSyscall (funcPC (libc_chroot_trampoline ), uintptr (unsafe .Pointer (chroot )), 0 , 0 )
if err1 != 0 {
goto childerror
}
}
if cred := sys .Credential ; cred != nil {
ngroups := uintptr (len (cred .Groups ))
groups := uintptr (0 )
if ngroups > 0 {
groups = uintptr (unsafe .Pointer (&cred .Groups [0 ]))
}
if !cred .NoSetGroups {
_, _, err1 = rawSyscall (funcPC (libc_setgroups_trampoline ), ngroups , groups , 0 )
if err1 != 0 {
goto childerror
}
}
_, _, err1 = rawSyscall (funcPC (libc_setgid_trampoline ), uintptr (cred .Gid ), 0 , 0 )
if err1 != 0 {
goto childerror
}
_, _, err1 = rawSyscall (funcPC (libc_setuid_trampoline ), uintptr (cred .Uid ), 0 , 0 )
if err1 != 0 {
goto childerror
}
}
if dir != nil {
_, _, err1 = rawSyscall (funcPC (libc_chdir_trampoline ), uintptr (unsafe .Pointer (dir )), 0 , 0 )
if err1 != 0 {
goto childerror
}
}
if pipe < nextfd {
_, _, err1 = rawSyscall (funcPC (libc_dup2_trampoline ), uintptr (pipe ), uintptr (nextfd ), 0 )
if err1 != 0 {
goto childerror
}
rawSyscall (funcPC (libc_fcntl_trampoline ), uintptr (nextfd ), F_SETFD , FD_CLOEXEC )
pipe = nextfd
nextfd ++
}
for i = 0 ; i < len (fd ); i ++ {
if fd [i ] >= 0 && fd [i ] < int (i ) {
if nextfd == pipe {
nextfd ++
}
_, _, err1 = rawSyscall (funcPC (libc_dup2_trampoline ), uintptr (fd [i ]), uintptr (nextfd ), 0 )
if err1 != 0 {
goto childerror
}
rawSyscall (funcPC (libc_fcntl_trampoline ), uintptr (nextfd ), F_SETFD , FD_CLOEXEC )
fd [i ] = nextfd
nextfd ++
}
}
for i = 0 ; i < len (fd ); i ++ {
if fd [i ] == -1 {
rawSyscall (funcPC (libc_close_trampoline ), uintptr (i ), 0 , 0 )
continue
}
if fd [i ] == int (i ) {
_, _, err1 = rawSyscall (funcPC (libc_fcntl_trampoline ), uintptr (fd [i ]), F_SETFD , 0 )
if err1 != 0 {
goto childerror
}
continue
}
_, _, err1 = rawSyscall (funcPC (libc_dup2_trampoline ), uintptr (fd [i ]), uintptr (i ), 0 )
if err1 != 0 {
goto childerror
}
}
for i = len (fd ); i < 3 ; i ++ {
rawSyscall (funcPC (libc_close_trampoline ), uintptr (i ), 0 , 0 )
}
if sys .Noctty {
_, _, err1 = rawSyscall (funcPC (libc_ioctl_trampoline ), 0 , uintptr (TIOCNOTTY ), 0 )
if err1 != 0 {
goto childerror
}
}
if sys .Setctty {
_, _, err1 = rawSyscall (funcPC (libc_ioctl_trampoline ), uintptr (sys .Ctty ), uintptr (TIOCSCTTY ), 0 )
if err1 != 0 {
goto childerror
}
}
_, _, err1 = rawSyscall (funcPC (libc_execve_trampoline ),
uintptr (unsafe .Pointer (argv0 )),
uintptr (unsafe .Pointer (&argv [0 ])),
uintptr (unsafe .Pointer (&envv [0 ])))
childerror :
rawSyscall (funcPC (libc_write_trampoline ), uintptr (pipe ), uintptr (unsafe .Pointer (&err1 )), unsafe .Sizeof (err1 ))
for {
rawSyscall (funcPC (libc_exit_trampoline ), 253 , 0 , 0 )
}
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .