Bug 9351

Summary: ntfw with FTW_CHDIR and FTW_DEPTH can't back out of a tree properly giving ENOENT
Product: uClibc Reporter: John Ata <john.ata>
Component: LocalesAssignee: unassigned
Status: NEW ---    
Severity: normal CC: uclibc-cvs, vapier
Priority: P5    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:
Attachments: Change directory to the parent before processing directory

Description John Ata 2016-10-13 22:40:59 UTC
Created attachment 6756 [details]
Change directory to the parent before processing directory

When using nftw with uclibc, there appears to be a problem when using FTW_CHDIR with FTW_DEPTH regarding climbing from the descent.  After processing a directory's contents, it should change working directory back to the parent before processing the directory since the pathname is relative to the parent.  Not doing so results in ENOENT being returned when processing the directory while still being in that directory.  The following patch fixes this problem and seems to work well after testing.

===================================================================
--- uclibc/libc/misc/ftw/ftw.c  2016-09-30 17:26:34.464299069 -0400
+++ uclibc/libc/misc/ftw/ftw.c  2016-09-30 17:27:15.180005570 -0400
@@ -558,19 +558,14 @@
   --data->ftw.level;
   data->ftw.base = previous_base;

-  /* Finally, if we process depth-first report the directory.  */
-  if (result == 0 && (data->flags & FTW_DEPTH))
-    result = (*data->func) (data->dirbuf, st, FTW_DP, &data->ftw);
-
-  if (old_dir
-      && (data->flags & FTW_CHDIR)
+  if ((data->flags & FTW_CHDIR)
       && (result == 0
          || ((data->flags & FTW_ACTIONRETVAL)
              && (result != -1 && result != FTW_STOP))))
     {
       /* Change back to the parent directory.  */
       int done = 0;
-      if (old_dir->stream != NULL)
+      if (old_dir && old_dir->stream != NULL)
        if (__fchdir (dirfd (old_dir->stream)) == 0)
          done = 1;

@@ -587,6 +582,10 @@
        }
     }

+  /* Finally, if we process depth-first report the directory.  */
+  if (result == 0 && (data->flags & FTW_DEPTH))
+    result = (*data->func) (data->dirbuf, st, FTW_DP, &data->ftw);
+
   return result;
 }
Comment 1 John Ata 2016-10-13 22:47:35 UTC
Will uclibc-ng pick up from here?  I couldn't file a bug on their website.