Commit 5eae3b21 authored by Russ Cox's avatar Russ Cox

lib misc

	* 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
parent 3d0e4741
......@@ -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;
}
......@@ -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()};
......
......@@ -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);
}
......@@ -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
}
......@@ -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
......
......@@ -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
......
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