From: SourceForge.net <no...@so...> - 2007-08-24 12:57:16
|
Bugs item #1779490, was opened at 2007-08-22 10:59 Message generated for change (Comment added) made by sds You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1779490&group_id=1355 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: ffi Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Aurelio Bignoli (abignoli) Assigned to: Jörg Höhle (hoehle) Summary: linux:dirent definition error Initial Comment: Field D_OFF of LINUX:DIRENT structure has wrong type. Test case: CL-USER> (linux:opendir "/tmp") #<FOREIGN-ADDRESS #x08217808> CL-USER> (linux:readdir *) #S(LINUX:dirent :D_INO 2 :D_OFF 0 :D_RECLEN 2 :D_TYPE 0 :D_NAME "") CL-USER> (type-of linux:dirent-d_off *) ; Evaluation aborted. CL-USER> (type-of (linux:dirent-d_off *)) BIT CL-USER> Field D_OFF should have type long. ---------------------------------------------------------------------- >Comment By: Sam Steingold (sds) Date: 2007-08-24 08:57 Message: Logged In: YES user_id=5735 Originator: NO (def-c-type size_t) means that 'size_t is mapped to "size_t" in *c-type-table*. a string type is interpreted by foreign.d as a lookup in O(foreign_inttype_table) which will map "size_t" to (u|s)int(32|64), according to register_foreign_inttype() call from module__linux__init_function_2(). with the new patch, readdir is still broken while readdir64 works, see modules/bindings/glibc/test.tst ---------------------------------------------------------------------- Comment By: Jörg Höhle (hoehle) Date: 2007-08-24 06:49 Message: Logged In: YES user_id=377168 Originator: NO Sam, I didn't understand all your comments. I used (in clisp-2.38) (def-c-struct dirent2 (d_ino sint64) (d_off sint64) (d_reclen ushort) (d_type uchar) (d_name (c-array-max character #.(cl:+ NAME_MAX 1))) ) and obtained (readdir2 fp) #S(DIRENT2 :D_INO 9389 :D_OFF 221505536 :D_RECLEN 32 :D_TYPE 0 :D_NAME ".ICE-unix") [22]> (readdir2 fp) #S(DIRENT2 :D_INO 35047 :D_OFF 411272320 :D_RECLEN 40 :D_TYPE 0 :D_NAME "keyring-OQyXPY") ls -lia shows D_INO looks good. I wonder how your patch can possibly work, since for ffi:parse-c-type (convert_to_foreign etc.) it is essential that all sizes be known so the structures are allocated of the correct size. Where does the size come from after clisp accepts (def-c-type size_t)? How does Lisp know that it needs 64bit versions of dirent? (I'm quite unsure I'll have time this week-end to check your patch). BTW, do you know that you may need to redefine functions when you redefine a c-struct? (because the original def is integrated into the signature) Maybe that explains why you observed garbage? E.g. if you overwrite linux:dirent with uint64, you should re-evaluate def-c-call readdir afterwards. ---------------------------------------------------------------------- Comment By: Sam Steingold (sds) Date: 2007-08-23 18:18 Message: Logged In: YES user_id=5735 Originator: NO OK, I committed a large patch that allows (def-c-type size_t) without specifying the actual size. this does NOT fix dirent for some reason, but I added dirent64 and readdir64, and they DO work. I am not closing the bug, but I am out of my depth here - Joerg, could you please fix it? ---------------------------------------------------------------------- Comment By: Sam Steingold (sds) Date: 2007-08-23 15:44 Message: Logged In: YES user_id=5735 Originator: NO what's even more confusing is that odd_t and ino_t are really 64 bit: sizeof(dirent)=276 offsetof(dirent,d_ino)=0 offsetof(dirent,d_off)=8 offsetof(dirent,d_reclen)=16 offsetof(dirent,d_type)=18 offsetof(dirent,d_name)=19 sizeof(dirent.d_ino)=8 sizeof(dirent.d_off)=8 sizeof(dirent.d_reclen)=2 sizeof(dirent.d_type)=1 sizeof(dirent.d_name)=256 but (def-c-struct my-dirent64 (d_ino uint64) (d_off uint64) (d_reclen ushort) (d_type uchar) (d_name (c-array-max character 256))) generates garbage, even though its size is "correct": (sizeof 'linux:dirent) 268 ; 4 (sizeof 'MY-DIRENT) 268 ; 4 (sizeof 'MY-DIRENT64) 276 ; 4 ---------------------------------------------------------------------- Comment By: Sam Steingold (sds) Date: 2007-08-23 13:13 Message: Logged In: YES user_id=5735 Originator: NO Joerg, I have a patch that should make it work (but does not...) basically, I allow (def-c-type foo) to mean "foo is an int type - figure out its size and sign at compile time". then (def-c-type off_t) will figure out whether off_t is 64 bit or 32 bit at compile time. alas, something is wrong: in convert_from_foreign, *(struct dirent*)data prints TRT with the patch, but the function returns garbage, while with the explicit (def-c-struct my-dirent (d_ino long) (d_off long) (d_reclen ushort) (d_type uchar) (d_name (c-array-max character 256))) *(struct dirent*)data prints garbage, but the lisp function return TRT. I attach the gdb sessions. any suggestions? File Added: gdb.log ---------------------------------------------------------------------- Comment By: Jörg Höhle (hoehle) Date: 2007-08-23 12:51 Message: Logged In: YES user_id=377168 Originator: NO On my Ubuntu Daper 32bit box /usr/include/bits/dirent.h contains: struct dirent { #ifndef __USE_FILE_OFFSET64 __ino_t d_ino; __off_t d_off; #else __ino64_t d_ino; __off64_t d_off; #endif unsigned short int d_reclen; unsigned char d_type; char d_name[256]; /* We must not include limits.h! */ }; I have no idea whether __USE_FILE_OFFSET64 is defined on my box. But that does not matter. What's worse is that I have no idea how to reproduce the above #ifdef in the Lisp code of modules/bindings/linux.lisp so that the correct def is chosen on all platforms. ... My Ubuntu Dapper 32bit Intel centrino system apparently requires 64bit defs. readdir yields proper results only with s/uint64 type definitions. _USE_FILE_OFFSET64 is defined in /usr/include/features.h based on other defines from an unknown location. So how to let Lisp know the proper definitions? Or work around the problem differently? ---------------------------------------------------------------------- Comment By: Sam Steingold (sds) Date: 2007-08-22 17:41 Message: Logged In: YES user_id=5735 Originator: NO actually, type-of return the type of the value, not the type of the slot. it's BIT because that's the type of 0. it's not clear to me what is going on: your code works and indicates that d_off and d_ino are 32-bit, while gdb appears to think they are 64 bit each. ---------------------------------------------------------------------- Comment By: Sam Steingold (sds) Date: 2007-08-22 11:36 Message: Logged In: YES user_id=5735 Originator: NO <http://permalink.gmane.org/gmane.lisp.clisp.general/11913> <http://permalink.gmane.org/gmane.lisp.clisp.general/11917> ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=101355&aid=1779490&group_id=1355 |