|
|
researchv10 Norman
/* Copyright (c) 1982 Regents of the University of California
* and modified by pjw in 1987 */
#include "ndir.h"
/*
* seek to an entry in a directory.
*
* offset `told' is interpreted in a non-obvious way:
* telldir computes it as dd_offset*DIRBLKSIZ + dd_loc
* dd_loc is the byte offset into the current dd_buf contents;
* dd_offset is the number of times dirread(fd, buf, DIRBLKSIZ)
* must be called to reproduce the same buffer.
*
* Why not just use lseek? Because told isn't a seek offset,
* and cannot conveniently be turned into one: the byte count
* in dd_loc is unrelated to the seek offset required to reach
* lseek(fd, 0L, 1)+dd_loc, because the seek offset refers to the raw
* directory, but dirread has reformatted the data.
* One might let dd_offset be the seek offset to the the beginning
* of dd_buf, compute told the same way, and let seekdir become
* lseek(fd, told/DIRBLKSIZ, 0); dirp->dd_loc = told%DIRBLKSIZ;
* but a somewhat strident prior implementor worries that this unfairly
* constrains the size of directories. This is probably a silly worry
* (will any real system have directories a megabyte long?) but it
* doesn't matter much except in programs that use seekdir a lot.
*/
void
seekdir(dirp, told)
register DIR *dirp;
long told;
{ long offset;
offset = told / DIRBLKSIZ;
dirp->dd_loc = told % DIRBLKSIZ;
if (offset < dirp->dd_offset)
lseek(dirp->dd_fd, dirp->dd_offset = 0L, 0);
if(offset > dirp->dd_offset) {
do {
dirp->dd_size = dirread(dirp->dd_fd, dirp->dd_buf,
DIRBLKSIZ);
if(dirp->dd_size < 0)
dirp->dd_size = pdirread(dirp->dd_fd,
dirp->dd_buf, DIRBLKSIZ);
}
while(++dirp->dd_offset < offset);
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.