home *** CD-ROM | disk | FTP | other *** search
- echo 'directory.3':
- sed 's/^X//' >'directory.3' <<'!'
- X.TH DIRECTORY 3 imported
- X.DA 9 Oct 1985
- X.SH NAME
- Xopendir, readdir, telldir, seekdir, rewinddir, closedir \- high-level directory operations
- X.SH SYNOPSIS
- X.B #include <sys/types.h>
- X.br
- X.B #include <ndir.h>
- X.PP
- X.SM
- X.B DIR
- X.B *opendir(filename)
- X.br
- X.B char *filename;
- X.PP
- X.SM
- X.B struct direct
- X.B *readdir(dirp)
- X.br
- X.B DIR *dirp;
- X.PP
- X.SM
- X.B long
- X.B telldir(dirp)
- X.br
- X.B DIR *dirp;
- X.PP
- X.SM
- X.B seekdir(dirp, loc)
- X.br
- X.B DIR *dirp;
- X.br
- X.B long loc;
- X.PP
- X.SM
- X.B rewinddir(dirp)
- X.br
- X.B DIR *dirp;
- X.PP
- X.SM
- X.B closedir(dirp)
- X.br
- X.B DIR *dirp;
- X.SH DESCRIPTION
- XThis library provides high-level primitives for directory scanning,
- Xsimilar to those available for 4.2BSD's (very different) directory system.
- X.\"The purpose of this library is to simulate
- X.\"the new flexible length directory names of 4.2bsd UNIX
- X.\"on top of the old directory structure of v7.
- XIt incidentally provides easy portability to and from 4.2BSD (insofar
- Xas such portability is not compromised by other 4.2/VAX dependencies).
- X.\"It allows programs to be converted immediately
- X.\"to the new directory access interface,
- X.\"so that they need only be relinked
- X.\"when moved to 4.2bsd.
- X.\"It is obtained with the loader option
- X.\".BR \-lndir .
- X.PP
- X.I Opendir
- Xopens the directory named by
- X.I filename
- Xand associates a
- X.I directory stream
- Xwith it.
- X.I Opendir
- Xreturns a pointer to be used to identify the
- X.I directory stream
- Xin subsequent operations.
- XThe pointer
- X.SM
- X.B NULL
- Xis returned if
- X.I filename
- Xcannot be accessed or is not a directory.
- X.PP
- X.I Readdir
- Xreturns a pointer to the next directory entry.
- XIt returns
- X.B NULL
- Xupon reaching the end of the directory or detecting
- Xan invalid
- X.I seekdir
- Xoperation.
- X.PP
- X.I Telldir
- Xreturns the current location associated with the named
- X.I directory stream.
- X.PP
- X.I Seekdir
- Xsets the position of the next
- X.I readdir
- Xoperation on the
- X.I directory stream.
- XThe new position reverts to the one associated with the
- X.I directory stream
- Xwhen the
- X.I telldir
- Xoperation was performed.
- XValues returned by
- X.I telldir
- Xare good only for the lifetime of the DIR pointer from
- Xwhich they are derived.
- XIf the directory is closed and then reopened,
- Xthe
- X.I telldir
- Xvalue may be invalidated
- Xdue to undetected directory compaction in 4.2BSD.
- XIt is safe to use a previous
- X.I telldir
- Xvalue immediately after a call to
- X.I opendir
- Xand before any calls to
- X.I readdir.
- X.PP
- X.I Rewinddir
- Xresets the position of the named
- X.I directory stream
- Xto the beginning of the directory.
- X.PP
- X.I Closedir
- Xcauses the named
- X.I directory stream
- Xto be closed,
- Xand the structure associated with the DIR pointer to be freed.
- X.PP
- XA
- X.I direct
- Xstructure is as follows:
- X.PP
- X.RS
- X.nf
- Xstruct direct {
- X /* unsigned */ long d_ino; /* inode number of entry */
- X unsigned short d_reclen; /* length of this record */
- X unsigned short d_namlen; /* length of string in d_name */
- X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
- X};
- X.fi
- X.RE
- X.PP
- XThe
- X.I d_reclen
- Xfield is meaningless in non-4.2BSD systems and should be ignored.
- XThe use of a
- X.I long
- Xfor
- X.I d_ino
- Xis also a 4.2BSDism;
- X.I ino_t
- X(see
- X.IR types (5))
- Xshould be used elsewhere.
- XThe macro
- X.I DIRSIZ(dp)
- Xgives the minimum memory size needed to hold the
- X.I direct
- Xvalue pointed to by
- X.IR dp ,
- Xwith the minimum necessary allocation for
- X.IR d_name .
- X.PP
- XThe preferred way to search the current directory for entry ``name'' is:
- X.PP
- X.RS
- X.nf
- X len = strlen(name);
- X dirp = opendir(".");
- X if (dirp == NULL) {
- X fprintf(stderr, "%s: can't read directory .\\n", argv[0]);
- X return NOT_FOUND;
- X }
- X while ((dp = readdir(dirp)) != NULL)
- X if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
- X closedir(dirp);
- X return FOUND;
- X }
- X closedir(dirp);
- X return NOT_FOUND;
- X.RE
- X.\".SH LINKING
- X.\"This library is accessed by specifying ``-lndir'' as the
- X.\"last argument to the compile line, e.g.:
- X.\".PP
- X.\" cc -I/usr/include/ndir -o prog prog.c -lndir
- X.SH "SEE ALSO"
- Xopen(2),
- Xclose(2),
- Xread(2),
- Xlseek(2)
- X.SH HISTORY
- XWritten by
- XKirk McKusick at Berkeley (ucbvax!mckusick).
- XMiscellaneous bug fixes from elsewhere.
- XThe size of the data structure has been decreased to avoid excessive
- Xspace waste under V7 (where filenames are 14 characters at most).
- XFor obscure historical reasons, the include file is also available
- Xas
- X.IR <ndir/sys/dir.h> .
- XThe Berkeley version lived in a separate library (\fI\-lndir\fR),
- Xwhereas ours is
- Xpart of the C library, although the separate library is retained to
- Xmaximize compatibility.
- X.PP
- XThis manual page has been substantially rewritten to be informative in
- Xthe absence of a 4.2BSD manual.
- X.SH BUGS
- XThe
- X.I DIRSIZ
- Xmacro actually wastes a bit of space due to some padding requirements
- Xthat are an artifact of 4.2BSD.
- X.PP
- XThe returned value of
- X.I readdir
- Xpoints to a static area that will be overwritten by subsequent calls.
- X.PP
- XThere are some unfortunate name conflicts with the \fIreal\fR V7
- Xdirectory structure definitions.
- !
- echo 'dir.h':
- sed 's/^X//' >'dir.h' <<'!'
- X/* dir.h 4.4 82/07/25 */
- X
- X/*
- X * A directory consists of some number of blocks of DIRBLKSIZ
- X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
- X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
- X *
- X * Each DIRBLKSIZ byte block contains some number of directory entry
- X * structures, which are of variable length. Each directory entry has
- X * a struct direct at the front of it, containing its inode number,
- X * the length of the entry, and the length of the name contained in
- X * the entry. These are followed by the name padded to a 4 byte boundary
- X * with null bytes. All names are guaranteed null terminated.
- X * The maximum length of a name in a directory is MAXNAMLEN.
- X *
- X * The macro DIRSIZ(dp) gives the amount of space required to represent
- X * a directory entry. Free space in a directory is represented by
- X * entries which have dp->d_reclen >= DIRSIZ(dp). All DIRBLKSIZ bytes
- X * in a directory block are claimed by the directory entries. This
- X * usually results in the last entry in a directory having a large
- X * dp->d_reclen. When entries are deleted from a directory, the
- X * space is returned to the previous entry in the same directory
- X * block by increasing its dp->d_reclen. If the first entry of
- X * a directory block is free, then its dp->d_ino is set to 0.
- X * Entries other than the first in a directory do not normally have
- X * dp->d_ino set to 0.
- X */
- X#define DIRBLKSIZ 512
- X#ifdef VMUNIX
- X#define MAXNAMLEN 255
- X#else
- X#define MAXNAMLEN 14
- X#endif
- X
- Xstruct direct {
- X /* unsigned */ long d_ino; /* inode number of entry */
- X unsigned short d_reclen; /* length of this record */
- X unsigned short d_namlen; /* length of string in d_name */
- X char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
- X};
- X
- X/*
- X * The DIRSIZ macro gives the minimum record length which will hold
- X * the directory entry. This requires the amount of space in struct direct
- X * without the d_name field, plus enough space for the name with a terminating
- X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- X */
- X#undef DIRSIZ
- X#define DIRSIZ(dp) \
- X ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
- X
- X#ifndef KERNEL
- X/*
- X * Definitions for library routines operating on directories.
- X */
- Xtypedef struct _dirdesc {
- X int dd_fd;
- X long dd_loc;
- X long dd_size;
- X char dd_buf[DIRBLKSIZ];
- X} DIR;
- X#ifndef NULL
- X#define NULL 0
- X#endif
- Xextern DIR *opendir();
- Xextern struct direct *readdir();
- Xextern long telldir();
- X#ifdef void
- Xextern void seekdir();
- Xextern void closedir();
- X#endif
- X#define rewinddir(dirp) seekdir((dirp), (long)0)
- X#endif KERNEL
- !
- echo 'makefile':
- sed 's/^X//' >'makefile' <<'!'
- XDIR = closedir.o opendir.o readdir.o seekdir.o telldir.o
- XCFLAGS=-O -I. -Dvoid=int
- XDEST=..
- X
- Xall: $(DIR)
- X
- Xmv: $(DIR)
- X mv $(DIR) $(DEST)
- X
- Xcpif: dir.h
- X cp dir.h /usr/include/ndir.h
- X
- Xclean:
- X rm -f *.o
- !
- echo 'closedir.c':
- sed 's/^X//' >'closedir.c' <<'!'
- Xstatic char sccsid[] = "@(#)closedir.c 4.2 3/10/82";
- X
- X#include <sys/types.h>
- X#include <dir.h>
- X
- X/*
- X * close a directory.
- X */
- Xvoid
- Xclosedir(dirp)
- X register DIR *dirp;
- X{
- X close(dirp->dd_fd);
- X dirp->dd_fd = -1;
- X dirp->dd_loc = 0;
- X free((char *)dirp);
- X}
- !
- echo 'opendir.c':
- sed 's/^X//' >'opendir.c' <<'!'
- X/* Copyright (c) 1982 Regents of the University of California */
- X
- Xstatic char sccsid[] = "@(#)opendir.c 4.4 11/12/82";
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <dir.h>
- X
- X/*
- X * open a directory.
- X */
- XDIR *
- Xopendir(name)
- X char *name;
- X{
- X register DIR *dirp;
- X register int fd;
- X struct stat statbuf;
- X char *malloc();
- X
- X if ((fd = open(name, 0)) == -1)
- X return NULL;
- X if (fstat(fd, &statbuf) == -1 || !(statbuf.st_mode & S_IFDIR)) {
- X close(fd);
- X return NULL;
- X }
- X if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
- X close (fd);
- X return NULL;
- X }
- X dirp->dd_fd = fd;
- X dirp->dd_loc = 0;
- X dirp->dd_size = 0; /* so that telldir will work before readdir */
- X return dirp;
- X}
- !
- echo 'readdir.c':
- sed 's/^X//' >'readdir.c' <<'!'
- X/* Copyright (c) 1982 Regents of the University of California */
- X
- Xstatic char sccsid[] = "@(#)readdir.c 4.3 8/8/82";
- X
- X#include <sys/types.h>
- X#include <dir.h>
- X
- X/*
- X * read an old stlye directory entry and present it as a new one
- X */
- X#define ODIRSIZ 14
- X
- Xstruct olddirect {
- X ino_t od_ino;
- X char od_name[ODIRSIZ];
- X};
- X
- X/*
- X * get next entry in a directory.
- X */
- Xstruct direct *
- Xreaddir(dirp)
- X register DIR *dirp;
- X{
- X register struct olddirect *dp;
- X static struct direct dir;
- X
- X for (;;) {
- X if (dirp->dd_loc == 0) {
- X dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf,
- X DIRBLKSIZ);
- X if (dirp->dd_size <= 0) {
- X dirp->dd_size = 0;
- X return NULL;
- X }
- X }
- X if (dirp->dd_loc >= dirp->dd_size) {
- X dirp->dd_loc = 0;
- X continue;
- X }
- X dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
- X dirp->dd_loc += sizeof(struct olddirect);
- X if (dp->od_ino == 0)
- X continue;
- X dir.d_ino = dp->od_ino;
- X strncpy(dir.d_name, dp->od_name, ODIRSIZ);
- X dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
- X dir.d_namlen = strlen(dir.d_name);
- X dir.d_reclen = DIRBLKSIZ;
- X return (&dir);
- X }
- X}
- !
- echo 'seekdir.c':
- sed 's/^X//' >'seekdir.c' <<'!'
- Xstatic char sccsid[] = "@(#)seekdir.c 4.9 3/25/83";
- X
- X#include <sys/param.h>
- X#include <dir.h>
- X
- X/*
- X * seek to an entry in a directory.
- X * Only values returned by "telldir" should be passed to seekdir.
- X */
- Xvoid
- Xseekdir(dirp, loc)
- X register DIR *dirp;
- X long loc;
- X{
- X long curloc, base, offset;
- X struct direct *dp;
- X extern long lseek();
- X
- X curloc = telldir(dirp);
- X if (loc == curloc)
- X return;
- X base = loc & ~(DIRBLKSIZ - 1);
- X offset = loc & (DIRBLKSIZ - 1);
- X (void) lseek(dirp->dd_fd, base, 0);
- X dirp->dd_size = 0;
- X dirp->dd_loc = 0;
- X while (dirp->dd_loc < offset) {
- X dp = readdir(dirp);
- X if (dp == NULL)
- X return;
- X }
- X}
- !
- echo 'telldir.c':
- sed 's/^X//' >'telldir.c' <<'!'
- Xstatic char sccsid[] = "@(#)telldir.c 4.1 2/21/82";
- X
- X#include <sys/types.h>
- X#include <dir.h>
- X
- X/*
- X * return a pointer into a directory
- X */
- Xlong
- Xtelldir(dirp)
- X DIR *dirp;
- X{
- X long lseek();
- X
- X return (lseek(dirp->dd_fd, 0L, 1) - dirp->dd_size + dirp->dd_loc);
- X}
- !
- echo done
-