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