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 ---> |