mirror of
https://github.com/golang/go
synced 2024-11-18 04:24:47 -07:00
Add os.Link, os.Symlink, os.Readlink.
R=r,rsc DELTA=161 (161 added, 0 deleted, 0 changed) OCL=28745 CL=28747
This commit is contained in:
parent
52f071ed43
commit
7aabf2d9b1
@ -306,3 +306,30 @@ func Remove(name string) Error {
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Link creates a hard link.
|
||||
func Link(oldpath, newpath string) Error {
|
||||
r, e := syscall.Link(oldpath, newpath);
|
||||
return ErrnoToError(e);
|
||||
}
|
||||
|
||||
// Symlink creates a symbolic link.
|
||||
func Symlink(oldpath, newpath string) Error {
|
||||
r, e := syscall.Symlink(oldpath, newpath);
|
||||
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) {
|
||||
for len := int64(128); ; len *= 2 {
|
||||
b := make([]byte, len);
|
||||
r, e := syscall.Readlink(path, &b[0], len);
|
||||
if r == -1 {
|
||||
return "", ErrnoToError(e);
|
||||
} else if r < len {
|
||||
return string(b[0:r]), nil;
|
||||
}
|
||||
}
|
||||
// Silence 6g.
|
||||
return "", nil;
|
||||
}
|
||||
|
@ -205,3 +205,97 @@ func TestReaddirnamesOneAtATime(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHardLink(t *testing.T) {
|
||||
from, to := "hardlinktestfrom", "hardlinktestto";
|
||||
Remove(from); // Just in case.
|
||||
file, err := Open(to, O_CREAT | O_WRONLY, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err);
|
||||
}
|
||||
defer Remove(to);
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err);
|
||||
}
|
||||
err = Link(to, from);
|
||||
if err != nil {
|
||||
t.Fatalf("link %q, %q failed: %v", to, from, err);
|
||||
}
|
||||
defer Remove(from);
|
||||
tostat, err := Stat(to);
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err);
|
||||
}
|
||||
fromstat, err := Stat(from);
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err);
|
||||
}
|
||||
if tostat.Dev != fromstat.Dev || tostat.Ino != fromstat.Ino {
|
||||
t.Errorf("link %q, %q did not create hard link", to, from);
|
||||
}
|
||||
}
|
||||
|
||||
func TestSymLink(t *testing.T) {
|
||||
from, to := "symlinktestfrom", "symlinktestto";
|
||||
Remove(from); // Just in case.
|
||||
file, err := Open(to, O_CREAT | O_WRONLY, 0666);
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", to, err);
|
||||
}
|
||||
defer Remove(to);
|
||||
if err = file.Close(); err != nil {
|
||||
t.Errorf("close %q failed: %v", to, err);
|
||||
}
|
||||
err = Symlink(to, from);
|
||||
if err != nil {
|
||||
t.Fatalf("symlink %q, %q failed: %v", to, from, err);
|
||||
}
|
||||
defer Remove(from);
|
||||
tostat, err := Stat(to);
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", to, err);
|
||||
}
|
||||
fromstat, err := Stat(from);
|
||||
if err != nil {
|
||||
t.Fatalf("stat %q failed: %v", from, err);
|
||||
}
|
||||
if tostat.Dev != fromstat.Dev || tostat.Ino != fromstat.Ino {
|
||||
t.Errorf("symlink %q, %q did not create symlink", to, from);
|
||||
}
|
||||
fromstat, err = Lstat(from);
|
||||
if err != nil {
|
||||
t.Fatalf("lstat %q failed: %v", from, err);
|
||||
}
|
||||
if !fromstat.IsSymlink() {
|
||||
t.Fatalf("symlink %q, %q did not create symlink", to, from);
|
||||
}
|
||||
s, err := Readlink(from);
|
||||
if err != nil {
|
||||
t.Fatalf("readlink %q failed: %v", from, err);
|
||||
}
|
||||
if s != to {
|
||||
t.Fatalf("after symlink %q != %q", s, to);
|
||||
}
|
||||
file, err = Open(from, O_RDONLY, 0);
|
||||
if err != nil {
|
||||
t.Fatalf("open %q failed: %v", from, err);
|
||||
}
|
||||
file.Close();
|
||||
}
|
||||
|
||||
func TestLongSymlink(t *testing.T) {
|
||||
s := "0123456789abcdef";
|
||||
s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s + s;
|
||||
from := "longsymlinktestfrom";
|
||||
err := Symlink(s, from);
|
||||
if err != nil {
|
||||
t.Fatalf("symlink %q, %q failed: %v", s, from, err);
|
||||
}
|
||||
defer Remove(from);
|
||||
r, err := Readlink(from);
|
||||
if err != nil {
|
||||
t.Fatalf("readlink %q failed: %v", from, err);
|
||||
}
|
||||
if r != s {
|
||||
t.Fatalf("after symlink %q != %q", r, s);
|
||||
}
|
||||
}
|
||||
|
@ -110,3 +110,23 @@ func Chdir(dir string) (ret int64, errno int64) {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return r1, err;
|
||||
}
|
||||
|
@ -111,3 +111,23 @@ func Chdir(dir string) (ret int64, errno int64) {
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return r1, err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user