github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/os/dir_ios.go (about) 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. 4 5 // +build darwin 6 // +build arm arm64 7 8 package os 9 10 import ( 11 "io" 12 "runtime" 13 "syscall" 14 "unsafe" 15 ) 16 17 // Auxiliary information if the File describes a directory 18 type dirInfo struct { 19 dir uintptr // Pointer to DIR structure from dirent.h 20 } 21 22 func (d *dirInfo) close() { 23 if d.dir == 0 { 24 return 25 } 26 closedir(d.dir) 27 d.dir = 0 28 } 29 30 func (f *File) readdirnames(n int) (names []string, err error) { 31 if f.dirinfo == nil { 32 dir, call, errno := f.pfd.OpenDir() 33 if errno != nil { 34 return nil, wrapSyscallError(call, errno) 35 } 36 f.dirinfo = &dirInfo{ 37 dir: dir, 38 } 39 } 40 d := f.dirinfo 41 42 size := n 43 if size <= 0 { 44 size = 100 45 n = -1 46 } 47 48 names = make([]string, 0, size) 49 var dirent syscall.Dirent 50 var entptr uintptr 51 for len(names) < size { 52 if res := readdir_r(d.dir, uintptr(unsafe.Pointer(&dirent)), uintptr(unsafe.Pointer(&entptr))); res != 0 { 53 return names, wrapSyscallError("readdir", syscall.Errno(res)) 54 } 55 if entptr == 0 { // EOF 56 break 57 } 58 if dirent.Ino == 0 { 59 continue 60 } 61 name := (*[len(syscall.Dirent{}.Name)]byte)(unsafe.Pointer(&dirent.Name))[:] 62 for i, c := range name { 63 if c == 0 { 64 name = name[:i] 65 break 66 } 67 } 68 // Check for useless names before allocating a string. 69 if string(name) == "." || string(name) == ".." { 70 continue 71 } 72 names = append(names, string(name)) 73 runtime.KeepAlive(f) 74 } 75 if n >= 0 && len(names) == 0 { 76 return names, io.EOF 77 } 78 return names, nil 79 } 80 81 // Implemented in syscall/syscall_darwin.go. 82 83 //go:linkname closedir syscall.closedir 84 func closedir(dir uintptr) (err error) 85 86 //go:linkname readdir_r syscall.readdir_r 87 func readdir_r(dir, entry, result uintptr) (res int)