github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/os/dir_plan9.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  package os
     6  
     7  import (
     8  	"github.com/x04/go/src/io"
     9  	"github.com/x04/go/src/syscall"
    10  )
    11  
    12  func (file *File) readdir(n int) ([]FileInfo, error) {
    13  	// If this file has no dirinfo, create one.
    14  	if file.dirinfo == nil {
    15  		file.dirinfo = new(dirInfo)
    16  	}
    17  	d := file.dirinfo
    18  	size := n
    19  	if size <= 0 {
    20  		size = 100
    21  		n = -1
    22  	}
    23  	fi := make([]FileInfo, 0, size)	// Empty with room to grow.
    24  	for n != 0 {
    25  		// Refill the buffer if necessary.
    26  		if d.bufp >= d.nbuf {
    27  			nb, err := file.Read(d.buf[:])
    28  
    29  			// Update the buffer state before checking for errors.
    30  			d.bufp, d.nbuf = 0, nb
    31  
    32  			if err != nil {
    33  				if err == io.EOF {
    34  					break
    35  				}
    36  				return fi, &PathError{"readdir", file.name, err}
    37  			}
    38  			if nb < syscall.STATFIXLEN {
    39  				return fi, &PathError{"readdir", file.name, syscall.ErrShortStat}
    40  			}
    41  		}
    42  
    43  		// Get a record from the buffer.
    44  		b := d.buf[d.bufp:]
    45  		m := int(uint16(b[0])|uint16(b[1])<<8) + 2
    46  		if m < syscall.STATFIXLEN {
    47  			return fi, &PathError{"readdir", file.name, syscall.ErrShortStat}
    48  		}
    49  
    50  		dir, err := syscall.UnmarshalDir(b[:m])
    51  		if err != nil {
    52  			return fi, &PathError{"readdir", file.name, err}
    53  		}
    54  		fi = append(fi, fileInfoFromStat(dir))
    55  
    56  		d.bufp += m
    57  		n--
    58  	}
    59  
    60  	if n >= 0 && len(fi) == 0 {
    61  		return fi, io.EOF
    62  	}
    63  	return fi, nil
    64  }
    65  
    66  func (file *File) readdirnames(n int) (names []string, err error) {
    67  	fi, err := file.Readdir(n)
    68  	names = make([]string, len(fi))
    69  	for i := range fi {
    70  		names[i] = fi[i].Name()
    71  	}
    72  	return
    73  }