func ext۰syscall۰ParseDirent(fr *Frame, args []Value) Value { // func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) max := args[1].(int) var names []string for _, iname := range args[2].([]Value) { names = append(names, iname.(string)) } consumed, count, newnames := syscall.ParseDirent(ValueToBytes(args[0]), max, names) var inewnames []Value for _, newname := range newnames { inewnames = append(inewnames, newname) } return tuple{consumed, count, inewnames} }
func readDir(dir string) []string { fd, err := syscall.Open(dir, syscall.O_CLOEXEC, 0644) if err != nil { return []string{} } defer syscall.Close(fd) var size = 100 var n = -1 var nbuf int var bufp int var buf = make([]byte, 4096) var names = make([]string, 0, size) for n != 0 { if bufp >= nbuf { bufp = 0 var errno error nbuf, errno = fixCount(syscall.ReadDirent(fd, buf)) if errno != nil { return names } if nbuf <= 0 { break } } var nb, nc int nb, nc, names = syscall.ParseDirent(buf[bufp:nbuf], n, names) bufp += nb n -= nc } return names }
func (f *File) readdirnames(n int) (names []string, err error) { // If this file has no dirinfo, create one. if f.dirinfo == nil { f.dirinfo = new(dirInfo) // The buffer must be at least a block long. f.dirinfo.buf = make([]byte, blockSize) } d := f.dirinfo size := n if size <= 0 { size = 100 n = -1 } names = make([]string, 0, size) // Empty with room to grow. for n != 0 { // Refill the buffer if necessary if d.bufp >= d.nbuf { d.bufp = 0 var errno error d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf) if errno != nil { return names, NewSyscallError("readdirent", errno) } if d.nbuf <= 0 { break // EOF } } // Drain the buffer var nb, nc int nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names) d.bufp += nb n -= nc } if n >= 0 && len(names) == 0 { return names, io.EOF } return names, nil }
func Walk(_path string, _filter Filter, _collector Collector, _errors Errors) { var _cursor *cursor var _error Error var _errno int _cursor, _error = open(nil, _path) if _error != nil { _errors(_error) } for _cursor != nil { if !_cursor.filtered { _cursor.recurse, _cursor.collect = _filter(_cursor.entity) _cursor.filtered = true } if _cursor.collect { _entity := new(Entity) *_entity = *_cursor.entity if _entity.Descriptor >= 0 { _entity.Descriptor, _errno = syscall.Dup(_entity.Descriptor) } else { _errno = 0 } if _errno == 0 { _collector(_entity) } else { _errors(newError("dup", _cursor.entity.Path, _cursor.entity.Descriptor, _errno)) } _cursor.collect = false } if _cursor.recurse && _cursor.entity.IsDirectory() && _cursor.entity.IsOpen() { if _cursor.dirent == nil { _cursor.dirent = new(dirent) _cursor.dirent.nameBuffer = make([]string, 0, _nameBufferSize) _cursor.dirent.dataBuffer = make([]byte, _dataBufferSize) } if _nameBufferLen := len(_cursor.dirent.nameBuffer); _nameBufferLen > 0 { _childName := _cursor.dirent.nameBuffer[_nameBufferLen-1] _cursor.dirent.nameBuffer[_nameBufferLen-1] = "" _cursor.dirent.nameBuffer = _cursor.dirent.nameBuffer[:_nameBufferLen-1] var _childCursor, _error = open(_cursor, _childName) if _error == nil { _cursor = _childCursor } else { _errors(_error) } continue } if !_cursor.dirent.dataEnded && (_cursor.dirent.dataOffset == _cursor.dirent.dataLimit) { _cursor.dirent.dataOffset = 0 _cursor.dirent.dataLimit, _errno = syscall.ReadDirent(_cursor.entity.Descriptor, _cursor.dirent.dataBuffer[:]) if _errno == 0 { if _cursor.dirent.dataLimit == 0 { _cursor.dirent.dataEnded = true } } else { _errors(newError("readdirent", _cursor.entity.Path, _cursor.entity.Descriptor, _errno)) _cursor.dirent.dataLimit = 0 _cursor.dirent.dataEnded = true } } if !_cursor.dirent.dataEnded { _dataParsed, _, _nameBuffer := syscall.ParseDirent(_cursor.dirent.dataBuffer[_cursor.dirent.dataOffset:_cursor.dirent.dataLimit], cap(_cursor.dirent.nameBuffer), _cursor.dirent.nameBuffer) if _dataParsed == 0 { _errors(newError("parsedirent", _cursor.entity.Path, _cursor.entity.Descriptor, syscall.EINVAL)) _cursor.dirent.dataLimit = 0 _cursor.dirent.dataOffset = 0 _cursor.dirent.dataEnded = true } else { _cursor.dirent.dataOffset += _dataParsed _cursor.dirent.nameBuffer = _nameBuffer continue } } } if _cursor.entity.IsOpen() { _cursor.entity.Close() } _cursor = _cursor.parent } }