OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package exec runs external commands. It wraps os.StartProcess to make it | 5 // Package exec runs external commands. It wraps os.StartProcess to make it |
6 // easier to remap stdin and stdout, connect I/O with pipes, and do other | 6 // easier to remap stdin and stdout, connect I/O with pipes, and do other |
7 // adjustments. | 7 // adjustments. |
8 package exec | 8 package exec |
9 | 9 |
10 import ( | 10 import ( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 // | 58 // |
59 // If Stdout and Stderr are are the same writer, at most one | 59 // If Stdout and Stderr are are the same writer, at most one |
60 // goroutine at a time will call Write. | 60 // goroutine at a time will call Write. |
61 Stdout io.Writer | 61 Stdout io.Writer |
62 Stderr io.Writer | 62 Stderr io.Writer |
63 | 63 |
64 err os.Error // last error (from LookPath, stdin, stdout, st
derr) | 64 err os.Error // last error (from LookPath, stdin, stdout, st
derr) |
65 process *os.Process | 65 process *os.Process |
66 finished bool // when Wait was called | 66 finished bool // when Wait was called |
67 childFiles []*os.File | 67 childFiles []*os.File |
68 » closeAfterStart []*os.File | 68 » closeAfterStart []io.Closer |
69 » closeAfterWait []*os.File | 69 » closeAfterWait []io.Closer |
70 goroutine []func() os.Error | 70 goroutine []func() os.Error |
71 errch chan os.Error // one send per goroutine | 71 errch chan os.Error // one send per goroutine |
72 } | 72 } |
73 | 73 |
74 // Command returns the Cmd struct to execute the named program with | 74 // Command returns the Cmd struct to execute the named program with |
75 // the given arguments. | 75 // the given arguments. |
76 // | 76 // |
77 // It sets Path and Args in the returned structure and zeroes the | 77 // It sets Path and Args in the returned structure and zeroes the |
78 // other fields. | 78 // other fields. |
79 // | 79 // |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 } | 300 } |
301 if c.Stderr != nil { | 301 if c.Stderr != nil { |
302 return nil, os.NewError("exec: Stderr already set") | 302 return nil, os.NewError("exec: Stderr already set") |
303 } | 303 } |
304 var b bytes.Buffer | 304 var b bytes.Buffer |
305 c.Stdout = &b | 305 c.Stdout = &b |
306 c.Stderr = &b | 306 c.Stderr = &b |
307 err := c.Run() | 307 err := c.Run() |
308 return b.Bytes(), err | 308 return b.Bytes(), err |
309 } | 309 } |
| 310 |
| 311 // StdinPipe returns a pipe that will be connected to the command's |
| 312 // standard input when the command starts. |
| 313 func (c *Cmd) StdinPipe() (io.WriteCloser, os.Error) { |
| 314 if c.Stdin != nil { |
| 315 return nil, os.NewError("exec: Stdin already set") |
| 316 } |
| 317 if c.process != nil { |
| 318 return nil, os.NewError("exec: StdinPipe after process started") |
| 319 } |
| 320 pr, pw, err := os.Pipe() |
| 321 if err != nil { |
| 322 return nil, err |
| 323 } |
| 324 c.Stdin = pr |
| 325 c.closeAfterStart = append(c.closeAfterStart, pr) |
| 326 c.closeAfterWait = append(c.closeAfterStart, pw) |
| 327 return pw, nil |
| 328 } |
| 329 |
| 330 // StdoutPipe returns a pipe that will be connected to the command's |
| 331 // standard output when the command starts. |
| 332 func (c *Cmd) StdoutPipe() (io.Reader, os.Error) { |
| 333 if c.Stdout != nil { |
| 334 return nil, os.NewError("exec: Stdout already set") |
| 335 } |
| 336 if c.process != nil { |
| 337 return nil, os.NewError("exec: StdoutPipe after process started"
) |
| 338 } |
| 339 pr, pw, err := os.Pipe() |
| 340 if err != nil { |
| 341 return nil, err |
| 342 } |
| 343 c.Stdout = pw |
| 344 c.closeAfterStart = append(c.closeAfterStart, pw) |
| 345 c.closeAfterWait = append(c.closeAfterStart, pr) |
| 346 return pr, nil |
| 347 } |
| 348 |
| 349 // StderrPipe returns a pipe that will be connected to the command's |
| 350 // standard error when the command starts. |
| 351 func (c *Cmd) StderrPipe() (io.Reader, os.Error) { |
| 352 if c.Stderr != nil { |
| 353 return nil, os.NewError("exec: Stderr already set") |
| 354 } |
| 355 if c.process != nil { |
| 356 return nil, os.NewError("exec: StderrPipe after process started"
) |
| 357 } |
| 358 pr, pw, err := os.Pipe() |
| 359 if err != nil { |
| 360 return nil, err |
| 361 } |
| 362 c.Stderr = pw |
| 363 c.closeAfterStart = append(c.closeAfterStart, pw) |
| 364 c.closeAfterWait = append(c.closeAfterStart, pr) |
| 365 return pr, nil |
| 366 } |
OLD | NEW |