github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/os/exec/exec.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 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 7 // adjustments. 8 // 9 // Note that the examples in this package assume a Unix system. 10 // They may not run on Windows, and they do not run in the Go Playground 11 // used by golang.org and godoc.org. 12 package exec 13 14 import ( 15 "bytes" 16 "errors" 17 "io" 18 "os" 19 "path/filepath" 20 "runtime" 21 "strconv" 22 "strings" 23 "sync" 24 "syscall" 25 ) 26 27 // Error records the name of a binary that failed to be executed 28 // and the reason it failed. 29 type Error struct { 30 Name string 31 Err error 32 } 33 34 func (e *Error) Error() string { 35 return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error() 36 } 37 38 // Cmd represents an external command being prepared or run. 39 // 40 // A Cmd cannot be reused after calling its Run, Output or CombinedOutput 41 // methods. 42 type Cmd struct { 43 // Path is the path of the command to run. 44 // 45 // This is the only field that must be set to a non-zero 46 // value. If Path is relative, it is evaluated relative 47 // to Dir. 48 Path string 49 50 // Args holds command line arguments, including the command as Args[0]. 51 // If the Args field is empty or nil, Run uses {Path}. 52 // 53 // In typical use, both Path and Args are set by calling Command. 54 Args []string 55 56 // Env specifies the environment of the process. 57 // If Env is nil, Run uses the current process's environment. 58 Env []string 59 60 // Dir specifies the working directory of the command. 61 // If Dir is the empty string, Run runs the command in the 62 // calling process's current directory. 63 Dir string 64 65 // Stdin specifies the process's standard input. 66 // If Stdin is nil, the process reads from the null device (os.DevNull). 67 // If Stdin is an *os.File, the process's standard input is connected 68 // directly to that file. 69 // Otherwise, during the execution of the command a separate 70 // goroutine reads from Stdin and delivers that data to the command 71 // over a pipe. In this case, Wait does not complete until the goroutine 72 // stops copying, either because it has reached the end of Stdin 73 // (EOF or a read error) or because writing to the pipe returned an error. 74 Stdin io.Reader 75 76 // Stdout and Stderr specify the process's standard output and error. 77 // 78 // If either is nil, Run connects the corresponding file descriptor 79 // to the null device (os.DevNull). 80 // 81 // If Stdout and Stderr are the same writer, at most one 82 // goroutine at a time will call Write. 83 Stdout io.Writer 84 Stderr io.Writer 85 86 // ExtraFiles specifies additional open files to be inherited by the 87 // new process. It does not include standard input, standard output, or 88 // standard error. If non-nil, entry i becomes file descriptor 3+i. 89 // 90 // BUG(rsc): On OS X 10.6, child processes may sometimes inherit unwanted fds. 91 // https://golang.org/issue/2603 92 ExtraFiles []*os.File 93 94 // SysProcAttr holds optional, operating system-specific attributes. 95 // Run passes it to os.StartProcess as the os.ProcAttr's Sys field. 96 SysProcAttr *syscall.SysProcAttr 97 98 // Process is the underlying process, once started. 99 Process *os.Process 100 101 // ProcessState contains information about an exited process, 102 // available after a call to Wait or Run. 103 ProcessState *os.ProcessState 104 105 lookPathErr error // LookPath error, if any. 106 finished bool // when Wait was called 107 childFiles []*os.File 108 closeAfterStart []io.Closer 109 closeAfterWait []io.Closer 110 goroutine []func() error 111 errch chan error // one send per goroutine 112 } 113 114 // Command returns the Cmd struct to execute the named program with 115 // the given arguments. 116 // 117 // It sets only the Path and Args in the returned structure. 118 // 119 // If name contains no path separators, Command uses LookPath to 120 // resolve the path to a complete name if possible. Otherwise it uses 121 // name directly. 122 // 123 // The returned Cmd's Args field is constructed from the command name 124 // followed by the elements of arg, so arg should not include the 125 // command name itself. For example, Command("echo", "hello") 126 func Command(name string, arg ...string) *Cmd { 127 cmd := &Cmd{ 128 Path: name, 129 Args: append([]string{name}, arg...), 130 } 131 if filepath.Base(name) == name { 132 if lp, err := LookPath(name); err != nil { 133 cmd.lookPathErr = err 134 } else { 135 cmd.Path = lp 136 } 137 } 138 return cmd 139 } 140 141 // interfaceEqual protects against panics from doing equality tests on 142 // two interfaces with non-comparable underlying types. 143 func interfaceEqual(a, b interface{}) bool { 144 defer func() { 145 recover() 146 }() 147 return a == b 148 } 149 150 func (c *Cmd) envv() []string { 151 if c.Env != nil { 152 return c.Env 153 } 154 return os.Environ() 155 } 156 157 func (c *Cmd) argv() []string { 158 if len(c.Args) > 0 { 159 return c.Args 160 } 161 return []string{c.Path} 162 } 163 164 // skipStdinCopyError optionally specifies a function which reports 165 // whether the provided the stdin copy error should be ignored. 166 // It is non-nil everywhere but Plan 9, which lacks EPIPE. See exec_posix.go. 167 var skipStdinCopyError func(error) bool 168 169 func (c *Cmd) stdin() (f *os.File, err error) { 170 if c.Stdin == nil { 171 f, err = os.Open(os.DevNull) 172 if err != nil { 173 return 174 } 175 c.closeAfterStart = append(c.closeAfterStart, f) 176 return 177 } 178 179 if f, ok := c.Stdin.(*os.File); ok { 180 return f, nil 181 } 182 183 pr, pw, err := os.Pipe() 184 if err != nil { 185 return 186 } 187 188 c.closeAfterStart = append(c.closeAfterStart, pr) 189 c.closeAfterWait = append(c.closeAfterWait, pw) 190 c.goroutine = append(c.goroutine, func() error { 191 _, err := io.Copy(pw, c.Stdin) 192 if skip := skipStdinCopyError; skip != nil && skip(err) { 193 err = nil 194 } 195 if err1 := pw.Close(); err == nil { 196 err = err1 197 } 198 return err 199 }) 200 return pr, nil 201 } 202 203 func (c *Cmd) stdout() (f *os.File, err error) { 204 return c.writerDescriptor(c.Stdout) 205 } 206 207 func (c *Cmd) stderr() (f *os.File, err error) { 208 if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) { 209 return c.childFiles[1], nil 210 } 211 return c.writerDescriptor(c.Stderr) 212 } 213 214 func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) { 215 if w == nil { 216 f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0) 217 if err != nil { 218 return 219 } 220 c.closeAfterStart = append(c.closeAfterStart, f) 221 return 222 } 223 224 if f, ok := w.(*os.File); ok { 225 return f, nil 226 } 227 228 pr, pw, err := os.Pipe() 229 if err != nil { 230 return 231 } 232 233 c.closeAfterStart = append(c.closeAfterStart, pw) 234 c.closeAfterWait = append(c.closeAfterWait, pr) 235 c.goroutine = append(c.goroutine, func() error { 236 _, err := io.Copy(w, pr) 237 pr.Close() // in case io.Copy stopped due to write error 238 return err 239 }) 240 return pw, nil 241 } 242 243 func (c *Cmd) closeDescriptors(closers []io.Closer) { 244 for _, fd := range closers { 245 fd.Close() 246 } 247 } 248 249 // Run starts the specified command and waits for it to complete. 250 // 251 // The returned error is nil if the command runs, has no problems 252 // copying stdin, stdout, and stderr, and exits with a zero exit 253 // status. 254 // 255 // If the command fails to run or doesn't complete successfully, the 256 // error is of type *ExitError. Other error types may be 257 // returned for I/O problems. 258 func (c *Cmd) Run() error { 259 if err := c.Start(); err != nil { 260 return err 261 } 262 return c.Wait() 263 } 264 265 // lookExtensions finds windows executable by its dir and path. 266 // It uses LookPath to try appropriate extensions. 267 // lookExtensions does not search PATH, instead it converts `prog` into `.\prog`. 268 func lookExtensions(path, dir string) (string, error) { 269 if filepath.Base(path) == path { 270 path = filepath.Join(".", path) 271 } 272 if dir == "" { 273 return LookPath(path) 274 } 275 if filepath.VolumeName(path) != "" { 276 return LookPath(path) 277 } 278 if len(path) > 1 && os.IsPathSeparator(path[0]) { 279 return LookPath(path) 280 } 281 dirandpath := filepath.Join(dir, path) 282 // We assume that LookPath will only add file extension. 283 lp, err := LookPath(dirandpath) 284 if err != nil { 285 return "", err 286 } 287 ext := strings.TrimPrefix(lp, dirandpath) 288 return path + ext, nil 289 } 290 291 // Start starts the specified command but does not wait for it to complete. 292 // 293 // The Wait method will return the exit code and release associated resources 294 // once the command exits. 295 func (c *Cmd) Start() error { 296 if c.lookPathErr != nil { 297 c.closeDescriptors(c.closeAfterStart) 298 c.closeDescriptors(c.closeAfterWait) 299 return c.lookPathErr 300 } 301 if runtime.GOOS == "windows" { 302 lp, err := lookExtensions(c.Path, c.Dir) 303 if err != nil { 304 c.closeDescriptors(c.closeAfterStart) 305 c.closeDescriptors(c.closeAfterWait) 306 return err 307 } 308 c.Path = lp 309 } 310 if c.Process != nil { 311 return errors.New("exec: already started") 312 } 313 314 type F func(*Cmd) (*os.File, error) 315 for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} { 316 fd, err := setupFd(c) 317 if err != nil { 318 c.closeDescriptors(c.closeAfterStart) 319 c.closeDescriptors(c.closeAfterWait) 320 return err 321 } 322 c.childFiles = append(c.childFiles, fd) 323 } 324 c.childFiles = append(c.childFiles, c.ExtraFiles...) 325 326 var err error 327 c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{ 328 Dir: c.Dir, 329 Files: c.childFiles, 330 Env: c.envv(), 331 Sys: c.SysProcAttr, 332 }) 333 if err != nil { 334 c.closeDescriptors(c.closeAfterStart) 335 c.closeDescriptors(c.closeAfterWait) 336 return err 337 } 338 339 c.closeDescriptors(c.closeAfterStart) 340 341 c.errch = make(chan error, len(c.goroutine)) 342 for _, fn := range c.goroutine { 343 go func(fn func() error) { 344 c.errch <- fn() 345 }(fn) 346 } 347 348 return nil 349 } 350 351 // An ExitError reports an unsuccessful exit by a command. 352 type ExitError struct { 353 *os.ProcessState 354 355 // Stderr holds a subset of the standard error output from the 356 // Cmd.Output method if standard error was not otherwise being 357 // collected. 358 // 359 // If the error output is long, Stderr may contain only a prefix 360 // and suffix of the output, with the middle replaced with 361 // text about the number of omitted bytes. 362 // 363 // Stderr is provided for debugging, for inclusion in error messages. 364 // Users with other needs should redirect Cmd.Stderr as needed. 365 Stderr []byte 366 } 367 368 func (e *ExitError) Error() string { 369 return e.ProcessState.String() 370 } 371 372 // Wait waits for the command to exit. 373 // It must have been started by Start. 374 // 375 // The returned error is nil if the command runs, has no problems 376 // copying stdin, stdout, and stderr, and exits with a zero exit 377 // status. 378 // 379 // If the command fails to run or doesn't complete successfully, the 380 // error is of type *ExitError. Other error types may be 381 // returned for I/O problems. 382 // 383 // If c.Stdin is not an *os.File, Wait also waits for the I/O loop 384 // copying from c.Stdin into the process's standard input 385 // to complete. 386 // 387 // Wait releases any resources associated with the Cmd. 388 func (c *Cmd) Wait() error { 389 if c.Process == nil { 390 return errors.New("exec: not started") 391 } 392 if c.finished { 393 return errors.New("exec: Wait was already called") 394 } 395 c.finished = true 396 state, err := c.Process.Wait() 397 c.ProcessState = state 398 399 var copyError error 400 for range c.goroutine { 401 if err := <-c.errch; err != nil && copyError == nil { 402 copyError = err 403 } 404 } 405 406 c.closeDescriptors(c.closeAfterWait) 407 408 if err != nil { 409 return err 410 } else if !state.Success() { 411 return &ExitError{ProcessState: state} 412 } 413 414 return copyError 415 } 416 417 // Output runs the command and returns its standard output. 418 // Any returned error will usually be of type *ExitError. 419 // If c.Stderr was nil, Output populates ExitError.Stderr. 420 func (c *Cmd) Output() ([]byte, error) { 421 if c.Stdout != nil { 422 return nil, errors.New("exec: Stdout already set") 423 } 424 var stdout bytes.Buffer 425 c.Stdout = &stdout 426 427 captureErr := c.Stderr == nil 428 if captureErr { 429 c.Stderr = &prefixSuffixSaver{N: 32 << 10} 430 } 431 432 err := c.Run() 433 if err != nil && captureErr { 434 if ee, ok := err.(*ExitError); ok { 435 ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes() 436 } 437 } 438 return stdout.Bytes(), err 439 } 440 441 // CombinedOutput runs the command and returns its combined standard 442 // output and standard error. 443 func (c *Cmd) CombinedOutput() ([]byte, error) { 444 if c.Stdout != nil { 445 return nil, errors.New("exec: Stdout already set") 446 } 447 if c.Stderr != nil { 448 return nil, errors.New("exec: Stderr already set") 449 } 450 var b bytes.Buffer 451 c.Stdout = &b 452 c.Stderr = &b 453 err := c.Run() 454 return b.Bytes(), err 455 } 456 457 // StdinPipe returns a pipe that will be connected to the command's 458 // standard input when the command starts. 459 // The pipe will be closed automatically after Wait sees the command exit. 460 // A caller need only call Close to force the pipe to close sooner. 461 // For example, if the command being run will not exit until standard input 462 // is closed, the caller must close the pipe. 463 func (c *Cmd) StdinPipe() (io.WriteCloser, error) { 464 if c.Stdin != nil { 465 return nil, errors.New("exec: Stdin already set") 466 } 467 if c.Process != nil { 468 return nil, errors.New("exec: StdinPipe after process started") 469 } 470 pr, pw, err := os.Pipe() 471 if err != nil { 472 return nil, err 473 } 474 c.Stdin = pr 475 c.closeAfterStart = append(c.closeAfterStart, pr) 476 wc := &closeOnce{File: pw} 477 c.closeAfterWait = append(c.closeAfterWait, wc) 478 return wc, nil 479 } 480 481 type closeOnce struct { 482 *os.File 483 484 once sync.Once 485 err error 486 } 487 488 func (c *closeOnce) Close() error { 489 c.once.Do(c.close) 490 return c.err 491 } 492 493 func (c *closeOnce) close() { 494 c.err = c.File.Close() 495 } 496 497 // StdoutPipe returns a pipe that will be connected to the command's 498 // standard output when the command starts. 499 // 500 // Wait will close the pipe after seeing the command exit, so most callers 501 // need not close the pipe themselves; however, an implication is that 502 // it is incorrect to call Wait before all reads from the pipe have completed. 503 // For the same reason, it is incorrect to call Run when using StdoutPipe. 504 // See the example for idiomatic usage. 505 func (c *Cmd) StdoutPipe() (io.ReadCloser, error) { 506 if c.Stdout != nil { 507 return nil, errors.New("exec: Stdout already set") 508 } 509 if c.Process != nil { 510 return nil, errors.New("exec: StdoutPipe after process started") 511 } 512 pr, pw, err := os.Pipe() 513 if err != nil { 514 return nil, err 515 } 516 c.Stdout = pw 517 c.closeAfterStart = append(c.closeAfterStart, pw) 518 c.closeAfterWait = append(c.closeAfterWait, pr) 519 return pr, nil 520 } 521 522 // StderrPipe returns a pipe that will be connected to the command's 523 // standard error when the command starts. 524 // 525 // Wait will close the pipe after seeing the command exit, so most callers 526 // need not close the pipe themselves; however, an implication is that 527 // it is incorrect to call Wait before all reads from the pipe have completed. 528 // For the same reason, it is incorrect to use Run when using StderrPipe. 529 // See the StdoutPipe example for idiomatic usage. 530 func (c *Cmd) StderrPipe() (io.ReadCloser, error) { 531 if c.Stderr != nil { 532 return nil, errors.New("exec: Stderr already set") 533 } 534 if c.Process != nil { 535 return nil, errors.New("exec: StderrPipe after process started") 536 } 537 pr, pw, err := os.Pipe() 538 if err != nil { 539 return nil, err 540 } 541 c.Stderr = pw 542 c.closeAfterStart = append(c.closeAfterStart, pw) 543 c.closeAfterWait = append(c.closeAfterWait, pr) 544 return pr, nil 545 } 546 547 // prefixSuffixSaver is an io.Writer which retains the first N bytes 548 // and the last N bytes written to it. The Bytes() methods reconstructs 549 // it with a pretty error message. 550 type prefixSuffixSaver struct { 551 N int // max size of prefix or suffix 552 prefix []byte 553 suffix []byte // ring buffer once len(suffix) == N 554 suffixOff int // offset to write into suffix 555 skipped int64 556 557 // TODO(bradfitz): we could keep one large []byte and use part of it for 558 // the prefix, reserve space for the '... Omitting N bytes ...' message, 559 // then the ring buffer suffix, and just rearrange the ring buffer 560 // suffix when Bytes() is called, but it doesn't seem worth it for 561 // now just for error messages. It's only ~64KB anyway. 562 } 563 564 func (w *prefixSuffixSaver) Write(p []byte) (n int, err error) { 565 lenp := len(p) 566 p = w.fill(&w.prefix, p) 567 568 // Only keep the last w.N bytes of suffix data. 569 if overage := len(p) - w.N; overage > 0 { 570 p = p[overage:] 571 w.skipped += int64(overage) 572 } 573 p = w.fill(&w.suffix, p) 574 575 // w.suffix is full now if p is non-empty. Overwrite it in a circle. 576 for len(p) > 0 { // 0, 1, or 2 iterations. 577 n := copy(w.suffix[w.suffixOff:], p) 578 p = p[n:] 579 w.skipped += int64(n) 580 w.suffixOff += n 581 if w.suffixOff == w.N { 582 w.suffixOff = 0 583 } 584 } 585 return lenp, nil 586 } 587 588 // fill appends up to len(p) bytes of p to *dst, such that *dst does not 589 // grow larger than w.N. It returns the un-appended suffix of p. 590 func (w *prefixSuffixSaver) fill(dst *[]byte, p []byte) (pRemain []byte) { 591 if remain := w.N - len(*dst); remain > 0 { 592 add := minInt(len(p), remain) 593 *dst = append(*dst, p[:add]...) 594 p = p[add:] 595 } 596 return p 597 } 598 599 func (w *prefixSuffixSaver) Bytes() []byte { 600 if w.suffix == nil { 601 return w.prefix 602 } 603 if w.skipped == 0 { 604 return append(w.prefix, w.suffix...) 605 } 606 var buf bytes.Buffer 607 buf.Grow(len(w.prefix) + len(w.suffix) + 50) 608 buf.Write(w.prefix) 609 buf.WriteString("\n... omitting ") 610 buf.WriteString(strconv.FormatInt(w.skipped, 10)) 611 buf.WriteString(" bytes ...\n") 612 buf.Write(w.suffix[w.suffixOff:]) 613 buf.Write(w.suffix[:w.suffixOff]) 614 return buf.Bytes() 615 } 616 617 func minInt(a, b int) int { 618 if a < b { 619 return a 620 } 621 return b 622 }