]> Cypherpunks repositories - gostls13.git/commitdiff
exec: add support for Plan 9
authorAnthony Martin <ality@pbrane.org>
Mon, 20 Jun 2011 03:34:10 +0000 (13:34 +1000)
committerRob Pike <r@golang.org>
Mon, 20 Jun 2011 03:34:10 +0000 (13:34 +1000)
R=paulzhol, mirtchovski, fshahriar, alex.brainman, r
CC=golang-dev
https://golang.org/cl/4386041

src/pkg/exec/Makefile
src/pkg/exec/lp_plan9.go [new file with mode: 0644]
src/pkg/os/error_plan9.go
src/pkg/os/exec_plan9.go
src/pkg/syscall/syscall_plan9.go

index 262ecac85e2bfac192379fcdd9cab1c8d9d7d0a9..90bb74b41c91bdcffeb46b0d9fbf6fd0a594fe0d 100644 (file)
@@ -20,6 +20,9 @@ GOFILES_linux=\
 GOFILES_windows=\
        lp_windows.go\
 
+GOFILES_plan9=\
+       lp_plan9.go\
+
 GOFILES+=$(GOFILES_$(GOOS))
 
 include ../../Make.pkg
diff --git a/src/pkg/exec/lp_plan9.go b/src/pkg/exec/lp_plan9.go
new file mode 100644 (file)
index 0000000..d0912f9
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright 2011 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.
+
+package exec
+
+import (
+       "os"
+       "strings"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+var ErrNotFound = os.ErrorString("executable file not found in $path")
+
+func findExecutable(file string) os.Error {
+       d, err := os.Stat(file)
+       if err != nil {
+               return err
+       }
+       if d.IsRegular() && d.Permission()&0111 != 0 {
+               return nil
+       }
+       return os.EPERM
+}
+
+// LookPath searches for an executable binary named file
+// in the directories named by the path environment variable.
+// If file begins with "/", "#", "./", or "../", it is tried
+// directly and the path is not consulted.
+func LookPath(file string) (string, os.Error) {
+       // skip the path lookup for these prefixes
+       skip := []string{"/", "#", "./", "../"}
+
+       for _, p := range skip {
+               if strings.HasPrefix(file, p) {
+                       err := findExecutable(file)
+                       if err == nil {
+                               return file, nil
+                       }
+                       return "", &Error{file, err}
+               }
+       }
+
+       path := os.Getenv("path")
+       for _, dir := range strings.Split(path, "\000", -1) {
+               if err := findExecutable(dir + "/" + file); err == nil {
+                       return dir + "/" + file, nil
+               }
+       }
+       return "", &Error{file, ErrNotFound}
+}
index 3374775b8e7d0c4f99bdc4938d4b69e0d3ddb240..cacfc150c43fadaa8283373ba0f4d33e0173c62c 100644 (file)
@@ -45,6 +45,7 @@ var (
        EEXIST  = Eexist
        EIO     = Eio
        EACCES  = Eperm
+       EPERM   = Eperm
        EISDIR  = syscall.EISDIR
 
        ENAMETOOLONG = NewError("file name too long")
index 29997b48a6b34281e7829c9ffca00661ce1f1d74..0598adc0fa1cc3e46f3e612281de5b6dea60285b 100644 (file)
@@ -63,7 +63,9 @@ func Exec(name string, argv []string, envv []string) Error {
 }
 
 // Waitmsg stores the information about an exited process as reported by Wait.
-type Waitmsg syscall.Waitmsg
+type Waitmsg struct {
+       syscall.Waitmsg
+}
 
 // Wait waits for the Process to exit or stop, and then returns a
 // Waitmsg describing its status and an Error, if any. The options
@@ -87,7 +89,7 @@ func (p *Process) Wait(options int) (w *Waitmsg, err Error) {
                }
        }
 
-       return (*Waitmsg)(&waitmsg), nil
+       return &Waitmsg{waitmsg}, nil
 }
 
 // Wait waits for process pid to exit or stop, and then returns a
index 831cbddb2466049dd8886f06c0352fe4cb5b85f9..4104050fd30537f4064fb3b1ae74fe550c1f749a 100644 (file)
@@ -35,7 +35,7 @@ var (
        Stdout = 1
        Stderr = 2
 
-       EISDIR Error = NewError("file is a directory")
+       EISDIR = NewError("file is a directory")
 )
 
 func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
@@ -200,6 +200,17 @@ type Waitmsg struct {
        Msg  string
 }
 
+func (w Waitmsg) Exited() bool   { return true }
+func (w Waitmsg) Signaled() bool { return false }
+
+func (w Waitmsg) ExitStatus() int {
+       if len(w.Msg) == 0 {
+               // a normal exit returns no message
+               return 0
+       }
+       return 1
+}
+
 //sys  await(s []byte) (n int, err Error)
 func Await(w *Waitmsg) (err Error) {
        var buf [512]byte
@@ -230,7 +241,7 @@ func Await(w *Waitmsg) (err Error) {
        w.Time[0] = uint32(atoi(f[1]))
        w.Time[1] = uint32(atoi(f[2]))
        w.Time[2] = uint32(atoi(f[3]))
-       w.Msg = string(f[4])
+       w.Msg = cstring(f[4])
        return
 }