| // 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 | 
 | } |