Re: [question]

Guest section DW (dwguest@win.tue.nl)
Tue, 19 Jan 1999 01:35:02 +0100 (MET)


I'm puzzled by the returned data of the 'readdir' call. The dirent
structure has a d_reclen entry. If I run a small C program under 2.0.36
which returns the d_reclen of the root directory entries I get:

d_name '.'
d_reclen:12 strlen(d_name):1
d_name '..'
d_reclen:16 strlen(d_name):2
d_name 'lost+found'
d_reclen:24 strlen(d_name):10

Yes - so what do you see?
d_reclen is strlen(d_name)+11, rounded up to be divisible by 4.

d_reclen is *very* different from the strlen of the entry. I would expect
d_reclen to be equal to the strlen result. d_reclen seems to return the
number of bytes of allocation in the directory file, these are multiple
of 4 . 32 bits INTS.
In the GNU C_library in the function getcwd d_reclen (d_namelen) is used
to build the pathname which sometimes give odd results e.g. somewhere in a
mounted NCP or Samba tree.
If one uses 'less' or 'vi' or '/bin/pwd' these programs complain that they
are unable to find the current working directory.

Hmm. Why not read the man pages?
Let me see - man readdir: ... superseded by getdents(2) ... -
man getdents:

The dirent structure is declared as follows:

struct dirent
{
long d_ino; /* inode number */
off_t d_off; /* offset to next dirent */
unsigned short d_reclen; /* length of this dirent */
char d_name [NAME_MAX+1]; /* file name (null-terminated) */
}

This answers your question about the meaning of d_reclen.
(And you see the 4+4+2+namelen+1=11+namelen.)

Or, to be more precise, about the meaning of d_reclen as returned by the
getdents() system call.

What about glibc? You shouldnt want to know this: POSIX only knows about
d_name, so any use of any other field is nonportable (and indeed, various
C libraries have had different layouts and contents for a struct dirent),
but inspection of /usr/include/dirent*.h shows

struct dirent
{
long int d_ino;
__off_t d_off;
unsigned short int d_reclen;
unsigned char d_type;
char d_name[256]; /* We must not include limits.h! */
};

Hmm - interesting, an additional field.
So, the dirent's of this glibc 2.0.7 are larger than the kernel's.
But your answers are identical to the kernel's.
So, your `GNU C-library' is not glibc 2.0.7 - probably older.
I am too lazy to investigate the history of struct dirent's in
various C libraries. If you continue to have problems, please
also give the glibc version you are using.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/