diff options
| author | Ondřej Surý <ondrej@sury.org> | 2011-02-18 09:50:58 +0100 | 
|---|---|---|
| committer | Ondřej Surý <ondrej@sury.org> | 2011-02-18 09:50:58 +0100 | 
| commit | c072558b90f1bbedc2022b0f30c8b1ac4712538e (patch) | |
| tree | 67767591619e4bd8111fb05fac185cde94fb7378 /src/pkg/exec/exec.go | |
| parent | 5859517b767c99749a45651c15d4bae5520ebae8 (diff) | |
| download | golang-c072558b90f1bbedc2022b0f30c8b1ac4712538e.tar.gz | |
Imported Upstream version 2011.02.15upstream/2011.02.15
Diffstat (limited to 'src/pkg/exec/exec.go')
| -rw-r--r-- | src/pkg/exec/exec.go | 80 | 
1 files changed, 42 insertions, 38 deletions
| diff --git a/src/pkg/exec/exec.go b/src/pkg/exec/exec.go index 4f4c8c777..80f6f3c7d 100644 --- a/src/pkg/exec/exec.go +++ b/src/pkg/exec/exec.go @@ -22,12 +22,12 @@ const (  // Stdin, Stdout, and Stderr are Files representing pipes  // connected to the running command's standard input, output, and error,  // or else nil, depending on the arguments to Run. -// Pid is the running command's operating system process ID. +// Process represents the underlying operating system process.  type Cmd struct { -	Stdin  *os.File -	Stdout *os.File -	Stderr *os.File -	Pid    int +	Stdin   *os.File +	Stdout  *os.File +	Stderr  *os.File +	Process *os.Process  }  // PathError records the name of a binary that was not @@ -88,24 +88,24 @@ func modeToFiles(mode, fd int) (*os.File, *os.File, os.Error) {  // If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr)  // of the returned Cmd is the other end of the pipe.  // Otherwise the field in Cmd is nil. -func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (p *Cmd, err os.Error) { -	p = new(Cmd) +func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int) (c *Cmd, err os.Error) { +	c = new(Cmd)  	var fd [3]*os.File -	if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil { +	if fd[0], c.Stdin, err = modeToFiles(stdin, 0); err != nil {  		goto Error  	} -	if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil { +	if fd[1], c.Stdout, err = modeToFiles(stdout, 1); err != nil {  		goto Error  	}  	if stderr == MergeWithStdout {  		fd[2] = fd[1] -	} else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil { +	} else if fd[2], c.Stderr, err = modeToFiles(stderr, 2); err != nil {  		goto Error  	}  	// Run command. -	p.Pid, err = os.ForkExec(name, argv, envv, dir, fd[0:]) +	c.Process, err = os.StartProcess(name, argv, envv, dir, fd[0:])  	if err != nil {  		goto Error  	} @@ -118,7 +118,7 @@ func Run(name string, argv, envv []string, dir string, stdin, stdout, stderr int  	if fd[2] != os.Stderr && fd[2] != fd[1] {  		fd[2].Close()  	} -	return p, nil +	return c, nil  Error:  	if fd[0] != os.Stdin && fd[0] != nil { @@ -130,63 +130,67 @@ Error:  	if fd[2] != os.Stderr && fd[2] != nil && fd[2] != fd[1] {  		fd[2].Close()  	} -	if p.Stdin != nil { -		p.Stdin.Close() +	if c.Stdin != nil { +		c.Stdin.Close()  	} -	if p.Stdout != nil { -		p.Stdout.Close() +	if c.Stdout != nil { +		c.Stdout.Close()  	} -	if p.Stderr != nil { -		p.Stderr.Close() +	if c.Stderr != nil { +		c.Stderr.Close() +	} +	if c.Process != nil { +		c.Process.Release()  	}  	return nil, err  } -// Wait waits for the running command p, -// returning the Waitmsg returned by os.Wait and an error. -// The options are passed through to os.Wait. -// Setting options to 0 waits for p to exit; +// Wait waits for the running command c, +// returning the Waitmsg returned when the process exits. +// The options are passed to the process's Wait method. +// Setting options to 0 waits for c to exit;  // other options cause Wait to return for other  // process events; see package os for details. -func (p *Cmd) Wait(options int) (*os.Waitmsg, os.Error) { -	if p.Pid <= 0 { +func (c *Cmd) Wait(options int) (*os.Waitmsg, os.Error) { +	if c.Process == nil {  		return nil, os.ErrorString("exec: invalid use of Cmd.Wait")  	} -	w, err := os.Wait(p.Pid, options) +	w, err := c.Process.Wait(options)  	if w != nil && (w.Exited() || w.Signaled()) { -		p.Pid = -1 +		c.Process.Release() +		c.Process = nil  	}  	return w, err  } -// Close waits for the running command p to exit, +// Close waits for the running command c to exit,  // if it hasn't already, and then closes the non-nil file descriptors -// p.Stdin, p.Stdout, and p.Stderr. -func (p *Cmd) Close() os.Error { -	if p.Pid > 0 { +// c.Stdin, c.Stdout, and c.Stderr. +func (c *Cmd) Close() os.Error { +	if c.Process != nil {  		// Loop on interrupt, but  		// ignore other errors -- maybe  		// caller has already waited for pid. -		_, err := p.Wait(0) +		_, err := c.Wait(0)  		for err == os.EINTR { -			_, err = p.Wait(0) +			_, err = c.Wait(0)  		}  	}  	// Close the FDs that are still open.  	var err os.Error -	if p.Stdin != nil && p.Stdin.Fd() >= 0 { -		if err1 := p.Stdin.Close(); err1 != nil { +	if c.Stdin != nil && c.Stdin.Fd() >= 0 { +		if err1 := c.Stdin.Close(); err1 != nil {  			err = err1  		}  	} -	if p.Stdout != nil && p.Stdout.Fd() >= 0 { -		if err1 := p.Stdout.Close(); err1 != nil && err != nil { +	if c.Stdout != nil && c.Stdout.Fd() >= 0 { +		if err1 := c.Stdout.Close(); err1 != nil && err != nil {  			err = err1  		}  	} -	if p.Stderr != nil && p.Stderr != p.Stdout && p.Stderr.Fd() >= 0 { -		if err1 := p.Stderr.Close(); err1 != nil && err != nil { +	if c.Stderr != nil && c.Stderr != c.Stdout && c.Stderr.Fd() >= 0 { +		if err1 := c.Stderr.Close(); err1 != nil && err != nil {  			err = err1  		}  	} | 
