[prev in list] [next in list] [prev in thread] [next in thread] 

List:       busybox
Subject:    2 bugs and a patch
From:       Dan Moinescu <dan () moinescu ! net>
Date:       2012-08-22 14:46:23
Message-ID: CAKkLDw5TUW0+V12uKmUWEcZKXz1q9MUMcvb9WEdPjB-8AZ=6dA () mail ! gmail ! com
[Download RAW message or body]

All,


I have 2 (related) bugs to report in the find function. Here they are:

1) -depth cancels out -xdev: when -depth is used, files on other file
systems are shown even though they shouldn't be.
Here's the output on my system, where /media/linux2/ is a mount point
(all examples use BusyBox v1.20.2):

dan@r2d2:~/busybox-1.20.2$ ./busybox find /media/ -depth -xdev |tail -n6
/media/linux2/stuff/CentOS-6.2-x86_64-LiveCD.iso
/media/linux2/stuff
/media/linux2
/media/.directory
/media/.hidden
/media/

The output is incorrect - no files under /media/linux2 should be shown.

2) In certain circumstances, -mindepth also cancels out -xdev. This
happens when the depth of the mount point is less then the mindepth
argument
Here's the output on my system again:

dan@r2d2~/busybox-1.20.2$ ./busybox find /media/ -mindepth 1 -xdev
/media/.hal-mtab
/media/linux2
/media/.directory
/media/.hidden

This is correct (mindepth 1, the depth of linux2 relative to /media is
also 1). But with a higher mindepth argument the output is incorrect:

dan@r2s2:~/busybox-1.20.2$ ./busybox find /media/ -mindepth 2 -xdev
/media/linux2/stuff
/media/linux2/lost+found


The attached patch solves these problems. It basically does 3 things
(all in function fileAction in findutils/find.c):
* moves the xdev-related checks to the beginning of the function (from
the very end)
* applies the xdev checks to all files (not just to directories)
* if -xdev is present, tests if each directory is a mount point (if it
is, it is processed but not descended into)

All the best,
Dan.

["find.c.patch" (text/x-patch)]

*** findutils/find.c	2012-06-26 16:35:45.000000000 +0300
--- /home/dan/find.c	2012-08-20 17:30:55.000000000 +0300
***************
*** 728,742 ****
  		int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM))
  {
  	int r;
  
  #if ENABLE_FEATURE_FIND_MAXDEPTH
  	if (depth < G.minmaxdepth[0])
! 		return TRUE; /* skip this, continue recursing */
  	if (depth > G.minmaxdepth[1])
  		return SKIP; /* stop recursing */
  #endif
  
! 	r = exec_actions(G.actions, fileName, statbuf);
  	/* Had no explicit -print[0] or -exec? then print */
  	if ((r & TRUE) && G.need_print)
  		puts(fileName);
--- 728,781 ----
  		int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM))
  {
  	int r;
+     int xdev_ok=1;
+     int is_xdev_boundary=0;
  
+ #if ENABLE_FEATURE_FIND_XDEV
+     if (G.xdev_count) {
+         int i;
+         struct stat st_parent;
+         int fnameLen;
+         char* parentName;
+         for (i = 0; i < G.xdev_count; i++) {
+             if (G.xdev_dev[i] == statbuf->st_dev)
+                 goto found;
+         }
+         xdev_ok=0;
+         if (S_ISDIR(statbuf->st_mode)) {
+             /* this directory is on a different file system. Let's see if it's a \
mount point */ +             /* code for testing mountpoint-ness adapted from \
mountpoint.c */ +             fnameLen = strlen(fileName);
+             parentName = malloc(fnameLen+4);
+             snprintf(parentName, fnameLen+4, "%s/..", fileName);
+ 
+             if (stat(parentName, &st_parent) == 0) { /* XXX should we use lstat \
here? */ +                 int is_mpoint = (statbuf->st_dev != st_parent.st_dev) || \
(statbuf->st_dev == st_parent.st_dev && statbuf->st_ino == st_parent.st_ino); +       \
if(is_mpoint) /* let's see if the parent is on the original partition */ +            \
{ +                     for (i = 0; i < G.xdev_count; i++) {
+                         if (G.xdev_dev[i] == st_parent.st_dev)
+                         {
+                             is_xdev_boundary=1;
+                             break;
+                         }
+                     }
+                 }
+             }
+             free(parentName);
+ found: ;
+         }
+     }
+ #endif
  #if ENABLE_FEATURE_FIND_MAXDEPTH
  	if (depth < G.minmaxdepth[0])
! 		return xdev_ok?TRUE:SKIP; /* skip this, continue recursing subject to xdev \
restrictions */  if (depth > G.minmaxdepth[1])
  		return SKIP; /* stop recursing */
  #endif
  
!     /* if xdev_ok==0, allow exec_actions only if it's a mount point */
! 	r = (xdev_ok || is_xdev_boundary)? exec_actions(G.actions, fileName, statbuf) : \
FALSE;  /* Had no explicit -print[0] or -exec? then print */
  	if ((r & TRUE) && G.need_print)
  		puts(fileName);
***************
*** 750,766 ****
  #if ENABLE_FEATURE_FIND_XDEV
  	/* -xdev stops on mountpoints, but AFTER mountpoit itself
  	 * is processed as usual */
! 	if (S_ISDIR(statbuf->st_mode)) {
! 		if (G.xdev_count) {
! 			int i;
! 			for (i = 0; i < G.xdev_count; i++) {
! 				if (G.xdev_dev[i] == statbuf->st_dev)
! 					goto found;
! 			}
! 			return SKIP;
!  found: ;
! 		}
! 	}
  #endif
  
  	/* Cannot return 0: our caller, recursive_action(),
--- 789,795 ----
  #if ENABLE_FEATURE_FIND_XDEV
  	/* -xdev stops on mountpoints, but AFTER mountpoit itself
  	 * is processed as usual */
! 	if (!xdev_ok) return SKIP;
  #endif
  
  	/* Cannot return 0: our caller, recursive_action(),



_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic