| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package os |
| |
| import ( |
| "io" |
| "syscall" |
| ) |
| |
| func (file *File) readdir(n int) ([]FileInfo, error) { |
| // If this file has no dirinfo, create one. |
| if file.dirinfo == nil { |
| file.dirinfo = new(dirInfo) |
| } |
| d := file.dirinfo |
| size := n |
| if size <= 0 { |
| size = 100 |
| n = -1 |
| } |
| fi := make([]FileInfo, 0, size) // Empty with room to grow. |
| for n != 0 { |
| // Refill the buffer if necessary. |
| if d.bufp >= d.nbuf { |
| nb, err := file.Read(d.buf[:]) |
| |
| // Update the buffer state before checking for errors. |
| d.bufp, d.nbuf = 0, nb |
| |
| if err != nil { |
| if err == io.EOF { |
| break |
| } |
| return fi, &PathError{"readdir", file.name, err} |
| } |
| if nb < syscall.STATFIXLEN { |
| return fi, &PathError{"readdir", file.name, syscall.ErrShortStat} |
| } |
| } |
| |
| // Get a record from the buffer. |
| b := d.buf[d.bufp:] |
| m := int(uint16(b[0])|uint16(b[1])<<8) + 2 |
| if m < syscall.STATFIXLEN { |
| return fi, &PathError{"readdir", file.name, syscall.ErrShortStat} |
| } |
| |
| dir, err := syscall.UnmarshalDir(b[:m]) |
| if err != nil { |
| return fi, &PathError{"readdir", file.name, err} |
| } |
| fi = append(fi, fileInfoFromStat(dir)) |
| |
| d.bufp += m |
| n-- |
| } |
| |
| if n >= 0 && len(fi) == 0 { |
| return fi, io.EOF |
| } |
| return fi, nil |
| } |
| |
| func (file *File) readdirnames(n int) (names []string, err error) { |
| fi, err := file.Readdir(n) |
| names = make([]string, len(fi)) |
| for i := range fi { |
| names[i] = fi[i].Name() |
| } |
| return |
| } |