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 "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 } 74