[unix-pc.sources] What's this dirent.h nonsense?

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