Bug 283 – incorrect std.c.linux.linux.dirent definition / listdir does not decend into subdirs on linux
Status
RESOLVED
Resolution
WONTFIX
Severity
major
Priority
P2
Component
phobos
Product
D
Version
D1 (retired)
Platform
x86
OS
Linux
Creation time
2006-08-12T01:01:00Z
Last change time
2014-02-15T13:25:00Z
Assigned to
bugzilla
Creator
funisher
Comments
Comment #0 by funisher — 2006-08-12T01:01:10Z
this is cause because the stat file is never being called. instead of checking the stat, it's easier (but probably slower) to isdir()
Comment #1 by thomas-dloop — 2007-04-29T02:09:23Z
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
Comment #2 by fvbommel — 2007-04-29T05:05:27Z
[email protected] wrote:
> ------- Comment #1 from [email protected] 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;
}
---
Comment #3 by bugzilla — 2007-10-02T15:42:12Z
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.
Comment #4 by afb — 2007-10-02T16:09:42Z
GDC uses autoconf and a C program, to generate the definition of "dirent"...