Exemplo n.º 1
0
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}
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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
}
Exemplo n.º 4
0
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
	}
}