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