github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/os/dir_unix.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 aix dragonfly freebsd js,wasm linux netbsd openbsd solaris
     6  
     7  package os
     8  
     9  import (
    10  	"github.com/x04/go/src/io"
    11  	"github.com/x04/go/src/runtime"
    12  	"github.com/x04/go/src/syscall"
    13  )
    14  
    15  // Auxiliary information if the File describes a directory
    16  type dirInfo struct {
    17  	buf	[]byte	// buffer for directory I/O
    18  	nbuf	int	// length of buf; return value from Getdirentries
    19  	bufp	int	// location of next record in buf.
    20  }
    21  
    22  const (
    23  	// More than 5760 to work around https://golang.org/issue/24015.
    24  	blockSize = 8192
    25  )
    26  
    27  func (d *dirInfo) close()	{}
    28  
    29  func (f *File) seekInvalidate()	{}
    30  
    31  func (f *File) readdirnames(n int) (names []string, err error) {
    32  	// If this file has no dirinfo, create one.
    33  	if f.dirinfo == nil {
    34  		f.dirinfo = new(dirInfo)
    35  		// The buffer must be at least a block long.
    36  		f.dirinfo.buf = make([]byte, blockSize)
    37  	}
    38  	d := f.dirinfo
    39  
    40  	size := n
    41  	if size <= 0 {
    42  		size = 100
    43  		n = -1
    44  	}
    45  
    46  	names = make([]string, 0, size)	// Empty with room to grow.
    47  	for n != 0 {
    48  		// Refill the buffer if necessary
    49  		if d.bufp >= d.nbuf {
    50  			d.bufp = 0
    51  			var errno error
    52  			d.nbuf, errno = f.pfd.ReadDirent(d.buf)
    53  			runtime.KeepAlive(f)
    54  			if errno != nil {
    55  				return names, wrapSyscallError("readdirent", errno)
    56  			}
    57  			if d.nbuf <= 0 {
    58  				break	// EOF
    59  			}
    60  		}
    61  
    62  		// Drain the buffer
    63  		var nb, nc int
    64  		nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
    65  		d.bufp += nb
    66  		n -= nc
    67  	}
    68  	if n >= 0 && len(names) == 0 {
    69  		return names, io.EOF
    70  	}
    71  	return names, nil
    72  }