exec_plan9.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  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. // Fork, exec, wait, etc.
  5. package plan9
  6. import (
  7. "runtime"
  8. "sync"
  9. "unsafe"
  10. )
  11. // Lock synchronizing creation of new file descriptors with fork.
  12. //
  13. // We want the child in a fork/exec sequence to inherit only the
  14. // file descriptors we intend. To do that, we mark all file
  15. // descriptors close-on-exec and then, in the child, explicitly
  16. // unmark the ones we want the exec'ed program to keep.
  17. // Unix doesn't make this easy: there is, in general, no way to
  18. // allocate a new file descriptor close-on-exec. Instead you
  19. // have to allocate the descriptor and then mark it close-on-exec.
  20. // If a fork happens between those two events, the child's exec
  21. // will inherit an unwanted file descriptor.
  22. //
  23. // This lock solves that race: the create new fd/mark close-on-exec
  24. // operation is done holding ForkLock for reading, and the fork itself
  25. // is done holding ForkLock for writing. At least, that's the idea.
  26. // There are some complications.
  27. //
  28. // Some system calls that create new file descriptors can block
  29. // for arbitrarily long times: open on a hung NFS server or named
  30. // pipe, accept on a socket, and so on. We can't reasonably grab
  31. // the lock across those operations.
  32. //
  33. // It is worse to inherit some file descriptors than others.
  34. // If a non-malicious child accidentally inherits an open ordinary file,
  35. // that's not a big deal. On the other hand, if a long-lived child
  36. // accidentally inherits the write end of a pipe, then the reader
  37. // of that pipe will not see EOF until that child exits, potentially
  38. // causing the parent program to hang. This is a common problem
  39. // in threaded C programs that use popen.
  40. //
  41. // Luckily, the file descriptors that are most important not to
  42. // inherit are not the ones that can take an arbitrarily long time
  43. // to create: pipe returns instantly, and the net package uses
  44. // non-blocking I/O to accept on a listening socket.
  45. // The rules for which file descriptor-creating operations use the
  46. // ForkLock are as follows:
  47. //
  48. // 1) Pipe. Does not block. Use the ForkLock.
  49. // 2) Socket. Does not block. Use the ForkLock.
  50. // 3) Accept. If using non-blocking mode, use the ForkLock.
  51. // Otherwise, live with the race.
  52. // 4) Open. Can block. Use O_CLOEXEC if available (Linux).
  53. // Otherwise, live with the race.
  54. // 5) Dup. Does not block. Use the ForkLock.
  55. // On Linux, could use fcntl F_DUPFD_CLOEXEC
  56. // instead of the ForkLock, but only for dup(fd, -1).
  57. var ForkLock sync.RWMutex
  58. // StringSlicePtr is deprecated. Use SlicePtrFromStrings instead.
  59. // If any string contains a NUL byte this function panics instead
  60. // of returning an error.
  61. func StringSlicePtr(ss []string) []*byte {
  62. bb := make([]*byte, len(ss)+1)
  63. for i := 0; i < len(ss); i++ {
  64. bb[i] = StringBytePtr(ss[i])
  65. }
  66. bb[len(ss)] = nil
  67. return bb
  68. }
  69. // SlicePtrFromStrings converts a slice of strings to a slice of
  70. // pointers to NUL-terminated byte slices. If any string contains
  71. // a NUL byte, it returns (nil, EINVAL).
  72. func SlicePtrFromStrings(ss []string) ([]*byte, error) {
  73. var err error
  74. bb := make([]*byte, len(ss)+1)
  75. for i := 0; i < len(ss); i++ {
  76. bb[i], err = BytePtrFromString(ss[i])
  77. if err != nil {
  78. return nil, err
  79. }
  80. }
  81. bb[len(ss)] = nil
  82. return bb, nil
  83. }
  84. // readdirnames returns the names of files inside the directory represented by dirfd.
  85. func readdirnames(dirfd int) (names []string, err error) {
  86. names = make([]string, 0, 100)
  87. var buf [STATMAX]byte
  88. for {
  89. n, e := Read(dirfd, buf[:])
  90. if e != nil {
  91. return nil, e
  92. }
  93. if n == 0 {
  94. break
  95. }
  96. for i := 0; i < n; {
  97. m, _ := gbit16(buf[i:])
  98. m += 2
  99. if m < STATFIXLEN {
  100. return nil, ErrBadStat
  101. }
  102. s, _, ok := gstring(buf[i+41:])
  103. if !ok {
  104. return nil, ErrBadStat
  105. }
  106. names = append(names, s)
  107. i += int(m)
  108. }
  109. }
  110. return
  111. }
  112. // readdupdevice returns a list of currently opened fds (excluding stdin, stdout, stderr) from the dup device #d.
  113. // ForkLock should be write locked before calling, so that no new fds would be created while the fd list is being read.
  114. func readdupdevice() (fds []int, err error) {
  115. dupdevfd, err := Open("#d", O_RDONLY)
  116. if err != nil {
  117. return
  118. }
  119. defer Close(dupdevfd)
  120. names, err := readdirnames(dupdevfd)
  121. if err != nil {
  122. return
  123. }
  124. fds = make([]int, 0, len(names)/2)
  125. for _, name := range names {
  126. if n := len(name); n > 3 && name[n-3:n] == "ctl" {
  127. continue
  128. }
  129. fd := int(atoi([]byte(name)))
  130. switch fd {
  131. case 0, 1, 2, dupdevfd:
  132. continue
  133. }
  134. fds = append(fds, fd)
  135. }
  136. return
  137. }
  138. var startupFds []int
  139. // Plan 9 does not allow clearing the OCEXEC flag
  140. // from the underlying channel backing an open file descriptor,
  141. // therefore we store a list of already opened file descriptors
  142. // inside startupFds and skip them when manually closing descriptors
  143. // not meant to be passed to a child exec.
  144. func init() {
  145. startupFds, _ = readdupdevice()
  146. }
  147. // forkAndExecInChild forks the process, calling dup onto 0..len(fd)
  148. // and finally invoking exec(argv0, argvv, envv) in the child.
  149. // If a dup or exec fails, it writes the error string to pipe.
  150. // (The pipe write end is close-on-exec so if exec succeeds, it will be closed.)
  151. //
  152. // In the child, this function must not acquire any locks, because
  153. // they might have been locked at the time of the fork. This means
  154. // no rescheduling, no malloc calls, and no new stack segments.
  155. // The calls to RawSyscall are okay because they are assembly
  156. // functions that do not grow the stack.
  157. func forkAndExecInChild(argv0 *byte, argv []*byte, envv []envItem, dir *byte, attr *ProcAttr, fdsToClose []int, pipe int, rflag int) (pid int, err error) {
  158. // Declare all variables at top in case any
  159. // declarations require heap allocation (e.g., errbuf).
  160. var (
  161. r1 uintptr
  162. nextfd int
  163. i int
  164. clearenv int
  165. envfd int
  166. errbuf [ERRMAX]byte
  167. )
  168. // Guard against side effects of shuffling fds below.
  169. // Make sure that nextfd is beyond any currently open files so
  170. // that we can't run the risk of overwriting any of them.
  171. fd := make([]int, len(attr.Files))
  172. nextfd = len(attr.Files)
  173. for i, ufd := range attr.Files {
  174. if nextfd < int(ufd) {
  175. nextfd = int(ufd)
  176. }
  177. fd[i] = int(ufd)
  178. }
  179. nextfd++
  180. if envv != nil {
  181. clearenv = RFCENVG
  182. }
  183. // About to call fork.
  184. // No more allocation or calls of non-assembly functions.
  185. r1, _, _ = RawSyscall(SYS_RFORK, uintptr(RFPROC|RFFDG|RFREND|clearenv|rflag), 0, 0)
  186. if r1 != 0 {
  187. if int32(r1) == -1 {
  188. return 0, NewError(errstr())
  189. }
  190. // parent; return PID
  191. return int(r1), nil
  192. }
  193. // Fork succeeded, now in child.
  194. // Close fds we don't need.
  195. for i = 0; i < len(fdsToClose); i++ {
  196. r1, _, _ = RawSyscall(SYS_CLOSE, uintptr(fdsToClose[i]), 0, 0)
  197. if int32(r1) == -1 {
  198. goto childerror
  199. }
  200. }
  201. if envv != nil {
  202. // Write new environment variables.
  203. for i = 0; i < len(envv); i++ {
  204. r1, _, _ = RawSyscall(SYS_CREATE, uintptr(unsafe.Pointer(envv[i].name)), uintptr(O_WRONLY), uintptr(0666))
  205. if int32(r1) == -1 {
  206. goto childerror
  207. }
  208. envfd = int(r1)
  209. r1, _, _ = RawSyscall6(SYS_PWRITE, uintptr(envfd), uintptr(unsafe.Pointer(envv[i].value)), uintptr(envv[i].nvalue),
  210. ^uintptr(0), ^uintptr(0), 0)
  211. if int32(r1) == -1 || int(r1) != envv[i].nvalue {
  212. goto childerror
  213. }
  214. r1, _, _ = RawSyscall(SYS_CLOSE, uintptr(envfd), 0, 0)
  215. if int32(r1) == -1 {
  216. goto childerror
  217. }
  218. }
  219. }
  220. // Chdir
  221. if dir != nil {
  222. r1, _, _ = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
  223. if int32(r1) == -1 {
  224. goto childerror
  225. }
  226. }
  227. // Pass 1: look for fd[i] < i and move those up above len(fd)
  228. // so that pass 2 won't stomp on an fd it needs later.
  229. if pipe < nextfd {
  230. r1, _, _ = RawSyscall(SYS_DUP, uintptr(pipe), uintptr(nextfd), 0)
  231. if int32(r1) == -1 {
  232. goto childerror
  233. }
  234. pipe = nextfd
  235. nextfd++
  236. }
  237. for i = 0; i < len(fd); i++ {
  238. if fd[i] >= 0 && fd[i] < int(i) {
  239. r1, _, _ = RawSyscall(SYS_DUP, uintptr(fd[i]), uintptr(nextfd), 0)
  240. if int32(r1) == -1 {
  241. goto childerror
  242. }
  243. fd[i] = nextfd
  244. nextfd++
  245. if nextfd == pipe { // don't stomp on pipe
  246. nextfd++
  247. }
  248. }
  249. }
  250. // Pass 2: dup fd[i] down onto i.
  251. for i = 0; i < len(fd); i++ {
  252. if fd[i] == -1 {
  253. RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
  254. continue
  255. }
  256. if fd[i] == int(i) {
  257. continue
  258. }
  259. r1, _, _ = RawSyscall(SYS_DUP, uintptr(fd[i]), uintptr(i), 0)
  260. if int32(r1) == -1 {
  261. goto childerror
  262. }
  263. }
  264. // Pass 3: close fd[i] if it was moved in the previous pass.
  265. for i = 0; i < len(fd); i++ {
  266. if fd[i] >= 0 && fd[i] != int(i) {
  267. RawSyscall(SYS_CLOSE, uintptr(fd[i]), 0, 0)
  268. }
  269. }
  270. // Time to exec.
  271. r1, _, _ = RawSyscall(SYS_EXEC,
  272. uintptr(unsafe.Pointer(argv0)),
  273. uintptr(unsafe.Pointer(&argv[0])), 0)
  274. childerror:
  275. // send error string on pipe
  276. RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&errbuf[0])), uintptr(len(errbuf)), 0)
  277. errbuf[len(errbuf)-1] = 0
  278. i = 0
  279. for i < len(errbuf) && errbuf[i] != 0 {
  280. i++
  281. }
  282. RawSyscall6(SYS_PWRITE, uintptr(pipe), uintptr(unsafe.Pointer(&errbuf[0])), uintptr(i),
  283. ^uintptr(0), ^uintptr(0), 0)
  284. for {
  285. RawSyscall(SYS_EXITS, 0, 0, 0)
  286. }
  287. // Calling panic is not actually safe,
  288. // but the for loop above won't break
  289. // and this shuts up the compiler.
  290. panic("unreached")
  291. }
  292. func cexecPipe(p []int) error {
  293. e := Pipe(p)
  294. if e != nil {
  295. return e
  296. }
  297. fd, e := Open("#d/"+itoa(p[1]), O_CLOEXEC)
  298. if e != nil {
  299. Close(p[0])
  300. Close(p[1])
  301. return e
  302. }
  303. Close(fd)
  304. return nil
  305. }
  306. type envItem struct {
  307. name *byte
  308. value *byte
  309. nvalue int
  310. }
  311. type ProcAttr struct {
  312. Dir string // Current working directory.
  313. Env []string // Environment.
  314. Files []uintptr // File descriptors.
  315. Sys *SysProcAttr
  316. }
  317. type SysProcAttr struct {
  318. Rfork int // additional flags to pass to rfork
  319. }
  320. var zeroProcAttr ProcAttr
  321. var zeroSysProcAttr SysProcAttr
  322. func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
  323. var (
  324. p [2]int
  325. n int
  326. errbuf [ERRMAX]byte
  327. wmsg Waitmsg
  328. )
  329. if attr == nil {
  330. attr = &zeroProcAttr
  331. }
  332. sys := attr.Sys
  333. if sys == nil {
  334. sys = &zeroSysProcAttr
  335. }
  336. p[0] = -1
  337. p[1] = -1
  338. // Convert args to C form.
  339. argv0p, err := BytePtrFromString(argv0)
  340. if err != nil {
  341. return 0, err
  342. }
  343. argvp, err := SlicePtrFromStrings(argv)
  344. if err != nil {
  345. return 0, err
  346. }
  347. var dir *byte
  348. if attr.Dir != "" {
  349. dir, err = BytePtrFromString(attr.Dir)
  350. if err != nil {
  351. return 0, err
  352. }
  353. }
  354. var envvParsed []envItem
  355. if attr.Env != nil {
  356. envvParsed = make([]envItem, 0, len(attr.Env))
  357. for _, v := range attr.Env {
  358. i := 0
  359. for i < len(v) && v[i] != '=' {
  360. i++
  361. }
  362. envname, err := BytePtrFromString("/env/" + v[:i])
  363. if err != nil {
  364. return 0, err
  365. }
  366. envvalue := make([]byte, len(v)-i)
  367. copy(envvalue, v[i+1:])
  368. envvParsed = append(envvParsed, envItem{envname, &envvalue[0], len(v) - i})
  369. }
  370. }
  371. // Acquire the fork lock to prevent other threads from creating new fds before we fork.
  372. ForkLock.Lock()
  373. // get a list of open fds, excluding stdin,stdout and stderr that need to be closed in the child.
  374. // no new fds can be created while we hold the ForkLock for writing.
  375. openFds, e := readdupdevice()
  376. if e != nil {
  377. ForkLock.Unlock()
  378. return 0, e
  379. }
  380. fdsToClose := make([]int, 0, len(openFds))
  381. for _, fd := range openFds {
  382. doClose := true
  383. // exclude files opened at startup.
  384. for _, sfd := range startupFds {
  385. if fd == sfd {
  386. doClose = false
  387. break
  388. }
  389. }
  390. // exclude files explicitly requested by the caller.
  391. for _, rfd := range attr.Files {
  392. if fd == int(rfd) {
  393. doClose = false
  394. break
  395. }
  396. }
  397. if doClose {
  398. fdsToClose = append(fdsToClose, fd)
  399. }
  400. }
  401. // Allocate child status pipe close on exec.
  402. e = cexecPipe(p[:])
  403. if e != nil {
  404. return 0, e
  405. }
  406. fdsToClose = append(fdsToClose, p[0])
  407. // Kick off child.
  408. pid, err = forkAndExecInChild(argv0p, argvp, envvParsed, dir, attr, fdsToClose, p[1], sys.Rfork)
  409. if err != nil {
  410. if p[0] >= 0 {
  411. Close(p[0])
  412. Close(p[1])
  413. }
  414. ForkLock.Unlock()
  415. return 0, err
  416. }
  417. ForkLock.Unlock()
  418. // Read child error status from pipe.
  419. Close(p[1])
  420. n, err = Read(p[0], errbuf[:])
  421. Close(p[0])
  422. if err != nil || n != 0 {
  423. if n != 0 {
  424. err = NewError(string(errbuf[:n]))
  425. }
  426. // Child failed; wait for it to exit, to make sure
  427. // the zombies don't accumulate.
  428. for wmsg.Pid != pid {
  429. Await(&wmsg)
  430. }
  431. return 0, err
  432. }
  433. // Read got EOF, so pipe closed on exec, so exec succeeded.
  434. return pid, nil
  435. }
  436. type waitErr struct {
  437. Waitmsg
  438. err error
  439. }
  440. var procs struct {
  441. sync.Mutex
  442. waits map[int]chan *waitErr
  443. }
  444. // startProcess starts a new goroutine, tied to the OS
  445. // thread, which runs the process and subsequently waits
  446. // for it to finish, communicating the process stats back
  447. // to any goroutines that may have been waiting on it.
  448. //
  449. // Such a dedicated goroutine is needed because on
  450. // Plan 9, only the parent thread can wait for a child,
  451. // whereas goroutines tend to jump OS threads (e.g.,
  452. // between starting a process and running Wait(), the
  453. // goroutine may have been rescheduled).
  454. func startProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
  455. type forkRet struct {
  456. pid int
  457. err error
  458. }
  459. forkc := make(chan forkRet, 1)
  460. go func() {
  461. runtime.LockOSThread()
  462. var ret forkRet
  463. ret.pid, ret.err = forkExec(argv0, argv, attr)
  464. // If fork fails there is nothing to wait for.
  465. if ret.err != nil || ret.pid == 0 {
  466. forkc <- ret
  467. return
  468. }
  469. waitc := make(chan *waitErr, 1)
  470. // Mark that the process is running.
  471. procs.Lock()
  472. if procs.waits == nil {
  473. procs.waits = make(map[int]chan *waitErr)
  474. }
  475. procs.waits[ret.pid] = waitc
  476. procs.Unlock()
  477. forkc <- ret
  478. var w waitErr
  479. for w.err == nil && w.Pid != ret.pid {
  480. w.err = Await(&w.Waitmsg)
  481. }
  482. waitc <- &w
  483. close(waitc)
  484. }()
  485. ret := <-forkc
  486. return ret.pid, ret.err
  487. }
  488. // Combination of fork and exec, careful to be thread safe.
  489. func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
  490. return startProcess(argv0, argv, attr)
  491. }
  492. // StartProcess wraps ForkExec for package os.
  493. func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
  494. pid, err = startProcess(argv0, argv, attr)
  495. return pid, 0, err
  496. }
  497. // Ordinary exec.
  498. func Exec(argv0 string, argv []string, envv []string) (err error) {
  499. if envv != nil {
  500. r1, _, _ := RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
  501. if int32(r1) == -1 {
  502. return NewError(errstr())
  503. }
  504. for _, v := range envv {
  505. i := 0
  506. for i < len(v) && v[i] != '=' {
  507. i++
  508. }
  509. fd, e := Create("/env/"+v[:i], O_WRONLY, 0666)
  510. if e != nil {
  511. return e
  512. }
  513. _, e = Write(fd, []byte(v[i+1:]))
  514. if e != nil {
  515. Close(fd)
  516. return e
  517. }
  518. Close(fd)
  519. }
  520. }
  521. argv0p, err := BytePtrFromString(argv0)
  522. if err != nil {
  523. return err
  524. }
  525. argvp, err := SlicePtrFromStrings(argv)
  526. if err != nil {
  527. return err
  528. }
  529. _, _, e1 := Syscall(SYS_EXEC,
  530. uintptr(unsafe.Pointer(argv0p)),
  531. uintptr(unsafe.Pointer(&argvp[0])),
  532. 0)
  533. return e1
  534. }
  535. // WaitProcess waits until the pid of a
  536. // running process is found in the queue of
  537. // wait messages. It is used in conjunction
  538. // with ForkExec/StartProcess to wait for a
  539. // running process to exit.
  540. func WaitProcess(pid int, w *Waitmsg) (err error) {
  541. procs.Lock()
  542. ch := procs.waits[pid]
  543. procs.Unlock()
  544. var wmsg *waitErr
  545. if ch != nil {
  546. wmsg = <-ch
  547. procs.Lock()
  548. if procs.waits[pid] == ch {
  549. delete(procs.waits, pid)
  550. }
  551. procs.Unlock()
  552. }
  553. if wmsg == nil {
  554. // ch was missing or ch is closed
  555. return NewError("process not found")
  556. }
  557. if wmsg.err != nil {
  558. return wmsg.err
  559. }
  560. if w != nil {
  561. *w = wmsg.Waitmsg
  562. }
  563. return nil
  564. }