bin/81837: Sort by directories first option for ls(1)

Mathieu Arnold mat at FreeBSD.org
Fri Jun 3 13:10:04 GMT 2005


>Number:         81837
>Category:       bin
>Synopsis:       Sort by directories first option for ls(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 03 13:10:02 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Mathieu Arnold
>Release:        FreeBSD 4.8-RELEASE i386
>Organization:
Absolight
>Environment:
System: FreeBSD aragorn.in.absolight.net 4.8-RELEASE FreeBSD 4.8-RELEASE #0: Wed Sep 3 12:54:37 CEST 2003 root at aragorn.reaumur.absolight.net:/usr/src/sys/compile/ARAGORN i386

>Description:

This allow to have your directories sorted before your files, so that you don't
have to look for which are files and which are directories :
$ ls -l /usr/src/
total 156
-rw-r--r--    1 root  wheel   6189  8 jan  2004 COPYRIGHT
-rw-r--r--    1 root  wheel   7736  1 aoû  2003 MAINTAINERS
-rw-r--r--    1 root  wheel   7822  7 nov  2003 Makefile
-rw-r--r--    1 root  wheel  26361 18 déc  2003 Makefile.inc1
-rw-r--r--    1 root  wheel   2749  8 mar  2003 README
-rw-r--r--    1 root  wheel  60761 25 avr 12:47 UPDATING
drwxr-xr-x   37 root  wheel   1024  4 nov  2004 bin
drwxr-xr-x   51 root  wheel   1024  4 nov  2004 contrib
drwxr-xr-x    5 root  wheel    512 22 mai  2004 crypto
drwxr-xr-x   19 root  wheel   1536  4 nov  2004 etc
drwxr-xr-x   13 root  wheel    512 22 mai  2004 games
drwxr-xr-x    4 root  wheel    512 22 mai  2004 gnu
drwxr-xr-x    6 root  wheel   2048  4 nov  2004 include
drwxr-xr-x    8 root  wheel    512  4 nov  2004 kerberos5
drwxr-xr-x   68 root  wheel   1536  4 nov  2004 lib
drwxr-xr-x   35 root  wheel   1024  4 nov  2004 libexec
drwxr-xr-x   12 root  wheel    512  4 nov  2004 release
drwxr-xr-x    4 root  wheel    512 22 mai  2004 rescue
drwxr-xr-x   93 root  wheel   2048  4 nov  2004 sbin
drwxr-xr-x    6 root  wheel    512  4 nov  2004 secure
drwxr-xr-x   24 root  wheel    512  4 nov  2004 share
drwxr-xr-x   55 root  wheel   1024  4 nov  2004 sys
drwxr-xr-x   10 root  wheel    512  4 nov  2004 tools
drwxr-xr-x  217 root  wheel   3584  4 nov  2004 usr.bin
drwxr-xr-x  177 root  wheel   3584  4 nov  2004 usr.sbin
and :
$ ls -lD /usr/src/
total 156
drwxr-xr-x   37 root  wheel   1024  4 nov  2004 bin
drwxr-xr-x   51 root  wheel   1024  4 nov  2004 contrib
drwxr-xr-x    5 root  wheel    512 22 mai  2004 crypto
drwxr-xr-x   19 root  wheel   1536  4 nov  2004 etc
drwxr-xr-x   13 root  wheel    512 22 mai  2004 games
drwxr-xr-x    4 root  wheel    512 22 mai  2004 gnu
drwxr-xr-x    6 root  wheel   2048  4 nov  2004 include
drwxr-xr-x    8 root  wheel    512  4 nov  2004 kerberos5
drwxr-xr-x   68 root  wheel   1536  4 nov  2004 lib
drwxr-xr-x   35 root  wheel   1024  4 nov  2004 libexec
drwxr-xr-x   12 root  wheel    512  4 nov  2004 release
drwxr-xr-x    4 root  wheel    512 22 mai  2004 rescue
drwxr-xr-x   93 root  wheel   2048  4 nov  2004 sbin
drwxr-xr-x    6 root  wheel    512  4 nov  2004 secure
drwxr-xr-x   24 root  wheel    512  4 nov  2004 share
drwxr-xr-x   55 root  wheel   1024  4 nov  2004 sys
drwxr-xr-x   10 root  wheel    512  4 nov  2004 tools
drwxr-xr-x  217 root  wheel   3584  4 nov  2004 usr.bin
drwxr-xr-x  177 root  wheel   3584  4 nov  2004 usr.sbin
-rw-r--r--    1 root  wheel   6189  8 jan  2004 COPYRIGHT
-rw-r--r--    1 root  wheel   7736  1 aoû  2003 MAINTAINERS
-rw-r--r--    1 root  wheel   7822  7 nov  2003 Makefile
-rw-r--r--    1 root  wheel  26361 18 déc  2003 Makefile.inc1
-rw-r--r--    1 root  wheel   2749  8 mar  2003 README
-rw-r--r--    1 root  wheel  60761 25 avr 12:47 UPDATING


>How-To-Repeat:
>Fix:

that's the current patch of today, it's also in mat_ls branch in perforce.

--- current-ls-D.diff begins here ---
--- //depot/vendor/freebsd/src/bin/ls/cmp.c	2005/06/03 11:37:01
+++ //depot/user/mat/src/ls/cmp.c	2005/06/03 13:06:06
@@ -157,3 +157,27 @@
 
 	return (sizecmp(b, a));
 }
+
+#define IS_FTS_DIR(x) ((x)->fts_info == FTS_D \
+		       || (x)->fts_info == FTS_DOT \
+		       || (x)->fts_info == FTS_DC \
+		       || (x)->fts_info == FTS_DNR \
+		       || (x)->fts_info == FTS_DP)
+
+int
+dirfcmp(const FTSENT *a, const FTSENT *b)
+{
+
+	if ((IS_FTS_DIR(a) && IS_FTS_DIR(b)) || (!IS_FTS_DIR(a) && !IS_FTS_DIR(b)))
+		return (real_sortfcn(a, b));
+	return (IS_FTS_DIR(a) ? -1 : 1);
+}
+
+int
+revdirfcmp(const FTSENT *a, const FTSENT *b)
+{
+
+	if ((IS_FTS_DIR(a) && IS_FTS_DIR(b)) || (!IS_FTS_DIR(a) && !IS_FTS_DIR(b)))
+		return (real_sortfcn(a, b));
+	return (IS_FTS_DIR(b) ? -1 : 1);
+}
--- //depot/vendor/freebsd/src/bin/ls/extern.h	2005/06/03 11:37:01
+++ //depot/user/mat/src/ls/extern.h	2005/06/03 12:52:48
@@ -40,6 +40,11 @@
 int	 revstatcmp(const FTSENT *, const FTSENT *);
 int	 sizecmp(const FTSENT *, const FTSENT *);
 int	 revsizecmp(const FTSENT *, const FTSENT *);
+int	 dirfcmp(const FTSENT *, const FTSENT *);
+int	 revdirfcmp(const FTSENT *, const FTSENT *);
+
+/* save the real sortfcn when sorting directories first */
+int (*real_sortfcn)(const FTSENT *, const FTSENT *);
 
 void	 printcol(const DISPLAY *);
 void	 printlong(const DISPLAY *);
--- //depot/vendor/freebsd/src/bin/ls/ls.1	2005/06/03 12:37:04
+++ //depot/user/mat/src/ls/ls.1	2005/06/03 12:52:48
@@ -83,6 +83,8 @@
 is the numeric value of the character in octal.
 .It Fl C
 Force multi-column output; this is the default when output is to a terminal.
+.It Fl D
+Sorts directories first
 .It Fl F
 Display a slash
 .Pq Ql /
--- //depot/vendor/freebsd/src/bin/ls/ls.c	2005/06/03 11:37:01
+++ //depot/user/mat/src/ls/ls.c	2005/06/03 12:52:48
@@ -104,6 +104,7 @@
 
 /* flags */
        int f_accesstime;	/* use time of last access */
+static int f_dirfirstsort;	/* put directories first */
        int f_flags;		/* show flags associated with a file */
        int f_humanval;		/* show human-readable file sizes */
        int f_inode;		/* print inode */
@@ -181,7 +182,7 @@
 
 	fts_options = FTS_PHYSICAL;
  	while ((ch = getopt(argc, argv,
-	    "1ABCFGHLPRSTWZabcdfghiklmnopqrstuwx")) != -1) {
+	    "1ABCDFGHLPRSTWZabcdfghiklmnopqrstuwx")) != -1) {
 		switch (ch) {
 		/*
 		 * The -1, -C, -x and -l options all override each other so
@@ -200,6 +201,9 @@
 		case 'C':
 			f_sortacross = f_longform = f_singlecol = 0;
 			break;
+		case 'D':
+			f_dirfirstsort = 1;
+			break;
 		case 'l':
 			f_longform = 1;
 			f_singlecol = 0;
@@ -364,12 +368,12 @@
 #endif
 
 	/*
-	 * If not -F, -i, -l, -s, -S or -t options, don't require stat
+	 * If not -D, -F, -i, -l, -s, -S or -t options, don't require stat
 	 * information, unless in color mode in which case we do
 	 * need this to determine which colors to display.
 	 */
 	if (!f_inode && !f_longform && !f_size && !f_timesort &&
-	    !f_sizesort && !f_type
+	    !f_sizesort && !f_type && !!f_dirfirstsort
 #ifdef COLORLS
 	    && !f_color
 #endif
@@ -412,6 +416,11 @@
 			sortfcn = revsizecmp;
 		else		/* Use modification time. */
 			sortfcn = revmodcmp;
+		if (f_dirfirstsort) {
+			real_sortfcn = sortfcn;
+			sortfcn = revdirfcmp;
+		}
+
 	} else {
 		if (!f_timesort && !f_sizesort)
 			sortfcn = namecmp;
@@ -423,6 +432,11 @@
 			sortfcn = sizecmp;
 		else		/* Use modification time. */
 			sortfcn = modcmp;
+		if (f_dirfirstsort) {
+			real_sortfcn = sortfcn;
+			sortfcn = dirfcmp;
+		}
+
 	}
 
 	/* Select a print function. */
--- //depot/vendor/freebsd/src/bin/ls/util.c	2005/06/03 11:37:01
+++ //depot/user/mat/src/ls/util.c	2005/06/03 12:52:48
@@ -222,9 +222,9 @@
 {
 	(void)fprintf(stderr,
 #ifdef COLORLS
-	"usage: ls [-ABCFGHLPRSTWZabcdfghiklmnopqrstuwx1]"
+	"usage: ls [-ABCDFGHLPRSTWZabcdfghiklmnopqrstuwx1]"
 #else
-	"usage: ls [-ABCFHLPRSTWZabcdfghiklmnopqrstuwx1]"
+	"usage: ls [-ABCDFHLPRSTWZabcdfghiklmnopqrstuwx1]"
 #endif
 		      " [file ...]\n");
 	exit(1);
--- current-ls-D.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list