mirror of
https://github.com/golang/go
synced 2024-11-20 09:34:52 -07:00
os: MkdirAll, RemoveAll, Chmod, Chown, Truncate, Getgroups.
Getuid, etc drop their errors -- they cannot error R=r DELTA=605 (547 added, 12 deleted, 46 changed) OCL=28919 CL=28929
This commit is contained in:
parent
a2ea790b1b
commit
66f5e89082
@ -3,7 +3,7 @@
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# DO NOT EDIT. Automatically generated by gobuild.
|
||||
# gobuild -m dir_${GOARCH}_${GOOS}.go env.go error.go file.go proc_${GOOS}.go stat_${GOARCH}_${GOOS}.go time.go types.go exec.go user.go >Makefile
|
||||
# gobuild -m dir_${GOARCH}_${GOOS}.go env.go error.go file.go path.go proc_${GOOS}.go stat_${GOARCH}_${GOOS}.go time.go types.go exec.go user.go >Makefile
|
||||
|
||||
D=
|
||||
|
||||
@ -56,6 +56,7 @@ O3=\
|
||||
O4=\
|
||||
dir_$(GOARCH)_$(GOOS).$O\
|
||||
exec.$O\
|
||||
path.$O\
|
||||
|
||||
|
||||
phases: a1 a2 a3 a4
|
||||
@ -74,7 +75,7 @@ a3: $(O3)
|
||||
rm -f $(O3)
|
||||
|
||||
a4: $(O4)
|
||||
$(AR) grc _obj$D/os.a dir_$(GOARCH)_$(GOOS).$O exec.$O
|
||||
$(AR) grc _obj$D/os.a dir_$(GOARCH)_$(GOOS).$O exec.$O path.$O
|
||||
rm -f $(O4)
|
||||
|
||||
|
||||
|
@ -315,23 +315,23 @@ func Remove(name string) Error {
|
||||
}
|
||||
|
||||
// Link creates a hard link.
|
||||
func Link(oldpath, newpath string) Error {
|
||||
r, e := syscall.Link(oldpath, newpath);
|
||||
func Link(oldname, newname string) Error {
|
||||
r, e := syscall.Link(oldname, newname);
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Symlink creates a symbolic link.
|
||||
func Symlink(oldpath, newpath string) Error {
|
||||
r, e := syscall.Symlink(oldpath, newpath);
|
||||
func Symlink(oldname, newname string) Error {
|
||||
r, e := syscall.Symlink(oldname, newname);
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Readlink reads the contents of a symbolic link: the destination of
|
||||
// the link. It returns the contents and an Error, if any.
|
||||
func Readlink(path string) (string, Error) {
|
||||
func Readlink(name string) (string, Error) {
|
||||
for len := int64(128); ; len *= 2 {
|
||||
b := make([]byte, len);
|
||||
r, e := syscall.Readlink(path, &b[0], len);
|
||||
r, e := syscall.Readlink(name, &b[0], len);
|
||||
if r == -1 {
|
||||
return "", ErrnoToError(e);
|
||||
} else if r < len {
|
||||
@ -341,3 +341,51 @@ func Readlink(path string) (string, Error) {
|
||||
// Silence 6g.
|
||||
return "", nil;
|
||||
}
|
||||
|
||||
// Chmod changes the mode of the named file to mode.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link's target.
|
||||
func Chmod(name string, mode int) Error {
|
||||
r, e := syscall.Chmod(name, int64(mode));
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Chmod changes the mode of the file to mode.
|
||||
func (f *File) Chmod(mode int) Error {
|
||||
r, e := syscall.Fchmod(f.fd, int64(mode));
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Chown changes the numeric uid and gid of the named file.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link's target.
|
||||
func Chown(name string, uid, gid int) Error {
|
||||
r, e := syscall.Chown(name, int64(uid), int64(gid));
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Lchown changes the numeric uid and gid of the named file.
|
||||
// If the file is a symbolic link, it changes the uid and gid of the link itself.
|
||||
func Lchown(name string, uid, gid int) Error {
|
||||
r, e := syscall.Lchown(name, int64(uid), int64(gid));
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Chown changes the numeric uid and gid of the named file.
|
||||
func (f *File) Chown(uid, gid int) Error {
|
||||
r, e := syscall.Fchown(f.fd, int64(uid), int64(gid));
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Truncate changes the size of the named file.
|
||||
// If the file is a symbolic link, it changes the size of the link's target.
|
||||
func Truncate(name string, size int64) Error {
|
||||
r, e := syscall.Truncate(name, size);
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Truncate changes the size of the file.
|
||||
// It does not change the I/O offset.
|
||||
func (f *File) Truncate(size int64) Error {
|
||||
r, e := syscall.Ftruncate(f.fd, size);
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
|
@ -331,3 +331,126 @@ func TestForkExec(t *testing.T) {
|
||||
}
|
||||
Wait(pid, 0);
|
||||
}
|
||||
|
||||
func checkMode(t *testing.T, path string, mode uint32) {
|
||||
dir, err := Stat(path);
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err);
|
||||
}
|
||||
if dir.Mode & 0777 != mode {
|
||||
t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode, 0777);
|
||||
}
|
||||
}
|
||||
|
||||
func TestChmod(t *testing.T) {
|
||||
MkdirAll("_obj", 0777);
|
||||
const Path = "_obj/_TestChmod_";
|
||||
fd, err := os.Open(Path, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err);
|
||||
}
|
||||
|
||||
if err = os.Chmod(Path, 0456); err != nil {
|
||||
t.Fatalf("chmod %s 0456: %s", Path, err);
|
||||
}
|
||||
checkMode(t, Path, 0456);
|
||||
|
||||
if err = fd.Chmod(0123); err != nil {
|
||||
t.Fatalf("fchmod %s 0123: %s", Path, err);
|
||||
}
|
||||
checkMode(t, Path, 0123);
|
||||
|
||||
fd.Close();
|
||||
Remove(Path);
|
||||
}
|
||||
|
||||
func checkUidGid(t *testing.T, path string, uid, gid int) {
|
||||
dir, err := Stat(path);
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for uid/gid %#o/%#o): %s", path, uid, gid, err);
|
||||
}
|
||||
if dir.Uid != uint32(uid) {
|
||||
t.Errorf("Stat %q: uid %#o want %#o", path, dir.Uid, uid);
|
||||
}
|
||||
if dir.Gid != uint32(gid) {
|
||||
t.Errorf("Stat %q: gid %#o want %#o", path, dir.Gid, uid);
|
||||
}
|
||||
}
|
||||
|
||||
func TestChown(t *testing.T) {
|
||||
// Use /tmp, not _obj, to make sure we're on a local file system,
|
||||
// so that the group ids returned by Getgroups will be allowed
|
||||
// on the file. If _obj is on NFS, the Getgroups groups are
|
||||
// basically useless.
|
||||
|
||||
const Path = "/tmp/_TestChown_";
|
||||
fd, err := os.Open(Path, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err);
|
||||
}
|
||||
dir, err := fd.Stat();
|
||||
if err != nil {
|
||||
t.Fatalf("fstat %s: %s", Path, err);
|
||||
}
|
||||
defer fd.Close();
|
||||
defer Remove(Path);
|
||||
|
||||
// Can't change uid unless root, but can try
|
||||
// changing the group id. First try our current group.
|
||||
gid := Getgid();
|
||||
if err = os.Chown(Path, -1, gid); err != nil {
|
||||
t.Fatalf("chown %s -1 %d: %s", Path, gid, err);
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), gid);
|
||||
|
||||
// Then try all the auxiliary groups.
|
||||
groups, err := Getgroups();
|
||||
if err != nil {
|
||||
t.Fatalf("getgroups: %s", err);
|
||||
}
|
||||
for i, g := range groups {
|
||||
if err = os.Chown(Path, -1, g); err != nil {
|
||||
t.Fatalf("chown %s -1 %d: %s", Path, g, err);
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), g);
|
||||
|
||||
// change back to gid to test fd.Chown
|
||||
if err = fd.Chown(-1, gid); err != nil {
|
||||
t.Fatalf("fchown %s -1 %d: %s", Path, gid, err);
|
||||
}
|
||||
checkUidGid(t, Path, int(dir.Uid), gid);
|
||||
}
|
||||
}
|
||||
|
||||
func checkSize(t *testing.T, path string, size uint64) {
|
||||
dir, err := Stat(path);
|
||||
if err != nil {
|
||||
t.Fatalf("Stat %q (looking for size %d): %s", path, size, err);
|
||||
}
|
||||
if dir.Size != size {
|
||||
t.Errorf("Stat %q: size %d want %d", path, dir.Size, size);
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncate(t *testing.T) {
|
||||
MkdirAll("_obj", 0777);
|
||||
const Path = "_obj/_TestTruncate_";
|
||||
fd, err := os.Open(Path, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %s: %s", Path, err);
|
||||
}
|
||||
|
||||
checkSize(t, Path, 0);
|
||||
fd.Write(io.StringBytes("hello, world\n"));
|
||||
checkSize(t, Path, 13);
|
||||
fd.Truncate(10);
|
||||
checkSize(t, Path, 10);
|
||||
fd.Truncate(1024);
|
||||
checkSize(t, Path, 1024);
|
||||
fd.Truncate(0);
|
||||
checkSize(t, Path, 0);
|
||||
fd.Write(io.StringBytes("surprise!"));
|
||||
checkSize(t, Path, 13 + 9); // wrote at offset past where hello, world was.
|
||||
fd.Close();
|
||||
Remove(Path);
|
||||
}
|
||||
|
121
src/lib/os/path.go
Normal file
121
src/lib/os/path.go
Normal file
@ -0,0 +1,121 @@
|
||||
// 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.
|
||||
|
||||
package os
|
||||
|
||||
import "os"
|
||||
|
||||
// PathError reports an error and the file path where it occurred.
|
||||
type PathError struct {
|
||||
Path string;
|
||||
Error Error;
|
||||
}
|
||||
|
||||
func (p *PathError) String() string {
|
||||
return p.Path + ": " + p.Error.String();
|
||||
}
|
||||
|
||||
// MkdirAll creates a directory named path,
|
||||
// along with any necessary parents, and returns nil,
|
||||
// or else returns an error.
|
||||
// The permission bits perm are used for all
|
||||
// directories that MkdirAll creates.
|
||||
// If path is already a directory, MkdirAll does nothing
|
||||
// and returns nil.
|
||||
func MkdirAll(path string, perm int) Error {
|
||||
// If path exists, stop with success or error.
|
||||
dir, err := os.Lstat(path);
|
||||
if err == nil {
|
||||
if dir.IsDirectory() {
|
||||
return nil;
|
||||
}
|
||||
return &PathError{path, ENOTDIR};
|
||||
}
|
||||
|
||||
// Doesn't already exist; make sure parent does.
|
||||
i := len(path);
|
||||
for i > 0 && path[i-1] == '/' { // Skip trailing slashes.
|
||||
i--;
|
||||
}
|
||||
|
||||
j := i;
|
||||
for j > 0 && path[j-1] != '/' { // Scan backward over element.
|
||||
j--;
|
||||
}
|
||||
|
||||
if j > 0 {
|
||||
// Create parent
|
||||
err = MkdirAll(path[0:j-1], perm);
|
||||
if err != nil {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Now parent exists, try to create.
|
||||
err = Mkdir(path, perm);
|
||||
if err != nil {
|
||||
// Handle arguments like "foo/." by
|
||||
// double-checking that directory doesn't exist.
|
||||
dir, err1 := os.Lstat(path);
|
||||
if err1 == nil && dir.IsDirectory() {
|
||||
return nil;
|
||||
}
|
||||
return &PathError{path, err};
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// RemoveAll removes path and any children it contains.
|
||||
// It removes everything it can but returns the first error
|
||||
// it encounters.
|
||||
func RemoveAll(path string) Error {
|
||||
// Simple case: if Remove works, we're done.
|
||||
err := Remove(path);
|
||||
if err == nil {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// Otherwise, is this a directory we need to recurse into?
|
||||
dir, err1 := os.Lstat(path);
|
||||
if err1 != nil {
|
||||
return &PathError{path, err1};
|
||||
}
|
||||
if !dir.IsDirectory() {
|
||||
// Not a directory; return the error from Remove.
|
||||
return &PathError{path, err};
|
||||
}
|
||||
|
||||
// Directory.
|
||||
fd, err := Open(path, os.O_RDONLY, 0);
|
||||
if err != nil {
|
||||
return &PathError{path, err};
|
||||
}
|
||||
defer fd.Close();
|
||||
|
||||
// Remove contents & return first error.
|
||||
err = nil;
|
||||
for {
|
||||
names, err1 := fd.Readdirnames(100);
|
||||
for i, name := range names {
|
||||
err1 := RemoveAll(path + "/" + name);
|
||||
if err1 != nil && err == nil {
|
||||
err = err1;
|
||||
}
|
||||
}
|
||||
// If Readdirnames returned an error, use it.
|
||||
if err1 != nil && err == nil {
|
||||
err = &PathError{path, err1};
|
||||
}
|
||||
if len(names) == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove directory.
|
||||
err1 = Remove(path);
|
||||
if err1 != nil && err == nil {
|
||||
err = &PathError{path, err1};
|
||||
}
|
||||
return err;
|
||||
}
|
152
src/lib/os/path_test.go
Normal file
152
src/lib/os/path_test.go
Normal file
@ -0,0 +1,152 @@
|
||||
// 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.
|
||||
|
||||
package os
|
||||
|
||||
import (
|
||||
"os";
|
||||
"testing";
|
||||
)
|
||||
|
||||
func TestMkdirAll(t *testing.T) {
|
||||
// Create new dir, in _obj so it will get
|
||||
// cleaned up by make if not by us.
|
||||
path := "_obj/_TestMkdirAll_/dir/./dir2";
|
||||
err := MkdirAll(path, 0777);
|
||||
if err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", path, err);
|
||||
}
|
||||
|
||||
// Already exists, should succeed.
|
||||
err = MkdirAll(path, 0777);
|
||||
if err != nil {
|
||||
t.Fatalf("MkdirAll %q (second time): %s", path, err);
|
||||
}
|
||||
|
||||
// Make file.
|
||||
fpath := path + "/file";
|
||||
fd, err := os.Open(fpath, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err);
|
||||
}
|
||||
|
||||
// Can't make directory named after file.
|
||||
err = MkdirAll(fpath, 0777);
|
||||
if err == nil {
|
||||
t.Fatalf("MkdirAll %q: no error");
|
||||
}
|
||||
perr, ok := err.(*PathError);
|
||||
if !ok {
|
||||
t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err);
|
||||
}
|
||||
if perr.Path != fpath {
|
||||
t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, perr.Path, fpath);
|
||||
}
|
||||
|
||||
// Can't make subdirectory of file.
|
||||
ffpath := fpath + "/subdir";
|
||||
err = MkdirAll(ffpath, 0777);
|
||||
if err == nil {
|
||||
t.Fatalf("MkdirAll %q: no error");
|
||||
}
|
||||
perr, ok = err.(*PathError);
|
||||
if !ok {
|
||||
t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err);
|
||||
}
|
||||
if perr.Path != fpath {
|
||||
t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, perr.Path, fpath);
|
||||
}
|
||||
|
||||
RemoveAll("_obj/_TestMkdirAll_");
|
||||
}
|
||||
|
||||
func TestRemoveAll(t *testing.T) {
|
||||
// Work directory.
|
||||
path := "_obj/_TestRemoveAll_";
|
||||
fpath := path + "/file";
|
||||
dpath := path + "/dir";
|
||||
|
||||
// Make directory with 1 file and remove.
|
||||
if err := MkdirAll(path, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", path, err);
|
||||
}
|
||||
fd, err := os.Open(fpath, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err);
|
||||
}
|
||||
fd.Close();
|
||||
if err = RemoveAll(path); err != nil {
|
||||
t.Fatalf("RemoveAll %q (first): %s", path, err);
|
||||
}
|
||||
if dir, err := os.Lstat(path); err == nil {
|
||||
t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path);
|
||||
}
|
||||
|
||||
// Make directory with file and subdirectory and remove.
|
||||
if err = MkdirAll(dpath, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", dpath, err);
|
||||
}
|
||||
fd, err = os.Open(fpath, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err);
|
||||
}
|
||||
fd.Close();
|
||||
fd, err = os.Open(dpath+"/file", os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", fpath, err);
|
||||
}
|
||||
fd.Close();
|
||||
if err = RemoveAll(path); err != nil {
|
||||
t.Fatalf("RemoveAll %q (second): %s", path, err);
|
||||
}
|
||||
if dir, err := os.Lstat(path); err == nil {
|
||||
t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path);
|
||||
}
|
||||
|
||||
// Make directory with file and subdirectory and trigger error.
|
||||
if err = MkdirAll(dpath, 0777); err != nil {
|
||||
t.Fatalf("MkdirAll %q: %s", dpath, err);
|
||||
}
|
||||
|
||||
// TODO(rsc): toss tmp once bug152 is fixed
|
||||
tmp := []string{fpath, dpath+"/file1", path+"/zzz"};
|
||||
for i, s := range tmp {
|
||||
fd, err = os.Open(s, os.O_WRONLY | os.O_CREAT, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("create %q: %s", s, err);
|
||||
}
|
||||
fd.Close();
|
||||
}
|
||||
if err = os.Chmod(dpath, 0); err != nil {
|
||||
t.Fatalf("Chmod %q 0: %s", dpath, err);
|
||||
}
|
||||
if err = RemoveAll(path); err == nil {
|
||||
dir, err := Lstat(path);
|
||||
if err == nil {
|
||||
t.Errorf("Can lstat %q after supposed RemoveAll", path);
|
||||
}
|
||||
t.Fatalf("RemoveAll %q succeeded with chmod 0 subdirectory", path, err);
|
||||
}
|
||||
perr, ok := err.(*PathError);
|
||||
if !ok {
|
||||
t.Fatalf("RemoveAll %q returned %T not *PathError", path, err);
|
||||
}
|
||||
if perr.Path != dpath {
|
||||
t.Fatalf("RemoveAll %q failed at %q not %q", path, perr.Path, dpath);
|
||||
}
|
||||
if err = os.Chmod(dpath, 0777); err != nil {
|
||||
t.Fatalf("Chmod %q 0777: %s", dpath, err);
|
||||
}
|
||||
for i, s := range []string{fpath, path+"/zzz"} {
|
||||
if dir, err := os.Lstat(s); err == nil {
|
||||
t.Fatalf("Lstat %q succeeded after partial RemoveAll", s);
|
||||
}
|
||||
}
|
||||
if err = RemoveAll(path); err != nil {
|
||||
t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err);
|
||||
}
|
||||
if dir, err := os.Lstat(path); err == nil {
|
||||
t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path);
|
||||
}
|
||||
}
|
@ -9,41 +9,54 @@ package os
|
||||
import (
|
||||
"syscall";
|
||||
"os";
|
||||
"unsafe";
|
||||
)
|
||||
|
||||
// Getuid returns the numeric user id of the caller.
|
||||
func Getuid() (uid int, err Error) {
|
||||
u, _, e := syscall.Syscall(syscall.SYS_GETUID, 0, 0, 0);
|
||||
if e != 0 {
|
||||
return -1, ErrnoToError(e)
|
||||
}
|
||||
return int(u), nil
|
||||
func Getuid() int {
|
||||
u, r2, e := syscall.Syscall(syscall.SYS_GETUID, 0, 0, 0);
|
||||
return int(u);
|
||||
}
|
||||
|
||||
// Geteuid returns the numeric effective user id of the caller.
|
||||
func Geteuid() (uid int, err Error) {
|
||||
u, _, e := syscall.Syscall(syscall.SYS_GETEUID, 0, 0, 0);
|
||||
if e != 0 {
|
||||
return -1, ErrnoToError(e)
|
||||
}
|
||||
return int(u), nil
|
||||
func Geteuid() int {
|
||||
u, r2, e := syscall.Syscall(syscall.SYS_GETEUID, 0, 0, 0);
|
||||
return int(u);
|
||||
}
|
||||
|
||||
// Getgid returns the numeric group id of the caller.
|
||||
func Getgid() (uid int, err Error) {
|
||||
g, _, e := syscall.Syscall(syscall.SYS_GETGID, 0, 0, 0);
|
||||
if e != 0 {
|
||||
return -1, ErrnoToError(e)
|
||||
}
|
||||
return int(g), nil
|
||||
func Getgid() int {
|
||||
g, r2, e := syscall.Syscall(syscall.SYS_GETGID, 0, 0, 0);
|
||||
return int(g);
|
||||
}
|
||||
|
||||
// Getegid returns the numeric effective group id of the caller.
|
||||
func Getegid() (uid int, err Error) {
|
||||
g, _, e := syscall.Syscall(syscall.SYS_GETEGID, 0, 0, 0);
|
||||
if e != 0 {
|
||||
return -1, ErrnoToError(e)
|
||||
}
|
||||
return int(g), nil
|
||||
func Getegid() int {
|
||||
g, r2, e := syscall.Syscall(syscall.SYS_GETEGID, 0, 0, 0);
|
||||
return int(g);
|
||||
}
|
||||
|
||||
// Getgroups returns a list of the numeric ids of groups that the caller belongs to.
|
||||
func Getgroups() ([]int, os.Error) {
|
||||
// first call asks how many there are.
|
||||
r1, r2, err := syscall.Syscall(syscall.SYS_GETGROUPS, 0, 0, 0);
|
||||
if err != 0 {
|
||||
return nil, ErrnoToError(err);
|
||||
}
|
||||
|
||||
if r1 < 0 || r1 > 1024 { // the current max is 16; 1024 is a future-proof sanity check
|
||||
return nil, EINVAL;
|
||||
}
|
||||
a := make([]int, r1);
|
||||
if r1 > 0 {
|
||||
tmp := make([]uint32, r1);
|
||||
r1, r2, err = syscall.Syscall(syscall.SYS_GETGROUPS, r1, int64(uintptr(unsafe.Pointer(&tmp[0]))), 0);
|
||||
if err != 0 {
|
||||
return nil, ErrnoToError(err);
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
a[i] = int(tmp[i]);
|
||||
}
|
||||
}
|
||||
return a[0:r1], nil;
|
||||
}
|
||||
|
@ -13,39 +13,39 @@ import (
|
||||
|
||||
const nameBufsize = 512
|
||||
|
||||
func Open(name string, mode int64, perm int64) (ret int64, errno int64) {
|
||||
func Open(name string, mode int64, perm int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_OPEN, int64(uintptr(unsafe.Pointer(namebuf))), mode, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Creat(name string, perm int64) (ret int64, errno int64) {
|
||||
func Creat(name string, perm int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_OPEN, int64(uintptr(unsafe.Pointer(namebuf))), O_CREAT|O_WRONLY|O_TRUNC, perm);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Close(fd int64) (ret int64, errno int64) {
|
||||
func Close(fd int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_CLOSE, fd, 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Read(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
|
||||
func Read(fd int64, buf *byte, nbytes int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_READ, fd, int64(uintptr(unsafe.Pointer(buf))), nbytes);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Write(fd int64, buf *byte, nbytes int64) (ret int64, errno int64) {
|
||||
func Write(fd int64, buf *byte, nbytes int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_WRITE, fd, int64(uintptr(unsafe.Pointer(buf))), nbytes);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Seek(fd int64, offset int64, whence int64) (ret int64, errno int64) {
|
||||
func Seek(fd int64, offset int64, whence int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_LSEEK, fd, offset, whence);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Pipe(fds *[2]int64) (ret int64, errno int64) {
|
||||
func Pipe(fds *[2]int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_PIPE, 0, 0, 0);
|
||||
if r1 < 0 {
|
||||
return r1, err;
|
||||
@ -55,78 +55,117 @@ func Pipe(fds *[2]int64) (ret int64, errno int64) {
|
||||
return 0, 0;
|
||||
}
|
||||
|
||||
func Stat(name string, buf *Stat_t) (ret int64, errno int64) {
|
||||
func Stat(name string, buf *Stat_t) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_STAT64, int64(uintptr(unsafe.Pointer(namebuf))), int64(uintptr(unsafe.Pointer(buf))), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Lstat(name string, buf *Stat_t) (ret int64, errno int64) {
|
||||
func Lstat(name string, buf *Stat_t) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_LSTAT64, int64(uintptr(unsafe.Pointer(namebuf))), int64(uintptr(unsafe.Pointer(buf))), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Fstat(fd int64, buf *Stat_t) (ret int64, errno int64) {
|
||||
func Fstat(fd int64, buf *Stat_t) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FSTAT64, fd, int64(uintptr(unsafe.Pointer(buf))), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Unlink(name string) (ret int64, errno int64) {
|
||||
func Unlink(name string) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_UNLINK, int64(uintptr(unsafe.Pointer(namebuf))), 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Rmdir(name string) (ret int64, errno int64) {
|
||||
func Rmdir(name string) (ret, 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) {
|
||||
func Fcntl(fd, cmd, arg int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FCNTL, fd, cmd, arg);
|
||||
return r1, err
|
||||
}
|
||||
|
||||
func Mkdir(name string, perm int64) (ret int64, errno int64) {
|
||||
func Mkdir(name string, perm int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_MKDIR, int64(uintptr(unsafe.Pointer(namebuf))), perm, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Dup2(fd1, fd2 int64) (ret int64, errno int64) {
|
||||
func Dup2(fd1, fd2 int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_DUP2, fd1, fd2, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Getdirentries(fd int64, buf *byte, nbytes int64, basep *int64) (ret int64, errno int64) {
|
||||
func Getdirentries(fd int64, buf *byte, nbytes int64, basep *int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall6(SYS_GETDIRENTRIES64, fd, int64(uintptr(unsafe.Pointer(buf))), nbytes, int64(uintptr(unsafe.Pointer(basep))), 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Chdir(dir string) (ret int64, errno int64) {
|
||||
func Chdir(dir string) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(dir);
|
||||
r1, r2, err := Syscall(SYS_CHDIR, int64(uintptr(unsafe.Pointer(namebuf))), 0, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Link(oldpath, newpath string) (ret int64, errno int64) {
|
||||
oldbuf := StringBytePtr(oldpath);
|
||||
newbuf := StringBytePtr(newpath);
|
||||
func Link(oldname, newname string) (ret, errno int64) {
|
||||
oldbuf := StringBytePtr(oldname);
|
||||
newbuf := StringBytePtr(newname);
|
||||
r1, r2, err := Syscall(SYS_LINK, int64(uintptr(unsafe.Pointer(oldbuf))), int64(uintptr(unsafe.Pointer(newbuf))), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Symlink(oldpath, newpath string) (ret int64, errno int64) {
|
||||
oldbuf := StringBytePtr(oldpath);
|
||||
newbuf := StringBytePtr(newpath);
|
||||
func Symlink(oldname, newname string) (ret, errno int64) {
|
||||
oldbuf := StringBytePtr(oldname);
|
||||
newbuf := StringBytePtr(newname);
|
||||
r1, r2, err := Syscall(SYS_SYMLINK, int64(uintptr(unsafe.Pointer(oldbuf))), int64(uintptr(unsafe.Pointer(newbuf))), 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Readlink(path string, buf *byte, nbytes int64) (ret int64, errno int64) {
|
||||
pathbuf := StringBytePtr(path);
|
||||
r1, r2, err := Syscall(SYS_READLINK, int64(uintptr(unsafe.Pointer(pathbuf))), int64(uintptr(unsafe.Pointer(buf))), nbytes);
|
||||
func Readlink(name string, buf *byte, nbytes int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_READLINK, int64(uintptr(unsafe.Pointer(namebuf))), int64(uintptr(unsafe.Pointer(buf))), nbytes);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Chmod(name string, mode int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_CHMOD, int64(uintptr(unsafe.Pointer(namebuf))), mode, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Fchmod(fd, mode int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FCHMOD, fd, mode, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Chown(name string, uid, gid int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_CHOWN, int64(uintptr(unsafe.Pointer(namebuf))), uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Lchown(name string, uid, gid int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_LCHOWN, int64(uintptr(unsafe.Pointer(namebuf))), uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Fchown(fd, uid, gid int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FCHOWN, fd, uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Truncate(name string, length int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_TRUNCATE, int64(uintptr(unsafe.Pointer(namebuf))), length, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Ftruncate(fd, length int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FTRUNCATE, fd, length, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
@ -131,3 +131,43 @@ func Readlink(path string, buf *byte, nbytes int64) (ret int64, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_READLINK, int64(uintptr(unsafe.Pointer(pathbuf))), int64(uintptr(unsafe.Pointer(buf))), nbytes);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Chmod(name string, mode int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_CHMOD, int64(uintptr(unsafe.Pointer(namebuf))), mode, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Fchmod(fd, mode int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FCHMOD, fd, mode, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Chown(name string, uid, gid int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_CHOWN, int64(uintptr(unsafe.Pointer(namebuf))), uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Lchown(name string, uid, gid int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_LCHOWN, int64(uintptr(unsafe.Pointer(namebuf))), uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Fchown(fd, uid, gid int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FCHOWN, fd, uid, gid);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Truncate(name string, length int64) (ret, errno int64) {
|
||||
namebuf := StringBytePtr(name);
|
||||
r1, r2, err := Syscall(SYS_TRUNCATE, int64(uintptr(unsafe.Pointer(namebuf))), length, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
func Ftruncate(fd, length int64) (ret, errno int64) {
|
||||
r1, r2, err := Syscall(SYS_FTRUNCATE, fd, length, 0);
|
||||
return r1, err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user