Commit 8a7eb778 authored by Russ Cox's avatar Russ Cox

misc doc

R=r
DELTA=50  (28 added, 0 deleted, 22 changed)
OCL=25763
CL=25770
parent 5b814d02
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// The exec package runs external commands.
package exec package exec
import ( import (
...@@ -9,13 +10,19 @@ import ( ...@@ -9,13 +10,19 @@ import (
"syscall"; "syscall";
) )
// Arguments to Run.
const ( const (
DevNull = iota; DevNull = iota;
Passthru; PassThrough;
Pipe; Pipe;
MergeWithStdout; MergeWithStdout;
) )
// A Cmd represents a running command.
// Stdin, Stdout, and Stderr are file descriptors to 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 { type Cmd struct {
Stdin *os.FD; Stdin *os.FD;
Stdout *os.FD; Stdout *os.FD;
...@@ -34,7 +41,7 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) { ...@@ -34,7 +41,7 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) {
} }
f, err := os.Open("/dev/null", rw, 0); f, err := os.Open("/dev/null", rw, 0);
return f, nil, err; return f, nil, err;
case Passthru: case PassThrough:
switch fd { switch fd {
case 0: case 0:
return os.Stdin, nil, nil; return os.Stdin, nil, nil;
...@@ -56,12 +63,22 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) { ...@@ -56,12 +63,22 @@ func modeToFDs(mode, fd int) (*os.FD, *os.FD, *os.Error) {
return nil, nil, os.EINVAL; return nil, nil, os.EINVAL;
} }
// Start command running with pipes possibly // Run starts the binary prog running with
// connected to stdin, stdout, stderr. // arguments argv and environment envv.
// TODO(rsc): Should the stdin,stdout,stderr args // It returns a pointer to a new Cmd representing
// be [3]int instead? // the command or an error.
func OpenCmd(argv0 string, argv, envv []string, stdin, stdout, stderr int) //
(p *Cmd, err *os.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); p = new(Cmd);
var fd [3]*os.FD; var fd [3]*os.FD;
...@@ -116,6 +133,12 @@ Error: ...@@ -116,6 +133,12 @@ Error:
return nil, err; 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) { func (p *Cmd) Wait(options uint64) (*os.Waitmsg, *os.Error) {
if p.Pid < 0 { if p.Pid < 0 {
return nil, os.EINVAL; return nil, os.EINVAL;
...@@ -127,6 +150,9 @@ func (p *Cmd) Wait(options uint64) (*os.Waitmsg, *os.Error) { ...@@ -127,6 +150,9 @@ func (p *Cmd) Wait(options uint64) (*os.Waitmsg, *os.Error) {
return w, err; 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 { func (p *Cmd) Close() *os.Error {
if p.Pid >= 0 { if p.Pid >= 0 {
// Loop on interrupt, but // Loop on interrupt, but
......
...@@ -10,8 +10,8 @@ import ( ...@@ -10,8 +10,8 @@ import (
"testing"; "testing";
) )
func TestOpenCmdCat(t *testing.T) { func TestRunCat(t *testing.T) {
cmd, err := exec.OpenCmd("/bin/cat", []string{"cat"}, nil, cmd, err := exec.Run("/bin/cat", []string{"cat"}, nil,
exec.Pipe, exec.Pipe, exec.DevNull); exec.Pipe, exec.Pipe, exec.DevNull);
if err != nil { if err != nil {
t.Fatalf("opencmd /bin/cat: %v", err); t.Fatalf("opencmd /bin/cat: %v", err);
...@@ -31,8 +31,8 @@ func TestOpenCmdCat(t *testing.T) { ...@@ -31,8 +31,8 @@ func TestOpenCmdCat(t *testing.T) {
} }
} }
func TestOpenCmdEcho(t *testing.T) { func TestRunEcho(t *testing.T) {
cmd, err := OpenCmd("/bin/echo", []string{"echo", "hello", "world"}, nil, cmd, err := Run("/bin/echo", []string{"echo", "hello", "world"}, nil,
exec.DevNull, exec.Pipe, exec.DevNull); exec.DevNull, exec.Pipe, exec.DevNull);
if err != nil { if err != nil {
t.Fatalf("opencmd /bin/echo: %v", err); t.Fatalf("opencmd /bin/echo: %v", err);
......
...@@ -31,16 +31,18 @@ import ( ...@@ -31,16 +31,18 @@ import (
var debug = false; var debug = false;
// Error codes returned by failures to parse an expression. // Error codes returned by failures to parse an expression.
var ErrInternal = os.NewError("internal error"); var (
var ErrUnmatchedLpar = os.NewError("unmatched '('"); ErrInternal = os.NewError("internal error");
var ErrUnmatchedRpar = os.NewError("unmatched ')'"); ErrUnmatchedLpar = os.NewError("unmatched '('");
var ErrUnmatchedLbkt = os.NewError("unmatched '['"); ErrUnmatchedRpar = os.NewError("unmatched ')'");
var ErrUnmatchedRbkt = os.NewError("unmatched ']'"); ErrUnmatchedLbkt = os.NewError("unmatched '['");
var ErrBadRange = os.NewError("bad range in character class"); ErrUnmatchedRbkt = os.NewError("unmatched ']'");
var ErrExtraneousBackslash = os.NewError("extraneous backslash"); ErrBadRange = os.NewError("bad range in character class");
var ErrBadClosure = os.NewError("repeated closure (**, ++, etc.)"); ErrExtraneousBackslash = os.NewError("extraneous backslash");
var ErrBareClosure = os.NewError("closure applies to nothing"); ErrBadClosure = os.NewError("repeated closure (**, ++, etc.)");
var ErrBadBackslash = os.NewError("illegal backslash escape"); ErrBareClosure = os.NewError("closure applies to nothing");
ErrBadBackslash = os.NewError("illegal backslash escape");
)
// An instruction executed by the NFA // An instruction executed by the NFA
type instr interface { type instr interface {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment