From c98688068db5d766bdb707c4eafdb16daac1cf2d Mon Sep 17 00:00:00 2001 From: John Marino Date: Tue, 8 Dec 2015 23:41:22 +0100 Subject: [PATCH] ls(1): Fix sort-by-size bug For a reason that escapes me, in order to sort files by size using ls(1), one had to pass both the size sort switch (-S) and the time sort switch (-t), otherwise the -S flag would be ignored. This hacky workaround was documented in the man page as well. Let's fix this with code taken from FreeBSD. The -t and -S switches are now mutually exclusive. If someone uses them together, then the last one wins (e.g. ls -st sorts by mod. time and -ts sorts by file size) --- bin/ls/ls.1 | 13 ++++++++++--- bin/ls/ls.c | 31 +++++++++++++++++-------------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index c635641a80..153056e180 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -31,7 +31,7 @@ .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" $FreeBSD: src/bin/ls/ls.1,v 1.86 2005/02/13 22:25:09 ru Exp $ .\" -.Dd November 20, 2015 +.Dd December 8, 2015 .Dt LS 1 .Os .Sh NAME @@ -142,8 +142,8 @@ options. .It Fl R Recursively list subdirectories encountered. .It Fl S -Use the size of a file for sorting -.Pq Fl t . +Sort by size (largest file first) before sorting the operands in +lexicographical order. .It Fl T When used with the .Fl l @@ -290,6 +290,13 @@ options override each other; the last one specified determines the file time used. .Pp The +.Fl S +and +.Fl t +options override each other; the last one specified determines +the sort order used. +.Pp +The .Fl B , b , w , and .Fl q diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 604d4ad38d..147244562d 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -113,7 +113,7 @@ static int f_reversesort; /* reverse whatever sort is used */ static int f_singlecol; /* use single column output */ int f_size; /* list size in short listing */ int f_slash; /* similar to f_type, but only for dirs */ - int f_sortsize; /* Sort by size */ + int f_sizesort; /* Sort by size */ int f_sortacross; /* sort across rows, not down columns */ int f_statustime; /* use time of last mode change */ static int f_stream; /* stream the output, separate with commas */ @@ -241,8 +241,14 @@ main(int argc, char *argv[]) case 'R': f_recursive = 1; break; + /* The -t and -S options override each other. */ case 'S': - f_sortsize = 1; + f_sizesort = 1; + f_timesort = 0; + break; + case 't': + f_timesort = 1; + f_sizesort = 0; break; case 'f': f_nosort = 1; @@ -299,9 +305,6 @@ main(int argc, char *argv[]) case 'T': f_sectime = 1; break; - case 't': - f_timesort = 1; - break; case 'W': f_whiteout = 1; break; @@ -361,12 +364,12 @@ main(int argc, char *argv[]) #endif /* - * If not -F, -i, -l, -s, -S or -t options, don't require stat + * If not -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_sortsize && !f_timesort - && !f_type + if (!f_inode && !f_longform && !f_size && !f_timesort && + !f_sizesort && !f_type #ifdef COLORLS && !f_color #endif @@ -399,23 +402,23 @@ main(int argc, char *argv[]) } /* Select a sort function. */ if (f_reversesort) { - if (!f_timesort) + if (!f_timesort && !f_sizesort) sortfcn = revnamecmp; + else if (f_sizesort) + sortfcn = revsizecmp; else if (f_accesstime) sortfcn = revacccmp; - else if (f_sortsize) - sortfcn = revsizecmp; else if (f_statustime) sortfcn = revstatcmp; else /* Use modification time. */ sortfcn = revmodcmp; } else { - if (!f_timesort) + if (!f_timesort && !f_sizesort) sortfcn = namecmp; + else if (f_sizesort) + sortfcn = sizecmp; else if (f_accesstime) sortfcn = acccmp; - else if (f_sortsize) - sortfcn = sizecmp; else if (f_statustime) sortfcn = statcmp; else /* Use modification time. */ -- 2.41.0