]> Cypherpunks repositories - gostls13.git/commitdiff
lib misc
authorRuss Cox <rsc@golang.org>
Mon, 13 Apr 2009 23:50:42 +0000 (16:50 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 13 Apr 2009 23:50:42 +0000 (16:50 -0700)
* exec.LookPath
* flag.Args
* os.Remove
* strings.HasPrefix
* strings.HasSuffix
* syscall.Rmdir

TBR=r
DELTA=100  (100 added, 0 deleted, 0 changed)
OCL=27373
CL=27392

src/lib/exec.go
src/lib/flag.go
src/lib/os/file.go
src/lib/strings.go
src/lib/syscall/file_darwin.go
src/lib/syscall/file_linux.go

index c832c17ffc82ce9545cac7f5dbc90d19a4856f60..effb46fa450f1fb05b7c961bdbcb39be913de3d5 100644 (file)
@@ -7,6 +7,7 @@ package exec
 
 import (
        "os";
+       "strings";
 )
 
 // Arguments to Run.
@@ -183,3 +184,45 @@ func (p *Cmd) Close() *os.Error {
        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;
+}
+
index f8e31ca6817290732dddd7a1b6df8af607501829..d8830c9dc441e43ca4e22ffe02972a0194e753e2 100644 (file)
@@ -290,6 +290,11 @@ func NArg() int {
        return len(sys.Args) - flags.first_arg
 }
 
+// Args returns the non-flag command-line arguments.
+func Args() []string {
+       return sys.Args[flags.first_arg:len(sys.Args)];
+}
+
 func add(name string, value FlagValue, usage string) {
        // Remember the default value as a string; it won't change.
        f := &Flag{name, usage, value, value.String()};
index 48daf0bce474b8548d40b17c6306ae0245d28d7d..80f43bb5939a9e534cbe23cf6e239efc9f6b2b8d 100644 (file)
@@ -267,3 +267,33 @@ func Chdir(dir string) *os.Error {
        return ErrnoToError(e);
 }
 
+// Remove removes the named file or directory.
+func Remove(name string) *os.Error {
+       // System call interface forces us to know
+       // whether name is a file or directory.
+       // Try both: it is cheaper on average than
+       // doing a Stat plus the right one.
+       r, e := syscall.Unlink(name);
+       if e == 0 {
+               return nil;
+       }
+       r1, e1 := syscall.Rmdir(name);
+       if e1 == 0 {
+               return nil;
+       }
+
+       // Both failed: figure out which error to return.
+       // OS X and Linux differ on whether unlink(dir)
+       // returns EISDIR, so can't use that.  However,
+       // both agree that rmdir(file) returns ENOTDIR,
+       // so we can use that to decide which error is real.
+       // Rmdir might return ENOTDIR if given a bad
+       // file path, like /etc/passwd/foo, but in that case,
+       // both errors will be ENOTDIR, so it's okay to
+       // use the error from unlink.
+       if e1 != syscall.ENOTDIR {
+               e = e1;
+       }
+       return ErrnoToError(e1);
+}
+
index 06a923427abf9ec89559f74baf5a94a2f4d8eb72..5ce4a8dae37047ed2c5dca142d1543c977902a87 100644 (file)
@@ -107,3 +107,13 @@ func Join(a []string, sep string) string {
        }
        return string(b)
 }
+
+// HasPrefix tests whether the string s begins with prefix.
+func HasPrefix(s, prefix string) bool {
+       return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
+}
+
+// HasSuffix tests whether the string s ends with suffix.
+func HasSuffix(s, suffix string) bool {
+       return len(s) >= len(suffix) && s[len(s)-len(suffix):len(s)] == suffix
+}
index b0777b5df4aeda70d58e3d4b3be23f6623fdd690..01005d207bde3a1b60e87bead1e96739660b758d 100644 (file)
@@ -78,6 +78,12 @@ func Unlink(name string) (ret int64, errno int64) {
        return r1, err;
 }
 
+func Rmdir(name string) (ret int64, errno int64) {
+       namebuf := StringBytePtr(name);
+       r1, r2, err := Syscall(SYS_RMDIR, int64(uintptr(unsafe.Pointer(namebuf))), 0, 0);
+       return r1, err;
+}
+
 func Fcntl(fd, cmd, arg int64) (ret int64, errno int64) {
        r1, r2, err := Syscall(SYS_FCNTL, fd, cmd, arg);
        return r1, err
index 9bf4408846d5e64c32710279e03f82e012301fa6..80800b6158dda888b8e895854ec0b5365f3beea7 100644 (file)
@@ -79,6 +79,12 @@ func Unlink(name string) (ret int64, errno int64) {
        return r1, err;
 }
 
+func Rmdir(name string) (ret int64, errno int64) {
+       namebuf := StringBytePtr(name);
+       r1, r2, err := Syscall(SYS_RMDIR, int64(uintptr(unsafe.Pointer(namebuf))), 0, 0);
+       return r1, err;
+}
+
 func Fcntl(fd, cmd, arg int64) (ret int64, errno int64) {
        r1, r2, err := Syscall(SYS_FCNTL, fd, cmd, arg);
        return r1, err