telldir()/seekdir() confusion

Dan Nelson dnelson at allantgroup.com
Tue Jul 8 13:30:29 PDT 2003


In the last episode (Jul 08), Jp Calderone said:
> I'm trying to work out some inconsistent behavior in my app across
> platforms.  On FreeBSD, seekdir() doesn't seem to behave as I expect
> it to.  Here's a short program that demonstrates my confusion:
> 
>     off_t pos;
>     dirp = opendir(".");
>     ent = readdir(dirp);
>     pos = telldir(dirp);
>     ent = readdir(dirp);
>     seekdir(dirp, pos);
>     printf("First telldir:%d\nSecond telldir:%d\n", pos, telldir(dirp));
> 
> On other platforms, the first and second telldir() return the same
> value.  On the two FreeBSD machines I've tried it on, the first
> telldir() returns 1 and the second returns 0.
> 
>   Can anyone explain this?

Well, your first problem is that pos is a long long, but you only
printed a %d value.  Change pos to a "long" type, and you'll get the
correct result :)

First telldir:1
Second telldir:2

But your basic question still stands: why aren't they the same?

When telldir() is called, the base offset into the directory and
filecount past that offset are stored in a linked list (see the
getdirentries manpage; directory entries are read in blocks, so you
don't necessarily know the absolute offset to a particular entry).  A
cookie value is returned to the user, and that value is used to look up
the stored values when seekdir() is called later.  Each call to telldir
will return an integer one higher that the result of the previous call.  

I don't think there's any pstandard that says that telldir has to
return a seekable file offset, or that consecutive calls on the same
position must return the same value.  Think about a filesystem that
uses hashed or btree-based directories, for example; there may not be a
way to store the correct position in a single "long" value without
using a cookie like FreeBSD does.

-- 
	Dan Nelson
	dnelson at allantgroup.com


More information about the freebsd-hackers mailing list