// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The exec package runs external commands.
package exec

import (
	"os";
	"strings";
)

// Arguments to Run.
const (
	DevNull = iota;
	PassThrough;
	Pipe;
	MergeWithStdout;
)

// A Cmd represents a running command.
// Stdin, Stdout, and Stderr are Files representing pipes
// connected to the running command's standard input, output, and error,
// or else nil, depending on the arguments to Run.
// Pid is the running command's operating system process ID.
type Cmd struct {
	Stdin *os.File;
	Stdout *os.File;
	Stderr *os.File;
	Pid int;
}

// Given mode (DevNull, etc), return file for child
// and file to record in Cmd structure.
func modeToFiles(mode, fd int) (*os.File, *os.File, *os.Error) {
	switch mode {
	case DevNull:
		rw := os.O_WRONLY;
		if fd == 0 {
			rw = os.O_RDONLY;
		}
		f, err := os.Open("/dev/null", rw, 0);
		return f, nil, err;
	case PassThrough:
		switch fd {
		case 0:
			return os.Stdin, nil, nil;
		case 1:
			return os.Stdout, nil, nil;
		case 2:
			return os.Stderr, nil, nil;
		}
	case Pipe:
		r, w, err := os.Pipe();
		if err != nil {
			return nil, nil, err;
		}
		if fd == 0 {
			return r, w, nil;
		}
		return w, r, nil;
	}
	return nil, nil, os.EINVAL;
}

// Run starts the binary prog running with
// arguments argv and environment envv.
// It returns a pointer to a new Cmd representing
// the command or an error.
//
// The parameters stdin, stdout, and stderr
// specify how to handle standard input, output, and error.
// The choices are DevNull (connect to /dev/null),
// PassThrough (connect to the current process's standard stream),
// Pipe (connect to an operating system pipe), and
// MergeWithStdout (only for standard error; use the same
// file descriptor as was used for standard output).
// If a parameter is Pipe, then the corresponding field (Stdin, Stdout, Stderr)
// of the returned Cmd is the other end of the pipe.
// Otherwise the field in Cmd is nil.
func Run(argv0 string, argv, envv []string, stdin, stdout, stderr int) (p *Cmd, err *os.Error)
{
	p = new(Cmd);
	var fd [3]*os.File;

	if fd[0], p.Stdin, err = modeToFiles(stdin, 0); err != nil {
		goto Error;
	}
	if fd[1], p.Stdout, err = modeToFiles(stdout, 1); err != nil {
		goto Error;
	}
	if stderr == MergeWithStdout {
		p.Stderr = p.Stdout;
	} else if fd[2], p.Stderr, err = modeToFiles(stderr, 2); err != nil {
		goto Error;
	}

	// Run command.
	p.Pid, err = os.ForkExec(argv0, argv, envv, fd);
	if err != nil {
		goto Error;
	}
	if fd[0] != os.Stdin {
		fd[0].Close();
	}
	if fd[1] != os.Stdout {
		fd[1].Close();
	}
	if fd[2] != os.Stderr && fd[2] != fd[1] {
		fd[2].Close();
	}
	return p, nil;

Error:
	if fd[0] != os.Stdin && fd[0] != nil {
		fd[0].Close();
	}
	if fd[1] != os.Stdout && fd[1] != nil {
		fd[1].Close();
	}
	if fd[2] != os.Stderr && fd[2] != nil && fd[2] != fd[1] {
		fd[2].Close();
	}
	if p.Stdin != nil {
		p.Stdin.Close();
	}
	if p.Stdout != nil {
		p.Stdout.Close();
	}
	if p.Stderr != nil {
		p.Stderr.Close();
	}
	return nil, err;
}

// Wait waits for the running command p,
// returning the Waitmsg returned by os.Wait and an error.
// The options are passed through to os.Wait.
// Setting options to 0 waits for p to exit;
// other options cause Wait to return for other
// process events; see package os for details.
func (p *Cmd) Wait(options uint64) (*os.Waitmsg, *os.Error) {
	if p.Pid < 0 {
		return nil, os.EINVAL;
	}
	w, err := os.Wait(p.Pid, options);
	if w != nil && (w.Exited() || w.Signaled()) {
		p.Pid = -1;
	}
	return w, err;
}

// Close waits for the running command p to exit,
// if it hasn't already, and then closes the non-nil file descriptors
// p.Stdin, p.Stdout, and p.Stderr.
func (p *Cmd) Close() *os.Error {
	if p.Pid >= 0 {
		// Loop on interrupt, but
		// ignore other errors -- maybe
		// caller has already waited for pid.
		w, err := p.Wait(0);
		for err == os.EINTR {
			w, err = p.Wait(0);
		}
	}

	// Close the FDs that are still open.
	var err *os.Error;
	if p.Stdin != nil && p.Stdin.Fd() >= 0 {
		if err1 := p.Stdin.Close(); err1 != nil {
			err = err1;
		}
	}
	if p.Stdout != nil && p.Stdout.Fd() >= 0 {
		if err1 := p.Stdout.Close(); err1 != nil && err != nil {
			err = err1;
		}
	}
	if p.Stderr != nil && p.Stderr != p.Stdout && p.Stderr.Fd() >= 0 {
		if err1 := p.Stderr.Close(); err1 != nil && err != nil {
			err = err1;
		}
	}
	return err;
}

func canExec(file string) bool{
	d, err := os.Stat(file);
	if err != nil {
		return false;
	}
	return d.IsRegular() && d.Permission() & 0111 != 0;
}

// LookPath searches for an executable binary named file
// in the directories named by the PATH environment variable.
// If file contains a slash, it is tried directly and the PATH is not consulted.
//
// TODO(rsc): Does LookPath belong in os instead?
func LookPath(file string) (string, *os.Error) {
	// NOTE(rsc): I wish we could use the Plan 9 behavior here
	// (only bypass the path if file begins with / or ./ or ../)
	// but that would not match all the Unix shells.

	if strings.Index(file, "/") >= 0 {
		if canExec(file) {
			return file, nil;
		}
		return "", os.ENOENT;
	}
	pathenv, err := os.Getenv("PATH");
	if err != nil {
		// Unix shell semantics: no $PATH means assume PATH=""
		// (equivalent to PATH=".").
		pathenv = "";
	}
	for i, dir := range strings.Split(pathenv, ":") {
		if dir == "" {
			// Unix shell semantics: path element "" means "."
			dir = ".";
		}
		if canExec(dir+"/"+file) {
			return dir+"/"+file, nil;
		}
	}
	return "", os.ENOENT;
}

