From c165325ed1850eb3678ff0ac5d37cc370a8b6cc5 Mon Sep 17 00:00:00 2001 From: Peter Waller Date: Wed, 21 May 2014 19:24:11 +0100 Subject: [PATCH] Embed *exec.Cmd in Process struct Motivation: Trying to slim the Process wrapper as much as possible to make later transformations easier. --- process.go | 39 ++++++++++----------------------------- run.go | 13 ++++++++----- start.go | 7 ++++--- unix.go | 4 ++-- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/process.go b/process.go index 9f3e391..ff8aa47 100644 --- a/process.go +++ b/process.go @@ -1,7 +1,6 @@ package main import ( - "io" "os" "os/exec" "syscall" @@ -11,35 +10,21 @@ type Process struct { Command string Env Env Interactive bool - Stdin io.Reader - Stdout io.Writer - Stderr io.Writer - Root string - cmd *exec.Cmd + *exec.Cmd } -func NewProcess(command string, env Env) (p *Process) { - p = new(Process) - p.Command = command - p.Env = env - p.Interactive = false - p.Stdin = os.Stdin - p.Stdout = os.Stdout - p.Stderr = os.Stderr - return +func NewProcess(workdir, command string, env Env, interactive bool) (p *Process) { + argv := ShellInvocationCommand(interactive, workdir, command) + return &Process{ + command, env, interactive, exec.Command(argv[0], argv[1:]...), + } } -func (p *Process) Start() { - command := ShellInvocationCommand(p.Interactive, p.Root, p.Command) - p.cmd = exec.Command(command[0], command[1:]...) - p.cmd.Dir = p.Root - p.cmd.Env = p.Env.asArray() - p.cmd.Stdin = p.Stdin - p.cmd.Stdout = p.Stdout - p.cmd.Stderr = p.Stderr +func (p *Process) Start() error { + p.Cmd.Env = p.Env.asArray() p.PlatformSpecificInit() - p.cmd.Start() + return p.Cmd.Start() } func (p *Process) Signal(signal syscall.Signal) { @@ -48,9 +33,5 @@ func (p *Process) Signal(signal syscall.Signal) { } func (p *Process) Pid() int { - return p.cmd.Process.Pid -} - -func (p *Process) Wait() { - p.cmd.Wait() + return p.Process.Pid } diff --git a/run.go b/run.go index 6b2d5dd..d7f067d 100644 --- a/run.go +++ b/run.go @@ -35,12 +35,15 @@ func runRun(cmd *Command, args []string) { env, err := ReadEnv(flagEnv) handleError(err) - ps := NewProcess(strings.Join(args, " "), env) - ps.Interactive = true - ps.Root = workDir + const interactive = true + ps := NewProcess(workDir, strings.Join(args, " "), env, interactive) ps.Stdin = os.Stdin ps.Stdout = os.Stdout ps.Stderr = os.Stderr - ps.Start() - ps.Wait() + + err = ps.Start() + handleError(err) + + err = ps.Wait() + handleError(err) } diff --git a/start.go b/start.go index a40dc75..1b1a72c 100644 --- a/start.go +++ b/start.go @@ -109,10 +109,11 @@ func (f *Forego) monitorInterrupt() { func (f *Forego) startProcess(idx, procNum int, proc ProcfileEntry, env Env, of *OutletFactory) { port := flagPort + (idx * 100) - ps := NewProcess(proc.Command, env) + const interactive = false + workDir := filepath.Dir(flagProcfile) + ps := NewProcess(workDir, proc.Command, env, interactive) procName := fmt.Sprint(proc.Name, ".", procNum+1) ps.Env["PORT"] = strconv.Itoa(port) - ps.Root = filepath.Dir(flagProcfile) ps.Stdin = nil ps.Stdout = of.CreateOutlet(procName, idx, false) ps.Stderr = of.CreateOutlet(procName, idx, true) @@ -148,7 +149,7 @@ func (f *Forego) startProcess(idx, procNum int, proc ProcfileEntry, env Env, of if !osHaveSigTerm { of.SystemOutput(fmt.Sprintf("Killing %s", procName)) - ps.cmd.Process.Kill() + ps.Process.Kill() return } diff --git a/unix.go b/unix.go index f691293..7f31bfe 100644 --- a/unix.go +++ b/unix.go @@ -23,8 +23,8 @@ func ShellInvocationCommand(interactive bool, root, command string) []string { func (p *Process) PlatformSpecificInit() { if !p.Interactive { - p.cmd.SysProcAttr = &syscall.SysProcAttr{} - p.cmd.SysProcAttr.Setsid = true + p.SysProcAttr = &syscall.SysProcAttr{} + p.SysProcAttr.Setsid = true } return }