Revert r215321.
[official-gcc.git] / libgo / go / os / dir.go
blobd811c9fdd863682e0bf601adbf8a342885780448
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package os
7 import (
8 "io"
9 "sync/atomic"
10 "syscall"
11 "unsafe"
14 //extern opendir
15 func libc_opendir(*byte) *syscall.DIR
17 //extern closedir
18 func libc_closedir(*syscall.DIR) int
20 // FIXME: pathconf returns long, not int.
21 //extern pathconf
22 func libc_pathconf(*byte, int) int
24 func clen(n []byte) int {
25 for i := 0; i < len(n); i++ {
26 if n[i] == 0 {
27 return i
30 return len(n)
33 var nameMax int32
35 func (file *File) readdirnames(n int) (names []string, err error) {
36 if file.dirinfo == nil {
37 p, err := syscall.BytePtrFromString(file.name)
38 if err != nil {
39 return nil, err
42 elen := int(atomic.LoadInt32(&nameMax))
43 if elen == 0 {
44 syscall.Entersyscall()
45 plen := libc_pathconf(p, syscall.PC_NAME_MAX)
46 syscall.Exitsyscall()
47 if plen < 1024 {
48 plen = 1024
50 var dummy syscall.Dirent
51 elen = int(unsafe.Offsetof(dummy.Name)) + plen + 1
52 atomic.StoreInt32(&nameMax, int32(elen))
55 syscall.Entersyscall()
56 r := libc_opendir(p)
57 errno := syscall.GetErrno()
58 syscall.Exitsyscall()
59 if r == nil {
60 return nil, &PathError{"opendir", file.name, errno}
63 file.dirinfo = new(dirInfo)
64 file.dirinfo.buf = make([]byte, elen)
65 file.dirinfo.dir = r
68 entryDirent := (*syscall.Dirent)(unsafe.Pointer(&file.dirinfo.buf[0]))
70 size := n
71 if size <= 0 {
72 size = 100
73 n = -1
76 names = make([]string, 0, size) // Empty with room to grow.
78 for n != 0 {
79 var dirent *syscall.Dirent
80 pr := &dirent
81 syscall.Entersyscall()
82 i := libc_readdir_r(file.dirinfo.dir, entryDirent, pr)
83 syscall.Exitsyscall()
84 if i != 0 {
85 return names, NewSyscallError("readdir_r", i)
87 if dirent == nil {
88 break // EOF
90 bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
91 var name = string(bytes[0:clen(bytes[:])])
92 if name == "." || name == ".." { // Useless names
93 continue
95 names = append(names, name)
96 n--
98 if n >= 0 && len(names) == 0 {
99 return names, io.EOF
101 return names, nil