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);
 }

Reply via email to