1234567891011121314151617181920212223242526272829303132333435363738394041424344 |
- (in-package :hurd)
- (defcfun ("dir_readdir" %dir-readdir)
- err
- (dir port)
- (data :pointer)
- (data-cnt :pointer)
- (entry :int)
- (nentries :int)
- (bufsiz vm-size)
- (amount :pointer))
- (defconstant +dir-readdir-start-size+ 2048
- "Initial block size for dirent data as libc's readdir64.c")
- (defun %get-entries (ptr total)
- (loop for i from 0 below total
- collect (let ((entry (read-dirent ptr)))
- (incf-pointer ptr (dirent-size entry))
- entry)))
- (defun dir-readdir (dir &key (entry 0) (nentries -1) (bufsiz 0))
- "Read directory entries from 'dir'. 'entry' indicates the starting entry. 'nentries' tells how many entries we want. 'bufsiz' limits the size of entries fetched."
- (declare (type fixnum dir entry nentries bufsiz))
- (when (or (zerop nentries)
- (< nentries -1))
- (return-from dir-readdir nil))
- (with-foreign-pointer (data +dir-readdir-start-size+)
- (with-foreign-pointer (data-cnt (foreign-type-size 'msg-type-number))
- (setf (mem-ref data-cnt 'msg-type-number) +dir-readdir-start-size+)
- (with-foreign-pointer (dataptr (foreign-type-size :pointer))
- (setf (mem-ref dataptr :pointer) data)
- (with-foreign-pointer (amount (foreign-type-size :int))
- (select-error
- (%dir-readdir dir dataptr data-cnt
- entry nentries bufsiz amount)
- (let ((ptr (mem-ref dataptr :pointer))
- (total (mem-ref data-cnt 'msg-type-number)))
- (with-cleanup (unless (pointer-eq ptr data)
- (munmap ptr total))
- (%get-entries ptr (mem-ref amount :int))))))))))
|