www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 283] New: listdir does not decend into subdirs on linux

reply d-bugmail puremagic.com writes:
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
next sibling parent reply d-bugmail puremagic.com writes:
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
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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
parent =?UTF-8?B?SmFyaS1NYXR0aSBNw6RrZWzDpA==?= <jmjmak utu.fi.invalid> writes:
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
prev sibling next sibling parent d-bugmail puremagic.com writes:
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
prev sibling parent d-bugmail puremagic.com writes:
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