Home | History | Annotate | Download | only in os
      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