ko...@comcast.net wrote: ... > To find out what was happening, I took all of the gnulib code out of > the picture by using the i686-pc-mingw32-gcc compiler to directly > compile a simple test program, and found that the mingw opendir > routine sets the dd_handle to -1 itself. > > #include <dirent.h> > #include <errno.h> > #include <stdio.h> > int main(int argc, char **argv) > { > char **path, *paths[] = { ".", "m4", "lib", NULL }; > for (path = paths; *path; path++) > { > DIR *d = opendir(*path); > printf("%p, %ld, %d: (%s) %s\n", > d, d->dd_handle, errno, d->dd_name, *path); > } > return 0; > } > > Z:\home\kodis\fts> a > 00116A68, -1, 0: (Z:\home\kodis\fts\*) . > 00116CB8, -1, 0: (Z:\home\kodis\fts\m4\*) m4 > 00116F08, -1, 0: (Z:\home\kodis\fts\lib\*) lib > > It looks like the file descriptor returned by dirfd is used mainly by > fts_safe_changedir to allow fts to work correctly even when parts of > the file system are changed while being traversed. I wonder if a > fallback to the less robust changing directory by name would be the > appropriate fix here?
Trying to do without a file descriptor looks like it'd add too much complexity in already-hairy code. Not worth it just for mingw. If you're interested in pursuing it, I'd suggest trying harder to get a file descriptor. I.e., on mingw, if dirfd returns -1, resort to calling openat or open on the directory name, similar to what's already done above in this code: # define __opendir2(file, flag) \ ( ! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \ ? opendirat(sp->fts_cwd_fd, file) \ : opendir(file)) #endif if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) { Sure, it'll open up a window (between opendir and the last-resort openat/open call) of vulnerability, but at least it'll compile and work in a non-adversarial environment. If you write the patch, be sure to mention that in a comment.