ditto@cbmvax.UUCP (Michael "Ford" Ditto) (03/11/89)
A few people have asked about <dirent.h>. This is the header file used by programs using the directory(3) directory-reading package. These routines come with SVR3, but for us Unix PC (SVR2) users, there are a few ways to get a package that works. Possibly the best thing to do is to get Doug Gwyn's complete portable directory(3) implementation. It has been posted in various news groups and should be easy to find. What I did is to use the one I wrote a long time ago. It is very simple, and supports opendir, readdir, rewinddir, and closedir (but not seekdir). It only works on "normal" (i.e. fixed-length-directory-entry) file systems, such as those in SVR2. You might want to delete the last two lines in my "dirent.h" - they allow programs to use the 4BSD name for struct dirent, but the #define is a bit dangerous. Just "make directory.o" and either install it as /usr/lib/libndir.a or, if you really trust it, ar it into /lib/libc.a. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # directory.c # dirent.h # This archive created: Fri Mar 10 18:59:47 1989 export PATH; PATH=/bin:$PATH echo shar: extracting "'directory.c'" '(1458 characters)' if test -f 'directory.c' then echo shar: will not over-write existing file "'directory.c'" else cat << \SHAR_EOF > 'directory.c' #include <stdio.h> #include <fcntl.h> #include <sys/dir.h> #include <dirent.h> #undef direct extern long lseek(); extern char *malloc(), *strncpy(); extern void free(); DIR *opendir(name) char *name; { DIR *dirp; int fd; if ((fd=open(name, O_RDONLY)) < 0) return NULL; if ( (dirp=(DIR *)malloc(sizeof (*dirp))) == NULL ) { (void)close(fd); return NULL; } dirp->dd_fd = fd; dirp->dd_ptr = dirp->dd_block + sizeof (dirp->dd_block); return dirp; } void rewinddir(dirp) DIR *dirp; { (void)lseek(dirp->dd_fd, 0L, 0); dirp->dd_ptr = dirp->dd_block + sizeof (dirp->dd_block); } struct dirent *readdir(dirp) DIR *dirp; { register int nbytes; register struct direct *directp; do { if (dirp->dd_ptr >= dirp->dd_block + sizeof (dirp->dd_block)) { nbytes = read(dirp->dd_fd, dirp->dd_block, sizeof dirp->dd_block); if ( nbytes <= 0 ) return NULL; while (nbytes<sizeof (dirp->dd_block)) dirp->dd_block[nbytes++] = 0; dirp->dd_ptr = dirp->dd_block; } directp = (struct direct *)dirp->dd_ptr; dirp->dd_ptr += sizeof (*directp); } while (directp->d_ino == 0); dirp->dd_ent.d_ino = directp->d_ino; (void)sprintf(dirp->dd_ent.d_name, "%.*s", sizeof (directp->d_name), directp->d_name); dirp->dd_ent.d_namlen = strlen(dirp->dd_ent.d_name); return &dirp->dd_ent; } void closedir(dirp) DIR *dirp; { (void)close(dirp->dd_fd); free(dirp); } SHAR_EOF if test 1458 -ne "`wc -c < 'directory.c'`" then echo shar: error transmitting "'directory.c'" '(should have been 1458 characters)' fi fi # end of overwriting check echo shar: extracting "'dirent.h'" '(477 characters)' if test -f 'dirent.h' then echo shar: will not over-write existing file "'dirent.h'" else cat << \SHAR_EOF > 'dirent.h' #include <sys/types.h> #define DIRBLKSIZ 1024 #define MAXNAMLEN 15 struct dirent { ino_t d_ino; char d_name[MAXNAMLEN+1]; short d_namlen; }; typedef struct _dirdesc { int dd_fd; char *dd_ptr; struct dirent dd_ent; char dd_block[DIRBLKSIZ]; } DIR; extern DIR *opendir(); extern struct dirent *readdir(); extern void rewinddir(), closedir(); /* for BSD-ish programs that think they are directly reading 'struct direct's */ #define direct dirent SHAR_EOF if test 477 -ne "`wc -c < 'dirent.h'`" then echo shar: error transmitting "'dirent.h'" '(should have been 477 characters)' fi fi # end of overwriting check # End of shell archive exit 0 -- -=] Ford [=- "The number of Unix installations (In Real Life: Mike Ditto) has grown to 10, with more expected." ford@kenobi.cts.com - The Unix Programmer's Manual, ...!sdcsvax!crash!kenobi!ford 2nd Edition, June, 1972. ditto@cbmvax.commodore.com