Date: Tue, 22 Aug 2017 13:38:00 +0200 From: Nikolaus Rath <Nikolaus@rath.org> To: freebsd-fs@freebsd.org Subject: Can telldir() == 0 value be made special? Message-ID: <87bmn7kf3b.fsf@vostro.rath.org>
next in thread | raw e-mail | index | archive | help
Hello, I am trying to debug a test failure of libfuse under FreeBSD. I believe I have reduced it to the following root cause: Consider the following program: #include <stdio.h> #include <dirent.h> #include <sys/types.h> int main(void) { struct dirent *e =3D NULL; DIR *dirp; printf("opendir...\n"); dirp =3D opendir("/"); if(dirp =3D=3D NULL) { perror("opendir"); return 1; } printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("closedir..\n"); closedir(dirp); =20=20=20=20 printf("opendir...\n"); dirp =3D opendir("/"); if(dirp =3D=3D NULL) { perror("opendir"); return 1; } e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("telldir: %ld\n", telldir(dirp)); e =3D readdir(dirp); printf("readdir: %s\n", e->d_name); printf("closedir..\n"); closedir(dirp); =20=20=20=20 return 0; } Under FreeBSD, running it gives: # ./simple=20 opendir... telldir: 0 readdir: . telldir: 1 readdir: .. closedir.. opendir... readdir: . telldir: 0 readdir: .. closedir.. In other words, if telldir() is called right after opendir(), it gives an offset of zero. But if telldir() is called only after the first readdir() call, it also gives an offset of zero. My hypothesis is that FreeBSD actually just enumerates the different telldir() calls - is that correct? Now, the offsets returned by telldir() are documented to be valid only within a given *dirp, so FreeBSD isn't doing anything wrong. However, having different meanings even for an offset of zero causes problems for libfuse, because under Linux an offset of zero is guaranteed to mean "first entry". This is reflected in the definition of the fuse readdir() function which always receives an *offset* parameter that needs to have a definite value even when telldir() was never called. If zero is suddenly also a valid telldir() return value that may indicate some other position in the stream, things get complicated. Now, I think I managed to work around that by shifting all offsets by one, but that is awkward (and I may have overlooked some problems that the unit tests don't cover). So I am wondering: Is there a reason why the FreeBSD kernel could not start enumerating telldir() offsets with 1, so that 0 can always have the same meaning? Best, -Nikolaus --=20 GPG Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F =C2=BBTime flies like an arrow, fruit flies like a Banana.=C2= =AB
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?87bmn7kf3b.fsf>