summaryrefslogtreecommitdiff
path: root/libgo/go/os/dir.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/os/dir.go')
-rw-r--r--libgo/go/os/dir.go128
1 files changed, 36 insertions, 92 deletions
diff --git a/libgo/go/os/dir.go b/libgo/go/os/dir.go
index d811c9fdd8..6c54456a21 100644
--- a/libgo/go/os/dir.go
+++ b/libgo/go/os/dir.go
@@ -1,102 +1,46 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2016 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 (
- "io"
- "sync/atomic"
- "syscall"
- "unsafe"
-)
-
-//extern opendir
-func libc_opendir(*byte) *syscall.DIR
-
-//extern closedir
-func libc_closedir(*syscall.DIR) int
-
-// FIXME: pathconf returns long, not int.
-//extern pathconf
-func libc_pathconf(*byte, int) int
-
-func clen(n []byte) int {
- for i := 0; i < len(n); i++ {
- if n[i] == 0 {
- return i
- }
+// Readdir reads the contents of the directory associated with file and
+// returns a slice of up to n FileInfo values, as would be returned
+// by Lstat, in directory order. Subsequent calls on the same file will yield
+// further FileInfos.
+//
+// If n > 0, Readdir returns at most n FileInfo structures. In this case, if
+// Readdir returns an empty slice, it will return a non-nil error
+// explaining why. At the end of a directory, the error is io.EOF.
+//
+// If n <= 0, Readdir returns all the FileInfo from the directory in
+// a single slice. In this case, if Readdir succeeds (reads all
+// the way to the end of the directory), it returns the slice and a
+// nil error. If it encounters an error before the end of the
+// directory, Readdir returns the FileInfo read until that point
+// and a non-nil error.
+func (f *File) Readdir(n int) ([]FileInfo, error) {
+ if f == nil {
+ return nil, ErrInvalid
}
- return len(n)
+ return f.readdir(n)
}
-var nameMax int32
-
-func (file *File) readdirnames(n int) (names []string, err error) {
- if file.dirinfo == nil {
- p, err := syscall.BytePtrFromString(file.name)
- if err != nil {
- return nil, err
- }
-
- elen := int(atomic.LoadInt32(&nameMax))
- if elen == 0 {
- syscall.Entersyscall()
- plen := libc_pathconf(p, syscall.PC_NAME_MAX)
- syscall.Exitsyscall()
- if plen < 1024 {
- plen = 1024
- }
- var dummy syscall.Dirent
- elen = int(unsafe.Offsetof(dummy.Name)) + plen + 1
- atomic.StoreInt32(&nameMax, int32(elen))
- }
-
- syscall.Entersyscall()
- r := libc_opendir(p)
- errno := syscall.GetErrno()
- syscall.Exitsyscall()
- if r == nil {
- return nil, &PathError{"opendir", file.name, errno}
- }
-
- file.dirinfo = new(dirInfo)
- file.dirinfo.buf = make([]byte, elen)
- file.dirinfo.dir = r
- }
-
- entryDirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0]))
-
- size := n
- if size <= 0 {
- size = 100
- n = -1
- }
-
- names = make([]string, 0, size) // Empty with room to grow.
-
- for n != 0 {
- var dirent *syscall.Dirent
- pr := &dirent
- syscall.Entersyscall()
- i := libc_readdir_r(file.dirinfo.dir, entryDirent, pr)
- syscall.Exitsyscall()
- if i != 0 {
- return names, NewSyscallError("readdir_r", i)
- }
- if dirent == nil {
- break // EOF
- }
- bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
- var name = string(bytes[0:clen(bytes[:])])
- if name == "." || name == ".." { // Useless names
- continue
- }
- names = append(names, name)
- n--
- }
- if n >= 0 && len(names) == 0 {
- return names, io.EOF
+// Readdirnames reads and returns a slice of names from the directory f.
+//
+// If n > 0, Readdirnames returns at most n names. In this case, if
+// Readdirnames returns an empty slice, it will return a non-nil error
+// explaining why. At the end of a directory, the error is io.EOF.
+//
+// If n <= 0, Readdirnames returns all the names from the directory in
+// a single slice. In this case, if Readdirnames succeeds (reads all
+// the way to the end of the directory), it returns the slice and a
+// nil error. If it encounters an error before the end of the
+// directory, Readdirnames returns the names read until that point and
+// a non-nil error.
+func (f *File) Readdirnames(n int) (names []string, err error) {
+ if f == nil {
+ return nil, ErrInvalid
}
- return names, nil
+ return f.readdirnames(n)
}