(executable string, args []string, files []*os.File, env []string)
| 22 | } |
| 23 | |
| 24 | func newOSProcess(executable string, args []string, files []*os.File, env []string) (process, error) { |
| 25 | executable, err := exec.LookPath(executable) |
| 26 | if err != nil { |
| 27 | return nil, err |
| 28 | } |
| 29 | |
| 30 | fds := make([]uintptr, 0, len(files)) |
| 31 | for _, file := range files { |
| 32 | fd, err := sysConnFd(file) |
| 33 | if err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | fds = append(fds, fd) |
| 37 | } |
| 38 | |
| 39 | attr := &syscall.ProcAttr{ |
| 40 | Dir: initialWD, |
| 41 | Env: env, |
| 42 | Files: fds, |
| 43 | } |
| 44 | |
| 45 | args = append([]string{executable}, args...) |
| 46 | pid, _, err := syscall.StartProcess(executable, args, attr) |
| 47 | if err != nil { |
| 48 | return nil, fmt.Errorf("fork/exec: %s", err) |
| 49 | } |
| 50 | |
| 51 | // Ensure that fds stay valid until after StartProcess finishes. |
| 52 | runtime.KeepAlive(files) |
| 53 | |
| 54 | proc, err := os.FindProcess(pid) |
| 55 | if err != nil { |
| 56 | return nil, fmt.Errorf("find pid %d: %s", pid, err) |
| 57 | } |
| 58 | |
| 59 | return &osProcess{Process: proc}, nil |
| 60 | } |
| 61 | |
| 62 | func (osp *osProcess) Wait() error { |
| 63 | if osp.finished { |
searching dependent graphs…