...

Source file src/pkg/os/dir_darwin.go

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

View as plain text