Any thoughts on this?
Also, resending the patch with proper tabs (doh!).
--
Carlin
On Tue, Jul 05, 2016 at 10:46:04AM +1200, Carlin Bingham wrote:
> If rewinddir(3) is called before the end of the directory was reached
> with readdir(3), subsequent calls to readdir() will return entries
> cached in the buffer, so any changes to the directory from before
> rewinddir() was called will not be reflected.
>
> Example:
>
> DIR *dir = opendir("/tmp/empty");
> struct dirent *dp;
> FILE *fd;
> int i;
>
> for (i = 0; i < 2; i++) {
> dp = readdir(dir);
> printf("%s\n", dp->d_name);
> }
>
> fd = fopen("/tmp/empty/newfile", "w");
> fclose(fd);
>
> rewinddir(dir);
>
> while ((dp = readdir(dir)))
> printf("%s\n", dp->d_name);
>
>
> Outputs (where /tmp/empty is an empty directory):
>
> .
> ..
> .
> ..
>
> ie. "newfile" was created before the rewinddir() call but is not
> returned by readdir().
>
> My understanding of the spec is that it should be:
>
> IEEE Std 1003.1-2008 rewinddir
>
> "The rewinddir() function shall reset the position of the
> directory stream to which dirp refers to the beginning of the
> directory. It shall also cause the directory stream to refer to
> the current state of the corresponding directory, as a call to
> opendir() would have done. [...]"
>
>
> Possible fix:
>
Index: lib/libc/gen/rewinddir.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/rewinddir.c,v
retrieving revision 1.11
diff -u -p -u -r1.11 rewinddir.c
--- lib/libc/gen/rewinddir.c 5 Nov 2013 20:36:51 -0000 1.11
+++ lib/libc/gen/rewinddir.c 30 Aug 2016 10:46:18 -0000
@@ -35,5 +35,8 @@
void
rewinddir(DIR *dirp)
{
- seekdir(dirp, 0);
+ _MUTEX_LOCK(&dirp->dd_lock);
+ dirp->dd_loc = dirp->dd_size;
+ dirp->dd_bufpos = dirp->dd_curpos = lseek(dirp->dd_fd, 0, SEEK_SET);
+ _MUTEX_UNLOCK(&dirp->dd_lock);
}