mirror of
https://git.freebsd.org/src.git
synced 2026-01-16 23:02:24 +00:00
ls: implement --group-directories-first for compatibility with GNU ls
Also implement --group-directories which takes a parameter. "first" is equivalent to --group-directories-first, "last" gives reversed sorting. Changes in sorting between elements of the same type (files, directories) are not intended. Differential Revision: https://reviews.freebsd.org/D48347
This commit is contained in:
parent
82fa7f83b5
commit
8b92977857
3 changed files with 51 additions and 7 deletions
19
bin/ls/ls.1
19
bin/ls/ls.1
|
|
@ -39,6 +39,8 @@
|
|||
.Nm
|
||||
.Op Fl ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1\&,
|
||||
.Op Fl -color Ns = Ns Ar when
|
||||
.Op Fl -group-directories Ns = Ns Ar order
|
||||
.Op Fl -group-directories-first
|
||||
.Op Fl D Ar format
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
|
|
@ -303,6 +305,16 @@ options.
|
|||
Display the long
|
||||
.Pq Fl l
|
||||
format output without the file owner's name or number.
|
||||
.It Fl -group-directories Ns = Ns Ar order
|
||||
Within results for each operand,
|
||||
group directories together and print them either
|
||||
.Cm first
|
||||
or
|
||||
.Cm last.
|
||||
.It Fl -group-directories-first
|
||||
Equivalent to
|
||||
.Fl -group-directories Ns = Ns Ar first .
|
||||
Implemented for compatibility with GNU coreutils.
|
||||
.It Fl h
|
||||
When used with the
|
||||
.Fl l
|
||||
|
|
@ -914,8 +926,13 @@ and
|
|||
.St -p1003.1-2008 .
|
||||
The options
|
||||
.Fl B , D , G , I , T , U , W , Z , b , h , v , w , y
|
||||
and
|
||||
,
|
||||
.Fl ,
|
||||
.Fl -color
|
||||
and
|
||||
.Fl -group-directories Ns =
|
||||
(including
|
||||
.Fl -group-directories-first )
|
||||
are non-standard extensions.
|
||||
.Pp
|
||||
The ACL support is compatible with
|
||||
|
|
|
|||
35
bin/ls/ls.c
35
bin/ls/ls.c
|
|
@ -87,12 +87,24 @@ static void display(const FTSENT *, FTSENT *, int);
|
|||
static int mastercmp(const FTSENT * const *, const FTSENT * const *);
|
||||
static void traverse(int, char **, int);
|
||||
|
||||
#define COLOR_OPT (CHAR_MAX + 1)
|
||||
enum {
|
||||
GRP_NONE = 0,
|
||||
GRP_DIR_FIRST = -1,
|
||||
GRP_DIR_LAST = 1
|
||||
};
|
||||
|
||||
enum {
|
||||
BIN_OPT = CHAR_MAX,
|
||||
COLOR_OPT,
|
||||
GROUP_OPT
|
||||
};
|
||||
|
||||
static const struct option long_opts[] =
|
||||
{
|
||||
{"color", optional_argument, NULL, COLOR_OPT},
|
||||
{NULL, no_argument, NULL, 0}
|
||||
{"color", optional_argument, NULL, COLOR_OPT},
|
||||
{"group-directories", optional_argument, NULL, GROUP_OPT},
|
||||
{"group-directories-first", no_argument, NULL, GROUP_OPT},
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
||||
static void (*printfcn)(const DISPLAY *);
|
||||
|
|
@ -105,6 +117,7 @@ int termwidth = 80; /* default terminal width */
|
|||
int f_accesstime; /* use time of last access */
|
||||
int f_birthtime; /* use time of birth */
|
||||
int f_flags; /* show flags associated with a file */
|
||||
static int f_groupdir = GRP_NONE;/* group directories first/last */
|
||||
int f_humanval; /* show human-readable file sizes */
|
||||
int f_inode; /* print inode */
|
||||
static int f_kblocks; /* print size in kilobytes */
|
||||
|
|
@ -449,6 +462,15 @@ main(int argc, char *argv[])
|
|||
case 'y':
|
||||
f_samesort = 1;
|
||||
break;
|
||||
case GROUP_OPT:
|
||||
if (optarg == NULL || strcmp(optarg, "first") == 0)
|
||||
f_groupdir = GRP_DIR_FIRST;
|
||||
else if (strcmp(optarg, "last") == 0)
|
||||
f_groupdir = GRP_DIR_LAST;
|
||||
else
|
||||
errx(2, "unsupported --group-directories value '%s' (must be first or last)",
|
||||
optarg);
|
||||
break;
|
||||
case COLOR_OPT:
|
||||
#ifdef COLORLS
|
||||
if (optarg == NULL || do_color_always(optarg))
|
||||
|
|
@ -1004,7 +1026,7 @@ label_out:
|
|||
static int
|
||||
mastercmp(const FTSENT * const *a, const FTSENT * const *b)
|
||||
{
|
||||
int a_info, b_info;
|
||||
int a_info, b_info, dir;
|
||||
|
||||
a_info = (*a)->fts_info;
|
||||
if (a_info == FTS_ERR)
|
||||
|
|
@ -1023,5 +1045,10 @@ mastercmp(const FTSENT * const *a, const FTSENT * const *b)
|
|||
if (b_info == FTS_D)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (f_groupdir != GRP_NONE)
|
||||
if ((dir = (a_info == FTS_D) - (b_info == FTS_D)) != 0)
|
||||
return (f_groupdir * dir);
|
||||
|
||||
return (sortfcn(*a, *b));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,9 +219,9 @@ usage(void)
|
|||
{
|
||||
(void)fprintf(stderr,
|
||||
#ifdef COLORLS
|
||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [--color=when] [-D format]"
|
||||
"usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [--color=when] [-D format] [--group-directories=]"
|
||||
#else
|
||||
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [-D format]"
|
||||
"usage: ls [-ABCFHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [-D format] [--group-directories=]"
|
||||
#endif
|
||||
" [file ...]\n");
|
||||
exit(1);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue