summaryrefslogtreecommitdiffstats
path: root/bin/ls
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
committerobrien <obrien@FreeBSD.org>2013-02-08 16:10:16 +0000
commit3028e3f8aba938dfd0bf9fda987b8a72140b8027 (patch)
treeb2f038222ff8a70f687652441df00d2b564c8abe /bin/ls
parent952a6d5a7cd3d3f9007acfa06805262fc04a105f (diff)
parent1d08d5f677c1dfa810e381073590adbae19cc69f (diff)
downloadFreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.zip
FreeBSD-src-3028e3f8aba938dfd0bf9fda987b8a72140b8027.tar.gz
Sync with HEAD.
Diffstat (limited to 'bin/ls')
-rw-r--r--bin/ls/cmp.c20
-rw-r--r--bin/ls/extern.h12
-rw-r--r--bin/ls/ls.172
-rw-r--r--bin/ls/ls.c106
-rw-r--r--bin/ls/ls.h4
-rw-r--r--bin/ls/print.c4
-rw-r--r--bin/ls/util.c19
7 files changed, 165 insertions, 72 deletions
diff --git a/bin/ls/cmp.c b/bin/ls/cmp.c
index 84fb038..a2e46ff 100644
--- a/bin/ls/cmp.c
+++ b/bin/ls/cmp.c
@@ -78,7 +78,10 @@ modcmp(const FTSENT *a, const FTSENT *b)
if (b->fts_statp->st_mtim.tv_nsec <
a->fts_statp->st_mtim.tv_nsec)
return (-1);
- return (strcoll(a->fts_name, b->fts_name));
+ if (f_samesort)
+ return (strcoll(b->fts_name, a->fts_name));
+ else
+ return (strcoll(a->fts_name, b->fts_name));
}
int
@@ -104,7 +107,10 @@ acccmp(const FTSENT *a, const FTSENT *b)
if (b->fts_statp->st_atim.tv_nsec <
a->fts_statp->st_atim.tv_nsec)
return (-1);
- return (strcoll(a->fts_name, b->fts_name));
+ if (f_samesort)
+ return (strcoll(b->fts_name, a->fts_name));
+ else
+ return (strcoll(a->fts_name, b->fts_name));
}
int
@@ -130,7 +136,10 @@ birthcmp(const FTSENT *a, const FTSENT *b)
if (b->fts_statp->st_birthtim.tv_nsec <
a->fts_statp->st_birthtim.tv_nsec)
return (-1);
- return (strcoll(a->fts_name, b->fts_name));
+ if (f_samesort)
+ return (strcoll(b->fts_name, a->fts_name));
+ else
+ return (strcoll(a->fts_name, b->fts_name));
}
int
@@ -156,7 +165,10 @@ statcmp(const FTSENT *a, const FTSENT *b)
if (b->fts_statp->st_ctim.tv_nsec <
a->fts_statp->st_ctim.tv_nsec)
return (-1);
- return (strcoll(a->fts_name, b->fts_name));
+ if (f_samesort)
+ return (strcoll(b->fts_name, a->fts_name));
+ else
+ return (strcoll(a->fts_name, b->fts_name));
}
int
diff --git a/bin/ls/extern.h b/bin/ls/extern.h
index f290fbb..90a20a8 100644
--- a/bin/ls/extern.h
+++ b/bin/ls/extern.h
@@ -55,12 +55,12 @@ int prn_octal(const char *);
int prn_printable(const char *);
#ifdef COLORLS
void parsecolors(const char *cs);
-void colorquit(int);
+void colorquit(int);
-extern char *ansi_fgcol;
-extern char *ansi_bgcol;
-extern char *ansi_coloff;
-extern char *attrs_off;
-extern char *enter_bold;
+extern char *ansi_fgcol;
+extern char *ansi_bgcol;
+extern char *ansi_coloff;
+extern char *attrs_off;
+extern char *enter_bold;
#endif
extern int termwidth;
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index cc5ff48..aa4fc18 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -32,7 +32,7 @@
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$
.\"
-.Dd September 28, 2011
+.Dd November 8, 2012
.Dt LS 1
.Os
.Sh NAME
@@ -40,7 +40,7 @@
.Nd list directory contents
.Sh SYNOPSIS
.Nm
-.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx1
+.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,
.Op Fl D Ar format
.Op Ar
.Sh DESCRIPTION
@@ -130,6 +130,8 @@ This option is equivalent to defining
.Ev CLICOLOR
in the environment.
(See below.)
+This functionality can be compiled out by removing the definition of
+.Ev COLORLS .
.It Fl H
Symbolic links on the command line are followed.
This option is assumed if
@@ -249,12 +251,35 @@ subsection below, except (if the long format is not also requested)
the directory totals are not output when the output is in a
single column, even if multi-column output is requested.
.It Fl t
-Sort by time modified (most recently modified
-first) before sorting the operands in lexicographical
-order.
+Sort by descending time modified (most recently modified first). If two files
+have the same modification timestamp, sort their names in ascending
+lexicographical order.
+The
+.Fl r
+option reverses both of these sort orders.
+.Pp
+Note that these sort orders are contradictory: the time sequence is in
+descending order, the lexicographical sort is in ascending order.
+This behavior is mandated by
+.St -p1003.2 .
+This feature can cause problems listing files stored with sequential names on
+FAT file systems, such as from digital cameras, where it is possible to have
+more than one image with the same timestamp.
+In such a case, the photos cannot be listed in the sequence in which
+they were taken.
+To ensure the same sort order for time and for lexicographical sorting, set the
+environment variable
+.Ev LS_SAMESORT
+or use the
+.Fl y
+option.
+This causes
+.Nm
+to reverse the lexicographal sort order when sorting files with the
+same modification timestamp.
.It Fl u
Use time of last access,
-instead of last modification
+instead of time of last modification
of the file for sorting
.Pq Fl t
or printing
@@ -268,6 +293,15 @@ The same as
.Fl C ,
except that the multi-column output is produced with entries sorted
across, rather than down, the columns.
+.It Fl y
+When the
+.Fl t
+option is set, sort the alphabetical output in the same order as the time output.
+This has the same effect as setting
+.Ev LS_SAMESORT .
+See the description of the
+.Fl t
+option for more details.
.It Fl 1
(The numeric digit
.Dq one . )
@@ -275,6 +309,15 @@ Force output to be
one entry per line.
This is the default when
output is not to a terminal.
+.It Fl ,
+(Comma) When the
+.Fl l
+option is set, print file sizes grouped and separated by thousands using the
+non-monetary separator returned by
+.Xr localeconv 3 ,
+typically a comma or period.
+If no locale is set, or the locale does not have a non-monetary separator, this
+option has no effect.
.El
.Pp
The
@@ -529,7 +572,7 @@ variable is defined.
.It Ev CLICOLOR_FORCE
Color sequences are normally disabled if the output is not directed to
a terminal.
-This can be overridden by setting this flag.
+This can be overridden by setting this variable.
The
.Ev TERM
variable still needs to reference a color capable terminal however
@@ -655,6 +698,14 @@ Not all columns have changeable widths.
The fields are,
in order: inode, block count, number of links, user name,
group name, flags, file size, file name.
+.It Ev LS_SAMESORT
+If this variable is set, the
+.Fl t
+option sorts the names of files with the same modification timestamp in the same
+sense as the time sort.
+See the description of the
+.Fl t
+option for more details.
.It Ev TERM
The
.Ev CLICOLOR
@@ -678,6 +729,7 @@ specification.
.Xr getfacl 1 ,
.Xr sort 1 ,
.Xr xterm 1 ,
+.Xr localeconv 3 ,
.Xr strftime 3 ,
.Xr strmode 3 ,
.Xr termcap 5 ,
@@ -716,3 +768,9 @@ option description might be a feature that was
based on the fact that single-column output
usually goes to something other than a terminal.
It is debatable whether this is a design bug.
+.Pp
+.St -p1003.2
+mandates opposite sort orders for files with the same timestamp when
+sorting with the
+.Fl t
+option.
diff --git a/bin/ls/ls.c b/bin/ls/ls.c
index b96d18b..be09035 100644
--- a/bin/ls/ls.c
+++ b/bin/ls/ls.c
@@ -109,10 +109,11 @@ int termwidth = 80; /* default terminal width */
int f_humanval; /* show human-readable file sizes */
int f_inode; /* print inode */
static int f_kblocks; /* print size in kilobytes */
+ int f_label; /* show MAC label */
static int f_listdir; /* list actual directory, not contents */
static int f_listdot; /* list files beginning with . */
-static int f_noautodot; /* do not automatically enable -A for root */
int f_longform; /* long listing format */
+static int f_noautodot; /* do not automatically enable -A for root */
static int f_nofollow; /* don't follow symbolic link arguments */
int f_nonprint; /* show unprintables as ? */
static int f_nosort; /* don't sort output */
@@ -122,19 +123,21 @@ static int f_numericonly; /* don't convert uid/gid to name */
int f_octal_escape; /* like f_octal but use C escapes if possible */
static int f_recursive; /* ls subdirectories also */
static int f_reversesort; /* reverse whatever sort is used */
- int f_sectime; /* print the real time for all files */
+ int f_samesort; /* sort time and name in same direction */
+ int f_sectime; /* print full time information */
static int f_singlecol; /* use single column output */
int f_size; /* list size in short listing */
+static int f_sizesort;
int f_slash; /* similar to f_type, but only for dirs */
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 */
+ int f_thousands; /* show file sizes with thousands separators */
+ char *f_timeformat; /* user-specified time format */
static int f_timesort; /* sort by time vice name */
- char *f_timeformat; /* user-specified time format */
-static int f_sizesort;
int f_type; /* add type character for non-regular files */
static int f_whiteout; /* show whiteout entries */
- int f_label; /* show MAC label */
+
#ifdef COLORLS
int f_color; /* add type in color for non-regular files */
@@ -180,8 +183,10 @@ main(int argc, char *argv[])
}
fts_options = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv,
- "1ABCD:FGHILPRSTUWZabcdfghiklmnopqrstuwx")) != -1) {
+ if (getenv("LS_SAMESORT"))
+ f_samesort = 1;
+ while ((ch = getopt(argc, argv,
+ "1ABCD:FGHILPRSTUWXZabcdfghiklmnopqrstuwxy,")) != -1) {
switch (ch) {
/*
* The -1, -C, -x and -l options all override each other so
@@ -192,17 +197,9 @@ main(int argc, char *argv[])
f_longform = 0;
f_stream = 0;
break;
- case 'B':
- f_nonprint = 0;
- f_octal = 1;
- f_octal_escape = 0;
- break;
case 'C':
f_sortacross = f_longform = f_singlecol = 0;
break;
- case 'D':
- f_timeformat = optarg;
- break;
case 'l':
f_longform = 1;
f_singlecol = 0;
@@ -229,16 +226,46 @@ main(int argc, char *argv[])
f_accesstime = 0;
f_statustime = 0;
break;
+ case 'a':
+ fts_options |= FTS_SEEDOT;
+ /* FALLTHROUGH */
+ case 'A':
+ f_listdot = 1;
+ break;
+ /* The -t and -S options override each other. */
+ case 'S':
+ f_sizesort = 1;
+ f_timesort = 0;
+ break;
+ case 't':
+ f_timesort = 1;
+ f_sizesort = 0;
+ break;
+ /* Other flags. Please keep alphabetic. */
+ case ',':
+ f_thousands = 1;
+ break;
+ case 'B':
+ f_nonprint = 0;
+ f_octal = 1;
+ f_octal_escape = 0;
+ break;
+ case 'D':
+ f_timeformat = optarg;
+ break;
case 'F':
f_type = 1;
f_slash = 0;
break;
+ case 'G':
+ setenv("CLICOLOR", "", 1);
+ break;
case 'H':
fts_options |= FTS_COMFOLLOW;
f_nofollow = 0;
break;
- case 'G':
- setenv("CLICOLOR", "", 1);
+ case 'I':
+ f_noautodot = 1;
break;
case 'L':
fts_options &= ~FTS_PHYSICAL;
@@ -254,14 +281,19 @@ main(int argc, char *argv[])
case 'R':
f_recursive = 1;
break;
- case 'a':
- fts_options |= FTS_SEEDOT;
- /* FALLTHROUGH */
- case 'A':
- f_listdot = 1;
+ case 'T':
+ f_sectime = 1;
break;
- case 'I':
- f_noautodot = 1;
+ case 'W':
+ f_whiteout = 1;
+ break;
+ case 'Z':
+ f_label = 1;
+ break;
+ case 'b':
+ f_nonprint = 0;
+ f_octal = 0;
+ f_octal_escape = 1;
break;
/* The -d option turns off the -R option. */
case 'd':
@@ -309,33 +341,13 @@ main(int argc, char *argv[])
case 's':
f_size = 1;
break;
- case 'T':
- f_sectime = 1;
- break;
- /* The -t and -S options override each other. */
- case 't':
- f_timesort = 1;
- f_sizesort = 0;
- break;
- case 'S':
- f_sizesort = 1;
- f_timesort = 0;
- break;
- case 'W':
- f_whiteout = 1;
- break;
- case 'b':
- f_nonprint = 0;
- f_octal = 0;
- f_octal_escape = 1;
- break;
case 'w':
f_nonprint = 0;
f_octal = 0;
f_octal_escape = 0;
break;
- case 'Z':
- f_label = 1;
+ case 'y':
+ f_samesort = 1;
break;
default:
case '?':
@@ -849,6 +861,8 @@ label_out:
d.s_size = sizelen;
d.s_user = maxuser;
}
+ if (f_thousands) /* make space for commas */
+ d.s_size += (d.s_size - 1) / 3;
printfcn(&d);
output = 1;
diff --git a/bin/ls/ls.h b/bin/ls/ls.h
index ee2a7a5..1a45eb4 100644
--- a/bin/ls/ls.h
+++ b/bin/ls/ls.h
@@ -49,12 +49,14 @@ extern int f_longform; /* long listing format */
extern int f_octal; /* print unprintables in octal */
extern int f_octal_escape; /* like f_octal but use C escapes if possible */
extern int f_nonprint; /* show unprintables as ? */
+extern int f_samesort; /* sort time and name in same direction */
extern int f_sectime; /* print the real time for all files */
extern int f_size; /* list size in short listing */
extern int f_slash; /* append a '/' if the file is a directory */
extern int f_sortacross; /* sort across rows, not down columns */
extern int f_statustime; /* use time of last mode change */
-extern char *f_timeformat; /* user-specified time format */
+extern int f_thousands; /* show file sizes with thousands separators */
+extern char *f_timeformat; /* user-specified time format */
extern int f_notabs; /* don't use tab-separated multi-col output */
extern int f_type; /* add type character for non-regular files */
#ifdef COLORLS
diff --git a/bin/ls/print.c b/bin/ls/print.c
index 5a0fc86..930d6ea 100644
--- a/bin/ls/print.c
+++ b/bin/ls/print.c
@@ -606,6 +606,10 @@ printsize(size_t width, off_t bytes)
humanize_number(buf, sizeof(buf), (int64_t)bytes, "",
HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL);
(void)printf("%*s ", (u_int)width, buf);
+ } else if (f_thousands) { /* with commas */
+ /* This format assignment needed to work round gcc bug. */
+ const char *format = "%*j'd ";
+ (void)printf(format, (u_int)width, bytes);
} else
(void)printf("%*jd ", (u_int)width, bytes);
}
diff --git a/bin/ls/util.c b/bin/ls/util.c
index ecb1732..f8466cd 100644
--- a/bin/ls/util.c
+++ b/bin/ls/util.c
@@ -132,7 +132,7 @@ prn_printable(const char *s)
* to fix this as an efficient fix would involve a lookup table. Same goes
* for the rather inelegant code in prn_octal.
*
- * DES 1998/04/23
+ * DES 1998/04/23
*/
size_t
@@ -175,7 +175,7 @@ prn_octal(const char *s)
size_t clen;
unsigned char ch;
int goodchar, i, len, prtlen;
-
+
memset(&mbs, 0, sizeof(mbs));
len = 0;
while ((clen = mbrtowc(&wc, s, MB_LEN_MAX, &mbs)) != 0) {
@@ -184,7 +184,10 @@ prn_octal(const char *s)
for (i = 0; i < (int)clen; i++)
putchar((unsigned char)s[i]);
len += wcwidth(wc);
- } else if (goodchar && f_octal_escape && wc >= 0 &&
+ } else if (goodchar && f_octal_escape &&
+#if WCHAR_MIN < 0
+ wc >= 0 &&
+#endif
wc <= (wchar_t)UCHAR_MAX &&
(p = strchr(esc, (char)wc)) != NULL) {
putchar('\\');
@@ -200,9 +203,9 @@ prn_octal(const char *s)
for (i = 0; i < prtlen; i++) {
ch = (unsigned char)s[i];
putchar('\\');
- putchar('0' + (ch >> 6));
- putchar('0' + ((ch >> 3) & 7));
- putchar('0' + (ch & 7));
+ putchar('0' + (ch >> 6));
+ putchar('0' + ((ch >> 3) & 7));
+ putchar('0' + (ch & 7));
len += 4;
}
}
@@ -222,9 +225,9 @@ usage(void)
{
(void)fprintf(stderr,
#ifdef COLORLS
- "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwx1] [-D format]"
+ "usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
#else
- "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwx1] [-D format]"
+ "usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuwxy1,] [-D format]"
#endif
" [file ...]\n");
exit(1);
OpenPOWER on IntegriCloud