From: Aurelio B. <cl...@bi...> - 2007-08-21 16:44:02
|
There is a problem with linux:dirent and linux:readdir: CL-USER> (setf *dd* (linux:opendir "/usr/local/src/clisp/")) #<FOREIGN-ADDRESS #x08217808> CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19916 :D_OFF 0 :D_RECLEN 2 :D_TYPE 0 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19819 :D_OFF 0 :D_RECLEN 40960 :D_TYPE 24 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19917 :D_OFF 0 :D_RECLEN 11392 :D_TYPE 36 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19921 :D_OFF 0 :D_RECLEN 10368 :D_TYPE 41 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 20051 :D_OFF 0 :D_RECLEN 5120 :D_TYPE 203 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 20093 :D_OFF 0 :D_RECLEN 25088 :D_TYPE 124 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19919 :D_OFF 0 :D_RECLEN 53504 :D_TYPE 59 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19923 :D_OFF 0 :D_RECLEN 54912 :D_TYPE 117 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 20091 :D_OFF 0 :D_RECLEN 32128 :D_TYPE 207 :D_NAME "") CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 20095 :D_OFF 0 :D_RECLEN 7808 :D_TYPE 53 :D_NAME "") CL-USER> (linux:closedir *dd*) 0 CL-USER> The d_name field should of course contain the file name instead of garbage. The cause of the bug seems to be the definition of the d_off field as off_t in linux:dirent: CL-USER> (use-package :ffi) T CL-USER> (def-c-struct my-dirent (d_ino long) (d_off long) (d_reclen ushort) (d_type uchar) (d_name (c-array-max character 256))) MY-DIRENT CL-USER> (def-call-out my-readdir (:name "readdir") (:library "libglib.so") (:language :stdc) (:arguments (dirp c-pointer)) (:return-type (c-ptr-null my-dirent))) MY-READDIR CL-USER> (setf *dd* (linux:opendir "/usr/local/src/clisp/")) #<FOREIGN-ADDRESS #x08219218> CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19916 :D_OFF 2 :D_RECLEN 16 :D_TYPE 0 :D_NAME ".") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19819 :D_OFF 1613824 :D_RECLEN 16 :D_TYPE 0 :D_NAME "..") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19917 :D_OFF 2370688 :D_RECLEN 16 :D_TYPE 0 :D_NAME "CVS") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19921 :D_OFF 2697344 :D_RECLEN 16 :D_TYPE 0 :D_NAME "doc") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 20051 :D_OFF 30086144 :D_RECLEN 16 :D_TYPE 0 :D_NAME "src") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 20093 :D_OFF 108814848 :D_RECLEN 16 :D_TYPE 0 :D_NAME "unix") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19919 :D_OFF 289132800 :D_RECLEN 24 :D_TYPE 0 :D_NAME "benchmarks") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 19923 :D_OFF 326489728 :D_RECLEN 20 :D_TYPE 0 :D_NAME "emacs") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 20091 :D_OFF 332365184 :D_RECLEN 20 :D_TYPE 0 :D_NAME "tests") CL-USER> (my-readdir *dd*) #S(MY-DIRENT :D_INO 20095 :D_OFF 473243264 :D_RECLEN 20 :D_TYPE 0 :D_NAME "utils") CL-USER> (linux:closedir *dd*) 0 CL-USER> off_t is defined in modules/bindings/glibc/linux.lisp by the following two def-c-type: (def-c-type __off_t long) (def-c-type off_t __off_t) but for some reasons I can't figure out d_off ends up to be a bit: CL-USER> (setf *dd* (linux:opendir "/usr/local/src/clisp/")) #<FOREIGN-ADDRESS #x08219218> CL-USER> (linux:readdir *dd*) #S(LINUX:dirent :D_INO 19916 :D_OFF 0 :D_RECLEN 2 :D_TYPE 0 :D_NAME "") CL-USER> (inspect *) #S(LINUX:dirent :D_INO 19916 :D_OFF 0 :D_RECLEN 2 :D_TYPE 0 :D_NAME ""): structure object type: LINUX:dirent 0 [D_INO]: 19916 1 [D_OFF]: 0 2 [D_RECLEN]: 2 3 [D_TYPE]: 0 4 [D_NAME]: "" INSPECT-- type :h for help; :q to return to the REPL ---> 1 0: atom type: BIT class: #1=#<BUILT-IN-CLASS INTEGER> INSPECT-- type :h for help; :q to return to the REPL ---> |
From: Sam S. <sd...@gn...> - 2007-08-22 14:30:11
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Aurelio Bignoli wrote: > There is a problem with linux:dirent and linux:readdir: > > > CL-USER> (setf *dd* (linux:opendir "/usr/local/src/clisp/")) > #<FOREIGN-ADDRESS #x08217808> > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19916 :D_OFF 0 :D_RECLEN 2 :D_TYPE 0 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19819 :D_OFF 0 :D_RECLEN 40960 :D_TYPE 24 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19917 :D_OFF 0 :D_RECLEN 11392 :D_TYPE 36 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19921 :D_OFF 0 :D_RECLEN 10368 :D_TYPE 41 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 20051 :D_OFF 0 :D_RECLEN 5120 :D_TYPE 203 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 20093 :D_OFF 0 :D_RECLEN 25088 :D_TYPE 124 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19919 :D_OFF 0 :D_RECLEN 53504 :D_TYPE 59 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 19923 :D_OFF 0 :D_RECLEN 54912 :D_TYPE 117 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 20091 :D_OFF 0 :D_RECLEN 32128 :D_TYPE 207 :D_NAME "") > CL-USER> (linux:readdir *dd*) > #S(LINUX:dirent :D_INO 20095 :D_OFF 0 :D_RECLEN 7808 :D_TYPE 53 :D_NAME "") > CL-USER> (linux:closedir *dd*) > 0 > CL-USER> > yep. a bug. please file a bug report on SF. thanks. > The d_name field should of course contain the file name instead of > garbage. The cause of the bug seems to be the definition of the d_off > field as off_t in linux:dirent: > > > CL-USER> (use-package :ffi) > T > CL-USER> (def-c-struct my-dirent > (d_ino long) > (d_off long) > (d_reclen ushort) > (d_type uchar) > (d_name (c-array-max character 256))) > > MY-DIRENT > CL-USER> (def-call-out my-readdir > (:name "readdir") > (:library "libglib.so") > (:language :stdc) > (:arguments (dirp c-pointer)) > (:return-type (c-ptr-null my-dirent))) > MY-READDIR > CL-USER> (setf *dd* (linux:opendir "/usr/local/src/clisp/")) > #<FOREIGN-ADDRESS #x08219218> > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19916 :D_OFF 2 :D_RECLEN 16 :D_TYPE 0 :D_NAME ".") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19819 :D_OFF 1613824 :D_RECLEN 16 :D_TYPE 0 :D_NAME "..") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19917 :D_OFF 2370688 :D_RECLEN 16 :D_TYPE 0 :D_NAME "CVS") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19921 :D_OFF 2697344 :D_RECLEN 16 :D_TYPE 0 :D_NAME "doc") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 20051 :D_OFF 30086144 :D_RECLEN 16 :D_TYPE 0 :D_NAME "src") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 20093 :D_OFF 108814848 :D_RECLEN 16 :D_TYPE 0 :D_NAME "unix") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19919 :D_OFF 289132800 :D_RECLEN 24 :D_TYPE 0 :D_NAME "benchmarks") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 19923 :D_OFF 326489728 :D_RECLEN 20 :D_TYPE 0 :D_NAME "emacs") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 20091 :D_OFF 332365184 :D_RECLEN 20 :D_TYPE 0 :D_NAME "tests") > CL-USER> (my-readdir *dd*) > #S(MY-DIRENT :D_INO 20095 :D_OFF 473243264 :D_RECLEN 20 :D_TYPE 0 :D_NAME "utils") > CL-USER> (linux:closedir *dd*) > 0 > CL-USER> > > > off_t is defined in modules/bindings/glibc/linux.lisp by the following > two def-c-type: > > (def-c-type __off_t long) > (def-c-type off_t __off_t) yeah, this is is a big problem with any ffi: how to figure out the types. alas, the only reliable way is to use a C compiler (i.e., C modules). the ffi relies on humans delivering correct type definitions, and this means changing the lisp files when the libc changes (and then old machines are no longer supported). I think I will try to implement (def-c-type foo) to mean "ask C compiler about size of foo". please file a bug report in the meantime... thanks. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGzEhnPp1Qsf2qnMcRAqJ1AKCk87VIf48nt6sGCvaJIh33h09P6ACfbZTZ lMycrOMMULJn1ygF+CCC1bI= =taeT -----END PGP SIGNATURE----- |