[BusyBox] Problem with ls

Matt Kraai kraai at alumni.carnegiemellon.edu
Mon Nov 27 17:49:01 UTC 2000


On Mon, Nov 27, 2000 at 09:18:15AM -0800, Matt Kraai wrote:
> On Mon, Nov 27, 2000 at 11:57:37AM -0500, Richard June wrote:
> > Using the 0.47 version of busy box I'm having a problem, ls -aR causes
> > an infinate loop, it recurses '.'.  I know *why* it's doing this, but
> > fixing it is a little bit different, I'm not overly familiar with all of
> > the structures, nor have I completely wrapped my head around the ls
> > code. I think the spot that is broken is showdirs, any preferences on
> > *how* it should be fixed?
> 
> My preference would be to define a SPLIT_SUBDIR flag for splitdnarray
> which ignores the "." and ".." directories.  Then change the call in
> showdirs to use SPLIT_SUBDIR instead of SPLIT_DIR.

Here is a patch which implements this suggestion.  I can't compile at the
moment, so I'd appreciate any testing and/or feedback.

Matt

--- ls.c.orig	Mon Nov 27 09:27:05 2000
+++ ls.c	Mon Nov 27 09:48:13 2000
@@ -127,6 +127,7 @@
 
 #define SPLIT_DIR		0
 #define SPLIT_FILE		1
+#define SPLIT_SUBDIR	2
 
 #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
 #define TYPECHAR(mode)  ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
@@ -236,11 +237,16 @@
 }
 
 /*----------------------------------------------------------------------*/
+static int is_subdir(struct dnode *dn)
+{
+	return (S_ISDIR(dn->dstat.st_mode) && strcmp(dn->name, ".") != 0 &&
+			strcmp(dn->name, "..") != 0);
+}
+
 int countdirs(struct dnode **dn, int nfiles)
 {
 	int i, dirs;
 
-	/* count how many dirs and regular files there are */
 	if (dn==NULL || nfiles < 1) return(0);
 	dirs= 0;
 	for (i=0; i<nfiles; i++) {
@@ -249,6 +255,18 @@
 	return(dirs);
 }
 
+int countsubdirs(struct dnode **dn, int nfiles)
+{
+	int i, subdirs;
+
+	if (dn == NULL || nfiles < 1) return 0;
+	subdirs = 0;
+	for (i = 0; i < nfiles; i++)
+		if (is_subdir(dn[i]))
+			subdirs++;
+	return subdirs;
+}
+
 int countfiles(struct dnode **dnp)
 {
 	int nfiles;
@@ -296,9 +314,13 @@
 	if (dn==NULL || nfiles < 1) return(NULL);
 
 	/* count how many dirs and regular files there are */
-	dncnt= countdirs(dn, nfiles); /* assume we are looking for dirs */
-	if (which != SPLIT_DIR)
-		dncnt= nfiles - dncnt;  /* looking for files */
+	if (which == SPLIT_SUBDIR)
+		dncnt = countsubdirs(dn, nfiles);
+	else {
+		dncnt= countdirs(dn, nfiles); /* assume we are looking for dirs */
+		if (which == SPLIT_FILE)
+			dncnt= nfiles - dncnt;  /* looking for files */
+	}
 
 	/* allocate a file array and a dir array */
 	dnp= dnalloc(dncnt);
@@ -309,6 +331,10 @@
 			if (S_ISDIR(dn[i]->dstat.st_mode)) {
 				dnp[d++]= dn[i];
 			}  /* else skip the file */
+		} else if (which == SPLIT_SUBDIR) {
+			if (is_subdir(dn[i])) {
+				dnp[d++]= dn[i];
+			}  /* else skip the file or dir */
 		} else {
 			if (!(S_ISDIR(dn[i]->dstat.st_mode))) {
 				dnp[d++]= dn[i];
@@ -455,8 +481,8 @@
 #ifdef BB_FEATURE_LS_RECURSIVE
 			if (disp_opts & DISP_RECURSIVE) {
 				/* recursive- list the sub-dirs */
-				dnd= splitdnarray(subdnp, nfiles, SPLIT_DIR);
-				dndirs= countdirs(subdnp, nfiles);
+				dnd= splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
+				dndirs= countsubdirs(subdnp, nfiles);
 				if (dndirs > 0) {
 #ifdef BB_FEATURE_LS_SORTFILES
 					shellsort(dnd, dndirs);





More information about the busybox mailing list