exec_unix.go 8.0 KB

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