(name string, argv []string, attr *ProcAttr)
| 27 | ) |
| 28 | |
| 29 | func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) { |
| 30 | // If there is no SysProcAttr (ie. no Chroot or changed |
| 31 | // UID/GID), double-check existence of the directory we want |
| 32 | // to chdir into. We can make the error clearer this way. |
| 33 | if attr != nil && attr.Sys == nil && attr.Dir != "" { |
| 34 | if _, err := os.Stat(attr.Dir); err != nil { |
| 35 | pe := err.(*os.PathError) |
| 36 | pe.Op = "chdir" |
| 37 | return nil, pe |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | sysattr := &forkexec.ProcAttr{ |
| 42 | Dir: attr.Dir, |
| 43 | Env: attr.Env, |
| 44 | Sys: attr.Sys, |
| 45 | } |
| 46 | if sysattr.Env == nil { |
| 47 | sysattr.Env, err = execenv.Default(sysattr.Sys) |
| 48 | if err != nil { |
| 49 | return nil, err |
| 50 | } |
| 51 | } |
| 52 | sysattr.Files = make([]uintptr, 0, len(attr.Files)) |
| 53 | for _, f := range attr.Files { |
| 54 | if fi, ok := f.(*os.File); ok { |
| 55 | sysattr.Files = append(sysattr.Files, fi.Fd()) |
| 56 | } else if fd, ok := f.(uintptr); ok { |
| 57 | sysattr.Files = append(sysattr.Files, fd) |
| 58 | } else { |
| 59 | return nil, errors.Errorf("Files only allow *os.File and uintptr(file descriptor)") |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | pid, h, e := forkexec.StartProcess(name, argv, sysattr) |
| 64 | |
| 65 | // Make sure we don't run the finalizers of attr.Files. |
| 66 | runtime.KeepAlive(attr) |
| 67 | |
| 68 | if e != nil { |
| 69 | return nil, &os.PathError{Op: "fork/exec", Path: name, Err: e} |
| 70 | } |
| 71 | |
| 72 | return newProcess(pid, h), nil |
| 73 | } |
| 74 | |
| 75 | func (p *Process) kill() error { |
| 76 | return p.Signal(Kill) |
no test coverage detected