[comp.lang.c] question on opendir, readdir, etc.

tr@samadams.princeton.edu (Tom Reingold) (11/30/90)

Here is what I've surmised so far.

To use opendir, readdir, etc. on BSD, you include <sys/dir.h>.  This
lets you use a struct defined as direct.  The member d_name is a
character array of size MAXNAMLEN+1 (256).

To use these functions on System V, you include <dirent.h>.  This lets
you use a struct defined as dirent.  Confusingly close.  The member
d_name is a character array of size 1!  Is this for real?  I have a
sample program which works, but I think I'm lucky that trashing the
area after my structure doesn't kill anything vital.

Am I not supposed to use these functions in System V?  If I am, do they
normally work?
--
        Tom Reingold
        tr@samadams.princeton.edu  OR  ...!princeton!samadams!tr
        "Warning: Do not drive with Auto-Shade in place.  Remove
        from windshield before starting ignition."

gwyn@smoke.brl.mil (Doug Gwyn) (11/30/90)

In article <4767@rossignol.Princeton.EDU> tr@samadams.princeton.edu (Tom Reingold) writes:
>To use opendir, readdir, etc. on BSD, you include <sys/dir.h>.  This
>lets you use a struct defined as direct.  The member d_name is a
>character array of size MAXNAMLEN+1 (256).

That is obsolete.

>To use these functions on System V, you include <dirent.h>.  This lets
>you use a struct defined as dirent.  Confusingly close.  The member
>d_name is a character array of size 1!  Is this for real?  I have a
>sample program which works, but I think I'm lucky that trashing the
>area after my structure doesn't kill anything vital.

UNIX System (as of release 3.0) included IEEE Std 1003.1 (POSIX)-
compatible directory access functions and the corresponding header.
The code actually originated with my independent implementation;
Kirk McKusick of UCB had earlier provided an implementation of the
BSD "struct direct" flavor of these functions, which inspired the
POSIX specification.  There were good reasons for the slight changes
made by IEEE P1003, which I won't go into here.

>Am I not supposed to use these functions in System V?  If I am, do they
>normally work?

Yes, they had BETTER work.  The [1] kludge is deliberate, and from
time to time argument rages about whether the C standard requires that
an implementation make it work or whether it could ever fail.  I have
yet to hear of any commercial UNIX implementation where it doesn't
work.

You can also obtain my current implementation simply by requesting it
in an e-mail message to me <Gwyn@BRL.MIL>.

tr@samadams.princeton.edu (Tom Reingold) (11/30/90)

In article <14611@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn)
writes:

$ In article <4767@rossignol.Princeton.EDU> tr@samadams.princeton.edu
$ (Tom Reingold) writes:
$ >To use opendir, readdir, etc. on BSD, you include <sys/dir.h>.  This
$ >lets you use a struct defined as direct.  The member d_name is a
$ >character array of size MAXNAMLEN+1 (256).
$ 
$ That is obsolete.

Which is obsolete?  <sys/ndir.h>?

$ >To use these functions on System V, you include <dirent.h>.  This lets
$ >you use a struct defined as dirent.  Confusingly close.  The member
$ >d_name is a character array of size 1!  Is this for real?  I have a
$ >sample program which works, but I think I'm lucky that trashing the
$ >area after my structure doesn't kill anything vital.
$ 
$ UNIX System (as of release 3.0) included IEEE Std 1003.1 (POSIX)-
$ compatible directory access functions and the corresponding header.
$ The code actually originated with my independent implementation;
$ Kirk McKusick of UCB had earlier provided an implementation of the
$ BSD "struct direct" flavor of these functions, which inspired the
$ POSIX specification.  There were good reasons for the slight changes
$ made by IEEE P1003, which I won't go into here.
$ 
$ >Am I not supposed to use these functions in System V?  If I am, do they
$ >normally work?
$ 
$ Yes, they had BETTER work.  The [1] kludge is deliberate, and from
$ time to time argument rages about whether the C standard requires that
$ an implementation make it work or whether it could ever fail.  I have
$ yet to hear of any commercial UNIX implementation where it doesn't
$ work.

How can it work?  And why was this kludge put there?

$ You can also obtain my current implementation simply by requesting it
$ in an e-mail message to me <Gwyn@BRL.MIL>.

I have it already, thank you.  Now I know I should use it.

Is this POSIX standard found in System V Release 4?
--
        Tom Reingold
        tr@samadams.princeton.edu  OR  ...!princeton!samadams!tr
        "Warning: Do not drive with Auto-Shade in place.  Remove
        from windshield before starting ignition."

gwyn@smoke.brl.mil (Doug Gwyn) (11/30/90)

In article <4776@rossignol.Princeton.EDU> tr@samadams.princeton.edu (Tom Reingold) writes:
>Which is obsolete?  <sys/ndir.h>?

All forms of directory access that bypass getdents() are obsolete.
Basically, you should use only the <dirent.h> form of opendir()/
readdir()/closedir() or some library function that is layered on top
of those.  seekdir()/telldir() are not recommended.

>How can it work?  And why was this kludge put there?

What do you mean, how can it work?  If you look at the sources you
said you have, you should see that there is actually more storage
present than one might guess from just looking at the struct dirent.
The line of argumentation that ties wording in the C standard to
exploitation of this trick is rather long and involved, and would
not be worth rehashing yet again here.  (Besides, everyone involved
in the argument, including me, has flip-flopped a couple of times on
the issue of whether a conforming implementation is obliged to make
the trick work.  In practice, it can normally be expected to work,
so this is a purely academic issue.)

The reason for the kludge (more a "trick") is that it was desired
to not allocate a maximum-length array for a directory entry, but
rather just as much storage as was really necessary.

>$ You can also obtain my current implementation simply by requesting it
>$ in an e-mail message to me <Gwyn@BRL.MIL>.
>I have it already, thank you.  Now I know I should use it.

Make sure you have a recent release.  Some of the versions in
circulation have a couple of subtle bugs in them (use of a field
in a free()d structure in closedir(), and a problem with 14-character
entries in the UFS version of getdents()).

>Is this POSIX standard found in System V Release 4?

UNIX System V Release 4.0 attempts to be IEEE Std 1003.1 compliant.
The <dirent.h> facilities are specified in the current SVID, so
naturally they are in SVR4.