diff --git a/src/os/file_anyos.go b/src/os/file_anyos.go index 74637a1e..f2c4acd0 100644 --- a/src/os/file_anyos.go +++ b/src/os/file_anyos.go @@ -27,6 +27,15 @@ const DevNull = "/dev/null" // filesystem support. const isOS = true +// Chdir changes the current working directory to the named directory. +// If there is an error, it will be of type *PathError. +func Chdir(dir string) error { + if e := syscall.Chdir(dir); e != nil { + return &PathError{Op: "chdir", Path: dir, Err: e} + } + return nil +} + // unixFilesystem is an empty handle for a Unix/Linux filesystem. All operations // are relative to the current working directory. type unixFilesystem struct { diff --git a/src/os/file_anyos_test.go b/src/os/file_anyos_test.go index 3c2b2457..51dac61d 100644 --- a/src/os/file_anyos_test.go +++ b/src/os/file_anyos_test.go @@ -1,3 +1,5 @@ +// +build !baremetal,!js + package os_test import ( @@ -23,3 +25,45 @@ func TestTempDir(t *testing.T) { t.Errorf("Remove %s: %s", name, err) } } + +func TestChdir(t *testing.T) { + // create and cd into a new directory + dir := "_os_test_TestChDir" + Remove(dir) + err := Mkdir(dir, 0755) + defer Remove(dir) // even though not quite sure which directory it will execute in + if err != nil { + t.Errorf("Mkdir(%s, 0755) returned %v", dir, err) + } + err = Chdir(dir) + if err != nil { + t.Fatalf("Chdir %s: %s", dir, err) + return + } + // create a file there + file := "_os_test_TestTempDir.dat" + f, err := OpenFile(file, O_RDWR|O_CREATE, 0644) + if err != nil { + t.Errorf("OpenFile %s: %s", file, err) + } + defer Remove(file) // even though not quite sure which directory it will execute in + err = f.Close() + if err != nil { + t.Errorf("Close %s: %s", file, err) + } + // cd back to original directory + err = Chdir("..") + if err != nil { + t.Errorf("Chdir ..: %s", err) + } + // clean up file and directory explicitly so we can check for errors + fullname := dir + "/" + file + err = Remove(fullname) + if err != nil { + t.Errorf("Remove %s: %s", fullname, err) + } + err = Remove(dir) + if err != nil { + t.Errorf("Remove %s: %s", dir, err) + } +} diff --git a/src/syscall/syscall_libc.go b/src/syscall/syscall_libc.go index b3cf1ce9..bfa8a72e 100644 --- a/src/syscall/syscall_libc.go +++ b/src/syscall/syscall_libc.go @@ -59,6 +59,15 @@ func Open(path string, flag int, mode uint32) (fd int, err error) { return } +func Chdir(path string) (err error) { + data := cstring(path) + fail := int(libc_chdir(&data[0])) + if fail < 0 { + err = getErrno() + } + return +} + func Mkdir(path string, mode uint32) (err error) { data := cstring(path) fail := int(libc_mkdir(&data[0], mode)) @@ -198,6 +207,10 @@ func libc_mmap(addr unsafe.Pointer, length uintptr, prot, flags, fd int32, offse //export mprotect func libc_mprotect(addr unsafe.Pointer, len uintptr, prot int32) int32 +// int chdir(const char *pathname, mode_t mode); +//export chdir +func libc_chdir(pathname *byte) int32 + // int mkdir(const char *pathname, mode_t mode); //export mkdir func libc_mkdir(pathname *byte, mode uint32) int32