Re: d_namlen?

Linus Torvalds (Linus.Torvalds@cs.helsinki.fi)
Mon, 26 Jun 1995 08:51:22 +0300


Snow Cat: "d_namlen?" (Jun 25, 2:25):
>
> Is there any plan to support correct and separate d_reclen and d_namlen in
> struct dirent in future? It appears that currently readdir() returns d_reclen
> that is useless to a user - a size of structure aligned to a 4-byte boundary
> (?). I think on most other system it's EXACT structure size. d_namlen is
> probably used by a lot of GNU and BSD programs. Other systems I have seen have
> both reclen and namlen.

I personally would like to totally forget about "d_namlen", for a couple
of reasons:
- it's not POSIX. Thus program which uses it is broken.
- SVR4 doesn't seem to have it, so programs that use it are _doubly_
broken.
- it's useless. Any broken program which uses it can trivially be
altered to use "strlen(dirent->d_name)" instead.

Thus, I personally feel that d_namlen should go away. Potentially
together with a library version increment operation..

Compared to d_namlen, d_reclen actually makes sense: I sent out a new
version of "readdir()" etc to some people, and that version was
_trivial_ to do using d_reclen and d_off. While d_namlen never even
entered the picture.

> It was my impression that under linux 1.2 and libc 5.0.x d_reclen was actually
> set to strlen(dir -> d_name). If so, shouldn't it be just renamed to d_namlen
> instead of having to recompile and patch make and other existing binaries?

I think we probably need an old entry-point in the library for the
old-style readdir() interface for programs that depend on it. Something
like this:

/*
* old_dirent is the same as the new dirent, but
* we have "d_namlen" instead of "d_reclen". Thus
* we can memcpy() from one to the other, as long as
* we fix up that difference.
*/
struct old_dirent {
long d_ino;
off_t d_off;
unsigned short d_namlen;
char d_name[256];
};

struct old_dirent * oldreaddir(DIR * dir)
{
static old_dirent oldd;
struct dirent * d;

d = readdir(dir);
if (!d)
return NULL;
memcpy(&oldd, d, d->d_reclen);
oldd.d_namlen = strlen(d->d_name);
return &oldd;
}

The above should take care of old binaries linked against an older
library, and newly compiled objects will use the new dirent structure
(and they'll have gotten compile-time warnings if they tried to use
d_namlen).

Linus