diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-06 02:00:13 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-06 02:00:13 +0000 |
commit | ccc7a47f9e250e1fcd4079dcb9d11c6aecd320f9 (patch) | |
tree | cc71dfa39df4e1b16b96f13ad38293dbc9f135e7 /libgo | |
parent | 25522845e74f2d4c50893f9b1893b0a45e043d55 (diff) | |
download | gcc-ccc7a47f9e250e1fcd4079dcb9d11c6aecd320f9.tar.gz |
os: Clean up directory reading code.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194237 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/go/os/dir.go | 56 | ||||
-rw-r--r-- | libgo/go/os/file_unix.go | 9 |
2 files changed, 41 insertions, 24 deletions
diff --git a/libgo/go/os/dir.go b/libgo/go/os/dir.go index a35d525319a..d811c9fdd86 100644 --- a/libgo/go/os/dir.go +++ b/libgo/go/os/dir.go @@ -6,6 +6,7 @@ package os import ( "io" + "sync/atomic" "syscall" "unsafe" ) @@ -29,27 +30,42 @@ func clen(n []byte) int { return len(n) } -var elen int +var nameMax int32 func (file *File) readdirnames(n int) (names []string, err error) { - if elen == 0 { - var dummy syscall.Dirent - elen = (int(unsafe.Offsetof(dummy.Name)) + - libc_pathconf(syscall.StringBytePtr(file.name), syscall.PC_NAME_MAX) + - 1) - } - if file.dirinfo == nil { - file.dirinfo = new(dirInfo) - file.dirinfo.buf = make([]byte, elen) - p := syscall.StringBytePtr(file.name) + 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 } - entry_dirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0])) + entryDirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0])) size := n if size <= 0 { @@ -59,24 +75,20 @@ func (file *File) readdirnames(n int) (names []string, err error) { names = make([]string, 0, size) // Empty with room to grow. - dir := file.dirinfo.dir - if dir == nil { - return names, NewSyscallError("opendir", syscall.GetErrno()) - } - for n != 0 { - var result *syscall.Dirent - pr := &result + var dirent *syscall.Dirent + pr := &dirent syscall.Entersyscall() - i := libc_readdir_r(dir, entry_dirent, pr) + i := libc_readdir_r(file.dirinfo.dir, entryDirent, pr) syscall.Exitsyscall() if i != 0 { return names, NewSyscallError("readdir_r", i) } - if result == nil { + if dirent == nil { break // EOF } - var name = string(result.Name[0:clen(result.Name[0:])]) + bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) + var name = string(bytes[0:clen(bytes[:])]) if name == "." || name == ".." { // Useless names continue } diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go index f677dbb986a..68f4be88d06 100644 --- a/libgo/go/os/file_unix.go +++ b/libgo/go/os/file_unix.go @@ -108,8 +108,13 @@ func (file *file) close() error { } if file.dirinfo != nil { - if libc_closedir(file.dirinfo.dir) < 0 && err == nil { - err = &PathError{"closedir", file.name, syscall.GetErrno()} + syscall.Entersyscall() + i := libc_closedir(file.dirinfo.dir) + errno := syscall.GetErrno() + syscall.Exitsyscall() + file.dirinfo = nil + if i < 0 && err == nil { + err = &PathError{"closedir", file.name, errno} } } |