diff options
Diffstat (limited to 'libgo/go/os')
-rw-r--r-- | libgo/go/os/error.go | 18 | ||||
-rw-r--r-- | libgo/go/os/error_plan9.go | 9 | ||||
-rw-r--r-- | libgo/go/os/error_posix.go | 14 | ||||
-rw-r--r-- | libgo/go/os/error_test.go | 81 | ||||
-rw-r--r-- | libgo/go/os/error_windows.go | 30 | ||||
-rw-r--r-- | libgo/go/os/exec/exec.go | 2 | ||||
-rw-r--r-- | libgo/go/os/file_unix.go | 16 | ||||
-rw-r--r-- | libgo/go/os/os_test.go | 19 | ||||
-rw-r--r-- | libgo/go/os/types.go | 4 |
9 files changed, 173 insertions, 20 deletions
diff --git a/libgo/go/os/error.go b/libgo/go/os/error.go index e0b83b5c22c..b88e49400de 100644 --- a/libgo/go/os/error.go +++ b/libgo/go/os/error.go @@ -42,3 +42,21 @@ func NewSyscallError(syscall string, err error) error { } return &SyscallError{syscall, err} } + +// IsExist returns whether the error is known to report that a file or directory +// already exists. It is satisfied by ErrExist as well as some syscall errors. +func IsExist(err error) bool { + return isExist(err) +} + +// IsNotExist returns whether the error is known to report that a file or directory +// does not exist. It is satisfied by ErrNotExist as well as some syscall errors. +func IsNotExist(err error) bool { + return isNotExist(err) +} + +// IsPermission returns whether the error is known to report that permission is denied. +// It is satisfied by ErrPermission as well as some syscall errors. +func IsPermission(err error) bool { + return isPermission(err) +} diff --git a/libgo/go/os/error_plan9.go b/libgo/go/os/error_plan9.go index 159d685e7cd..3c9dfb0b158 100644 --- a/libgo/go/os/error_plan9.go +++ b/libgo/go/os/error_plan9.go @@ -4,24 +4,21 @@ package os -// IsExist returns whether the error is known to report that a file already exists. -func IsExist(err error) bool { +func isExist(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } return contains(err.Error(), " exists") } -// IsNotExist returns whether the error is known to report that a file does not exist. -func IsNotExist(err error) bool { +func isNotExist(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } return contains(err.Error(), "does not exist") } -// IsPermission returns whether the error is known to report that permission is denied. -func IsPermission(err error) bool { +func isPermission(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go index 74b75d11218..1685c1f2132 100644 --- a/libgo/go/os/error_posix.go +++ b/libgo/go/os/error_posix.go @@ -2,33 +2,27 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin freebsd linux netbsd openbsd windows +// +build darwin freebsd linux netbsd openbsd package os import "syscall" -// IsExist returns whether the error is known to report that a file already exists. -// It is satisfied by ErrExist as well as some syscall errors. -func IsExist(err error) bool { +func isExist(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } return err == syscall.EEXIST || err == ErrExist } -// IsNotExist returns whether the error is known to report that a file does not exist. -// It is satisfied by ErrNotExist as well as some syscall errors. -func IsNotExist(err error) bool { +func isNotExist(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } return err == syscall.ENOENT || err == ErrNotExist } -// IsPermission returns whether the error is known to report that permission is denied. -// It is satisfied by ErrPermission as well as some syscall errors. -func IsPermission(err error) bool { +func isPermission(err error) bool { if pe, ok := err.(*PathError); ok { err = pe.Err } diff --git a/libgo/go/os/error_test.go b/libgo/go/os/error_test.go new file mode 100644 index 00000000000..42f846fa3c5 --- /dev/null +++ b/libgo/go/os/error_test.go @@ -0,0 +1,81 @@ +// Copyright 2012 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_test + +import ( + "fmt" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func TestErrIsExist(t *testing.T) { + f, err := ioutil.TempFile("", "_Go_ErrIsExist") + if err != nil { + t.Fatalf("open ErrIsExist tempfile: %s", err) + return + } + defer os.Remove(f.Name()) + defer f.Close() + f2, err := os.OpenFile(f.Name(), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600) + if err == nil { + f2.Close() + t.Fatal("Open should have failed") + return + } + if s := checkErrorPredicate("os.IsExist", os.IsExist, err); s != "" { + t.Fatal(s) + return + } +} + +func testErrNotExist(name string) string { + f, err := os.Open(name) + if err == nil { + f.Close() + return "Open should have failed" + } + if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" { + return s + } + + err = os.Chdir(name) + if err == nil { + return "Chdir should have failed" + } + if s := checkErrorPredicate("os.IsNotExist", os.IsNotExist, err); s != "" { + return s + } + return "" +} + +func TestErrIsNotExist(t *testing.T) { + tmpDir, err := ioutil.TempDir("", "_Go_ErrIsNotExist") + if err != nil { + t.Fatalf("create ErrIsNotExist tempdir: %s", err) + return + } + defer os.RemoveAll(tmpDir) + + name := filepath.Join(tmpDir, "NotExists") + if s := testErrNotExist(name); s != "" { + t.Fatal(s) + return + } + + name = filepath.Join(name, "NotExists2") + if s := testErrNotExist(name); s != "" { + t.Fatal(s) + return + } +} + +func checkErrorPredicate(predName string, pred func(error) bool, err error) string { + if !pred(err) { + return fmt.Sprintf("%s does not work as expected for %#v", predName, err) + } + return "" +} diff --git a/libgo/go/os/error_windows.go b/libgo/go/os/error_windows.go new file mode 100644 index 00000000000..5d692b07362 --- /dev/null +++ b/libgo/go/os/error_windows.go @@ -0,0 +1,30 @@ +// Copyright 2012 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 "syscall" + +func isExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return err == syscall.ERROR_ALREADY_EXISTS || + err == syscall.ERROR_FILE_EXISTS || err == ErrExist +} + +func isNotExist(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return err == syscall.ERROR_FILE_NOT_FOUND || + err == syscall.ERROR_PATH_NOT_FOUND || err == ErrNotExist +} + +func isPermission(err error) bool { + if pe, ok := err.(*PathError); ok { + err = pe.Err + } + return err == ErrPermission +} diff --git a/libgo/go/os/exec/exec.go b/libgo/go/os/exec/exec.go index ebe92a9fba3..bbd04902b74 100644 --- a/libgo/go/os/exec/exec.go +++ b/libgo/go/os/exec/exec.go @@ -59,7 +59,7 @@ type Cmd struct { // If either is nil, Run connects the corresponding file descriptor // to the null device (os.DevNull). // - // If Stdout and Stderr are are the same writer, at most one + // If Stdout and Stderr are the same writer, at most one // goroutine at a time will call Write. Stdout io.Writer Stderr io.Writer diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go index a69680cb8c9..b8fb2e22c98 100644 --- a/libgo/go/os/file_unix.go +++ b/libgo/go/os/file_unix.go @@ -179,7 +179,21 @@ func (f *File) pread(b []byte, off int64) (n int, err error) { // write writes len(b) bytes to the File. // It returns the number of bytes written and an error, if any. func (f *File) write(b []byte) (n int, err error) { - return syscall.Write(f.fd, b) + for { + m, err := syscall.Write(f.fd, b) + n += m + + // If the syscall wrote some data but not all (short write) + // or it returned EINTR, then assume it stopped early for + // reasons that are uninteresting to the caller, and try again. + if 0 < m && m < len(b) || err == syscall.EINTR { + b = b[m:] + continue + } + + return n, err + } + panic("not reached") } // pwrite writes len(b) bytes to the File starting at byte offset off. diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index aa01669a5da..8d3f677fd4e 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -1045,3 +1045,22 @@ func TestSameFile(t *testing.T) { t.Errorf("files should be different") } } + +func TestDevNullFile(t *testing.T) { + f, err := Open(DevNull) + if err != nil { + t.Fatalf("Open(%s): %v", DevNull, err) + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + t.Fatalf("Stat(%s): %v", DevNull, err) + } + name := filepath.Base(DevNull) + if fi.Name() != name { + t.Fatalf("wrong file name have %v want %v", fi.Name(), name) + } + if fi.Size() != 0 { + t.Fatalf("wrong file size have %d want 0", fi.Size()) + } +} diff --git a/libgo/go/os/types.go b/libgo/go/os/types.go index c7c5199be1c..0c95c9cece0 100644 --- a/libgo/go/os/types.go +++ b/libgo/go/os/types.go @@ -15,7 +15,7 @@ func Getpagesize() int { return syscall.Getpagesize() } // A FileInfo describes a file and is returned by Stat and Lstat type FileInfo interface { Name() string // base name of the file - Size() int64 // length in bytes + Size() int64 // length in bytes for regular files; system-dependent for others Mode() FileMode // file mode bits ModTime() time.Time // modification time IsDir() bool // abbreviation for Mode().IsDir() @@ -58,7 +58,7 @@ const ( func (m FileMode) String() string { const str = "dalTLDpSugct" - var buf [20]byte + var buf [32]byte // Mode is uint32. w := 0 for i, c := range str { if m&(1<<uint(32-1-i)) != 0 { |