[Larceny-users] directory-files

Felix Klock felixluser at pnkfx.org
Wed Feb 28 21:51:26 EST 2007


On Jan 29, 2007, at 10:45 PM, Felix Klock wrote:

>
> On Jan 29, 2007, at 5:18 AM, Sven.Hartrumpf at FernUni-Hagen.de wrote:
>
>> Is there a function in Larceny like
>>
>> http://www.shiro.dreamhost.com/scheme/wiliki/schemexref.cgi? 
>> directory-files
>>
>> I have searched the Larceny svn tree but could not find anything.
>
> To my knowledge, there is not such a function in Larceny.
>
> Which is unfortunate because it is not easy to write such a  
> function with the primitives offered by (native and Petit)  
> Larceny.  The only options I can think of are to either go through  
> the FFI to implement your own routine to do directory listings, or  
> invoke the system procedure with a command string like "dir > tmp- 
> file" and then if you're lucky, you can parse the resulting file.

Here is a definition of a function that uses the FFI  to list the  
files in a directory (represented by a string holding the directory's  
path).

There is a bit of target-specific magic, namely the "magic  
number" (11) for the offset into the dirent structure to get at the  
char* for the entry name.  This is a part of the FFI I am unhappy  
about; obviously no one wants to have to calculate offsets into  
structures that might differ from platform to platform.  (E.g., my  
attempt to use this same code on Solaris indicates that the magic  
number on that platform is 10.)  I am vaguely aware of "solutions" to  
this problem (e.g. libffi) but am not sure if any is worth  
incorporating into Larceny. . .

Anyway, the below seems to work on Larceny v0.93 on (my particular  
version of) Linux.

(require 'std-ffi)

(define list-directory
   (let ()
     ;; magic number pointing to d_name offset in dirent structure...
     (define *d_name_offset* 11)
     (define readdir  (foreign-procedure "readdir"  '(unsigned)  
'unsigned))
     (define opendir  (foreign-procedure "opendir"  '(string)    
'unsigned))
     (define closedir (foreign-procedure "closedir" '(unsigned) 'void))

     (define (dirent->name ent)
       (let loop ((l '())
                  (i *d_name_offset*))
         (let ((b (%peek8 (+ ent i))))
           (if (zero? b)
               (list->string (reverse l))
               (loop (cons (integer->char b) l)
                     (+ i 1))))))

     ;; list-directory : String -> [Listof String]
     (define (list-directory path)
       (let* ((dir (opendir path))
              (files (let loop ((ent (readdir dir)))
                       (if (zero? ent)
                           '()
                           (cons (dirent->name ent)
                                 (loop (readdir dir)))))))

         (closedir dir)
         files))

     list-directory))




More information about the Larceny-users mailing list