...

Source file src/os/exec/exec.go

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

View as plain text