digitalmars.D.bugs - [Issue 283] New: listdir does not decend into subdirs on linux
- d-bugmail puremagic.com Aug 11 2006
- d-bugmail puremagic.com Apr 29 2007
- Frits van Bommel <fvbommel REMwOVExCAPSs.nl> Apr 29 2007
- d-bugmail puremagic.com Oct 02 2007
- d-bugmail puremagic.com Oct 02 2007
http://d.puremagic.com/issues/show_bug.cgi?id=283 Summary: listdir does not decend into subdirs on linux Product: D Version: 0.163 Platform: PC OS/Version: Linux Status: NEW Severity: minor Priority: P2 Component: Phobos AssignedTo: bugzilla digitalmars.com ReportedBy: funisher gmail.com this is cause because the stat file is never being called. instead of checking the stat, it's easier (but probably slower) to isdir() --
Aug 11 2006
http://d.puremagic.com/issues/show_bug.cgi?id=283 thomas-dloop kuehne.cn changed: What |Removed |Added ---------------------------------------------------------------------------- Severity|minor |major Summary|listdir does not decend into|incorrect |subdirs on linux |std.c.linux.linux.dirent | |definition / listdir does | |not decend into subdirs on | |linux ------- Comment #1 from thomas-dloop kuehne.cn 2007-04-29 02:09 ------- std.c.linux.linux.dirent is defined as # struct dirent # { # int d_ino; # off_t d_off; # ushort d_reclen; # ubyte d_type; # char[256] d_name; # } It is just luck that the current std.file.listdir functions don't segfault on Linux because the above structure should be named dirent64 not dirent. /usr/include/linux/dirent.h : # #ifndef _LINUX_DIRENT_H # #define _LINUX_DIRENT_H # # #include <linux/types.h> # # struct dirent { # long d_ino; # __kernel_off_t d_off; # unsigned short d_reclen; # char d_name[256]; /* We must not include limits.h! */ # }; # # struct dirent64 { # __u64 d_ino; # __s64 d_off; # unsigned short d_reclen; # unsigned char d_type; # char d_name[256]; # }; # # # #endif Either rename the structure to dirent64 and use readdir64 in std.file.listdir or fix the definition and rewrite std.file.DirEntry.init/isdir/isfile --
Apr 29 2007
d-bugmail puremagic.com wrote:------- Comment #1 from thomas-dloop kuehne.cn 2007-04-29 02:09 ------- std.c.linux.linux.dirent is defined as # struct dirent # { # int d_ino; # off_t d_off; # ushort d_reclen; # ubyte d_type; # char[256] d_name; # } It is just luck that the current std.file.listdir functions don't segfault on Linux because the above structure should be named dirent64 not dirent. /usr/include/linux/dirent.h : # #ifndef _LINUX_DIRENT_H # #define _LINUX_DIRENT_H # # #include <linux/types.h> # # struct dirent { # long d_ino; # __kernel_off_t d_off; # unsigned short d_reclen; # char d_name[256]; /* We must not include limits.h! */ # }; # # struct dirent64 { # __u64 d_ino; # __s64 d_off; # unsigned short d_reclen; # unsigned char d_type; # char d_name[256]; # }; # # # #endif Either rename the structure to dirent64 and use readdir64 in std.file.listdir or fix the definition and rewrite std.file.DirEntry.init/isdir/isfile
Actually, it looks like the current structure is a weird mix of dirent and dirent64. It has dirent64's d_type element, but the types of d_ino and d_off are both 32-bit signed integers (like in dirent) instead of unsigned 64-bit an signed 64-bit, respectively (like in dirent64). So it should either be: --- struct dirent { int d_ino; off_t d_off; ushort d_reclen; char[256] d_name; } --- or: --- struct dirent64 { ulong d_ino; long d_off; ushort d_reclen; ubyte d_type; char[256] d_name; } ---
Apr 29 2007
Frits van Bommel kirjoitti:d-bugmail puremagic.com wrote:------- Comment #1 from thomas-dloop kuehne.cn 2007-04-29 02:09 ------- std.c.linux.linux.dirent is defined as # struct dirent # { # int d_ino; # off_t d_off; # ushort d_reclen; # ubyte d_type; # char[256] d_name; # } It is just luck that the current std.file.listdir functions don't segfault on Linux because the above structure should be named dirent64 not dirent. /usr/include/linux/dirent.h : # #ifndef _LINUX_DIRENT_H # #define _LINUX_DIRENT_H # # #include <linux/types.h> # # struct dirent { # long d_ino; # __kernel_off_t d_off; # unsigned short d_reclen; # char d_name[256]; /* We must not include limits.h! */ # }; # # struct dirent64 { # __u64 d_ino; # __s64 d_off; # unsigned short d_reclen; # unsigned char d_type; # char d_name[256]; # }; # # # #endif Either rename the structure to dirent64 and use readdir64 in std.file.listdir or fix the definition and rewrite std.file.DirEntry.init/isdir/isfile
Actually, it looks like the current structure is a weird mix of dirent and dirent64. It has dirent64's d_type element, but the types of d_ino and d_off are both 32-bit signed integers (like in dirent) instead of unsigned 64-bit an signed 64-bit, respectively (like in dirent64). So it should either be: --- struct dirent { int d_ino; off_t d_off; ushort d_reclen; char[256] d_name; } --- or: --- struct dirent64 { ulong d_ino; long d_off; ushort d_reclen; ubyte d_type; char[256] d_name; }
That's interesting. Tango had the same problem (although IIRC dirent struct in Tango looked exactly the same as on my system .h files). It still didn't work. Tango team switched it to use stat, which I think is what it uses even now. At least that works.
Apr 29 2007
http://d.puremagic.com/issues/show_bug.cgi?id=283 bugzilla digitalmars.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |WONTFIX ------- Comment #3 from bugzilla digitalmars.com 2007-10-02 15:42 ------- On Redhat 9, dirent is defined in /usr/include/bits/dirent.h as: struct dirent { #ifndef __USE_FILE_OFFSET54 __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]; }; which matches what is in std.c.linux.linux, so I really don't see what can be done about this. --
Oct 02 2007
http://d.puremagic.com/issues/show_bug.cgi?id=283 ------- Comment #4 from afb algonet.se 2007-10-02 16:09 ------- GDC uses autoconf and a C program, to generate the definition of "dirent"... --
Oct 02 2007









=?UTF-8?B?SmFyaS1NYXR0aSBNw6RrZWzDpA==?= <jmjmak utu.fi.invalid> 