github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/syscall/exec_unix.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build darwin dragonfly freebsd linux netbsd openbsd solaris
     6  
     7  // Fork, exec, wait, etc.
     8  
     9  package syscall
    10  
    11  import (
    12  	"runtime"
    13  	"sync"
    14  	"unsafe"
    15  )
    16  
    17  //sysnb	raw_fork() (pid Pid_t, err Errno)
    18  //fork() Pid_t
    19  
    20  //sysnb	raw_getpid() (pid Pid_t)
    21  //getpid() Pid_t
    22  
    23  //sysnb	raw_getppid() (pid Pid_t)
    24  //getppid() Pid_t
    25  
    26  //sysnb raw_setsid() (err Errno)
    27  //setsid() Pid_t
    28  
    29  //sysnb raw_setpgid(pid int, pgid int) (err Errno)
    30  //setpgid(pid Pid_t, pgid Pid_t) _C_int
    31  
    32  //sysnb	raw_chroot(path *byte) (err Errno)
    33  //chroot(path *byte) _C_int
    34  
    35  //sysnb	raw_chdir(path *byte) (err Errno)
    36  //chdir(path *byte) _C_int
    37  
    38  //sysnb	raw_fcntl(fd int, cmd int, arg int) (val int, err Errno)
    39  //__go_fcntl(fd _C_int, cmd _C_int, arg _C_int) _C_int
    40  
    41  //sysnb	raw_close(fd int) (err Errno)
    42  //close(fd _C_int) _C_int
    43  
    44  //sysnb	raw_ioctl(fd int, cmd uintptr, val int) (rval int, err Errno)
    45  //__go_ioctl(fd _C_int, cmd _C_int, val _C_int) _C_int
    46  
    47  //sysnb raw_ioctl_ptr(fd int, cmd uintptr, val unsafe.Pointer) (rval int, err Errno)
    48  //__go_ioctl_ptr(fd _C_int, cmd _C_int, val unsafe.Pointer) _C_int
    49  
    50  //sysnb	raw_execve(argv0 *byte, argv **byte, envv **byte) (err Errno)
    51  //execve(argv0 *byte, argv **byte, envv **byte) _C_int
    52  
    53  //sysnb	raw_write(fd int, buf *byte, count int) (err Errno)
    54  //write(fd _C_int, buf *byte, count Size_t) Ssize_t
    55  
    56  //sysnb	raw_exit(status int)
    57  //_exit(status _C_int)
    58  
    59  //sysnb raw_dup2(oldfd int, newfd int) (err Errno)
    60  //dup2(oldfd _C_int, newfd _C_int) _C_int
    61  
    62  //sysnb raw_kill(pid Pid_t, sig Signal) (err Errno)
    63  //kill(pid Pid_t, sig _C_int) _C_int
    64  
    65  //sysnb raw_setgroups(size int, list unsafe.Pointer) (err Errno)
    66  //setgroups(size Size_t, list *Gid_t) _C_int
    67  
    68  //sysnb raw_setuid(uid int) (err Errno)
    69  //setuid(uid Uid_t) _C_int
    70  
    71  //sysnb raw_setgid(gid int) (err Errno)
    72  //setgid(gid Gid_t) _C_int
    73  
    74  // Lock synchronizing creation of new file descriptors with fork.
    75  //
    76  // We want the child in a fork/exec sequence to inherit only the
    77  // file descriptors we intend.  To do that, we mark all file
    78  // descriptors close-on-exec and then, in the child, explicitly
    79  // unmark the ones we want the exec'ed program to keep.
    80  // Unix doesn't make this easy: there is, in general, no way to
    81  // allocate a new file descriptor close-on-exec.  Instead you
    82  // have to allocate the descriptor and then mark it close-on-exec.
    83  // If a fork happens between those two events, the child's exec
    84  // will inherit an unwanted file descriptor.
    85  //
    86  // This lock solves that race: the create new fd/mark close-on-exec
    87  // operation is done holding ForkLock for reading, and the fork itself
    88  // is done holding ForkLock for writing.  At least, that's the idea.
    89  // There are some complications.
    90  //
    91  // Some system calls that create new file descriptors can block
    92  // for arbitrarily long times: open on a hung NFS server or named
    93  // pipe, accept on a socket, and so on.  We can't reasonably grab
    94  // the lock across those operations.
    95  //
    96  // It is worse to inherit some file descriptors than others.
    97  // If a non-malicious child accidentally inherits an open ordinary file,
    98  // that's not a big deal.  On the other hand, if a long-lived child
    99  // accidentally inherits the write end of a pipe, then the reader
   100  // of that pipe will not see EOF until that child exits, potentially
   101  // causing the parent program to hang.  This is a common problem
   102  // in threaded C programs that use popen.
   103  //
   104  // Luckily, the file descriptors that are most important not to
   105  // inherit are not the ones that can take an arbitrarily long time
   106  // to create: pipe returns instantly, and the net package uses
   107  // non-blocking I/O to accept on a listening socket.
   108  // The rules for which file descriptor-creating operations use the
   109  // ForkLock are as follows:
   110  //
   111  // 1) Pipe.    Does not block.  Use the ForkLock.
   112  // 2) Socket.  Does not block.  Use the ForkLock.
   113  // 3) Accept.  If using non-blocking mode, use the ForkLock.
   114  //             Otherwise, live with the race.
   115  // 4) Open.    Can block.  Use O_CLOEXEC if available (GNU/Linux).
   116  //             Otherwise, live with the race.
   117  // 5) Dup.     Does not block.  Use the ForkLock.
   118  //             On GNU/Linux, could use fcntl F_DUPFD_CLOEXEC
   119  //             instead of the ForkLock, but only for dup(fd, -1).
   120  
   121  var ForkLock sync.RWMutex
   122  
   123  // StringSlicePtr converts a slice of strings to a slice of pointers
   124  // to NUL-terminated byte arrays. If any string contains a NUL byte
   125  // this function panics instead of returning an error.
   126  //
   127  // Deprecated: Use SlicePtrFromStrings instead.
   128  func StringSlicePtr(ss []string) []*byte {
   129  	bb := make([]*byte, len(ss)+1)
   130  	for i := 0; i < len(ss); i++ {
   131  		bb[i] = StringBytePtr(ss[i])
   132  	}
   133  	bb[len(ss)] = nil
   134  	return bb
   135  }
   136  
   137  // SlicePtrFromStrings converts a slice of strings to a slice of
   138  // pointers to NUL-terminated byte arrays. If any string contains
   139  // a NUL byte, it returns (nil, EINVAL).
   140  func SlicePtrFromStrings(ss []string) ([]*byte, error) {
   141  	var err error
   142  	bb := make([]*byte, len(ss)+1)
   143  	for i := 0; i < len(ss); i++ {
   144  		bb[i], err = BytePtrFromString(ss[i])
   145  		if err != nil {
   146  			return nil, err
   147  		}
   148  	}
   149  	bb[len(ss)] = nil
   150  	return bb, nil
   151  }
   152  
   153  func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
   154  
   155  func SetNonblock(fd int, nonblocking bool) (err error) {
   156  	flag, err := fcntl(fd, F_GETFL, 0)
   157  	if err != nil {
   158  		return err
   159  	}
   160  	if nonblocking {
   161  		flag |= O_NONBLOCK
   162  	} else {
   163  		flag &= ^O_NONBLOCK
   164  	}
   165  	_, err = fcntl(fd, F_SETFL, flag)
   166  	return err
   167  }
   168  
   169  // Credential holds user and group identities to be assumed
   170  // by a child process started by StartProcess.
   171  type Credential struct {
   172  	Uid    uint32   // User ID.
   173  	Gid    uint32   // Group ID.
   174  	Groups []uint32 // Supplementary group IDs.
   175  }
   176  
   177  // ProcAttr holds attributes that will be applied to a new process started
   178  // by StartProcess.
   179  type ProcAttr struct {
   180  	Dir   string    // Current working directory.
   181  	Env   []string  // Environment.
   182  	Files []uintptr // File descriptors.
   183  	Sys   *SysProcAttr
   184  }
   185  
   186  var zeroProcAttr ProcAttr
   187  var zeroSysProcAttr SysProcAttr
   188  
   189  func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
   190  	var p [2]int
   191  	var n int
   192  	var err1 Errno
   193  	var wstatus WaitStatus
   194  
   195  	if attr == nil {
   196  		attr = &zeroProcAttr
   197  	}
   198  	sys := attr.Sys
   199  	if sys == nil {
   200  		sys = &zeroSysProcAttr
   201  	}
   202  
   203  	p[0] = -1
   204  	p[1] = -1
   205  
   206  	// Convert args to C form.
   207  	argv0p, err := BytePtrFromString(argv0)
   208  	if err != nil {
   209  		return 0, err
   210  	}
   211  	argvp, err := SlicePtrFromStrings(argv)
   212  	if err != nil {
   213  		return 0, err
   214  	}
   215  	envvp, err := SlicePtrFromStrings(attr.Env)
   216  	if err != nil {
   217  		return 0, err
   218  	}
   219  
   220  	if (runtime.GOOS == "freebsd" || runtime.GOOS == "dragonfly") && len(argv[0]) > len(argv0) {
   221  		argvp[0] = argv0p
   222  	}
   223  
   224  	var chroot *byte
   225  	if sys.Chroot != "" {
   226  		chroot, err = BytePtrFromString(sys.Chroot)
   227  		if err != nil {
   228  			return 0, err
   229  		}
   230  	}
   231  	var dir *byte
   232  	if attr.Dir != "" {
   233  		dir, err = BytePtrFromString(attr.Dir)
   234  		if err != nil {
   235  			return 0, err
   236  		}
   237  	}
   238  
   239  	// Acquire the fork lock so that no other threads
   240  	// create new fds that are not yet close-on-exec
   241  	// before we fork.
   242  	ForkLock.Lock()
   243  
   244  	// Allocate child status pipe close on exec.
   245  	if err = forkExecPipe(p[:]); err != nil {
   246  		goto error
   247  	}
   248  
   249  	// Kick off child.
   250  	pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
   251  	if err1 != 0 {
   252  		err = Errno(err1)
   253  		goto error
   254  	}
   255  	ForkLock.Unlock()
   256  
   257  	// Read child error status from pipe.
   258  	Close(p[1])
   259  	n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
   260  	Close(p[0])
   261  	if err != nil || n != 0 {
   262  		if n == int(unsafe.Sizeof(err1)) {
   263  			err = Errno(err1)
   264  		}
   265  		if err == nil {
   266  			err = EPIPE
   267  		}
   268  
   269  		// Child failed; wait for it to exit, to make sure
   270  		// the zombies don't accumulate.
   271  		_, err1 := Wait4(pid, &wstatus, 0, nil)
   272  		for err1 == EINTR {
   273  			_, err1 = Wait4(pid, &wstatus, 0, nil)
   274  		}
   275  		return 0, err
   276  	}
   277  
   278  	// Read got EOF, so pipe closed on exec, so exec succeeded.
   279  	return pid, nil
   280  
   281  error:
   282  	if p[0] >= 0 {
   283  		Close(p[0])
   284  		Close(p[1])
   285  	}
   286  	ForkLock.Unlock()
   287  	return 0, err
   288  }
   289  
   290  // Combination of fork and exec, careful to be thread safe.
   291  func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
   292  	return forkExec(argv0, argv, attr)
   293  }
   294  
   295  // StartProcess wraps ForkExec for package os.
   296  func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
   297  	pid, err = forkExec(argv0, argv, attr)
   298  	return pid, 0, err
   299  }
   300  
   301  // Ordinary exec.
   302  func Exec(argv0 string, argv []string, envv []string) (err error) {
   303  	argv0p, err := BytePtrFromString(argv0)
   304  	if err != nil {
   305  		return err
   306  	}
   307  	argvp, err := SlicePtrFromStrings(argv)
   308  	if err != nil {
   309  		return err
   310  	}
   311  	envvp, err := SlicePtrFromStrings(envv)
   312  	if err != nil {
   313  		return err
   314  	}
   315  	err1 := raw_execve(argv0p, &argvp[0], &envvp[0])
   316  	return Errno(err1)
   317  }