github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 "io" 9 "io/fs" 10 "syscall" 11 ) 12 13 func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) { 14 // If this file has no dirinfo, create one. 15 if file.dirinfo == nil { 16 file.dirinfo = new(dirInfo) 17 } 18 d := file.dirinfo 19 size := n 20 if size <= 0 { 21 size = 100 22 n = -1 23 } 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 names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: err} 37 } 38 if nb < syscall.STATFIXLEN { 39 return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: 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 names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: syscall.ErrShortStat} 48 } 49 50 dir, err := syscall.UnmarshalDir(b[:m]) 51 if err != nil { 52 return names, dirents, infos, &PathError{Op: "readdir", Path: file.name, Err: err} 53 } 54 55 if mode == readdirName { 56 names = append(names, dir.Name) 57 } else { 58 f := fileInfoFromStat(dir) 59 if mode == readdirDirEntry { 60 dirents = append(dirents, dirEntry{f}) 61 } else { 62 infos = append(infos, f) 63 } 64 } 65 d.bufp += m 66 n-- 67 } 68 69 if n > 0 && len(names)+len(dirents)+len(infos) == 0 { 70 return nil, nil, nil, io.EOF 71 } 72 return names, dirents, infos, nil 73 } 74 75 type dirEntry struct { 76 fs *fileStat 77 } 78 79 func (de dirEntry) Name() string { return de.fs.Name() } 80 func (de dirEntry) IsDir() bool { return de.fs.IsDir() } 81 func (de dirEntry) Type() FileMode { return de.fs.Mode().Type() } 82 func (de dirEntry) Info() (FileInfo, error) { return de.fs, nil } 83 84 func (de dirEntry) String() string { 85 return fs.FormatDirEntry(de) 86 }