ls: Improve POSIX compatibility for -g and -n.

- Change -g (ignored for BSD 4.3 compatibility since BSD 4.4)
  to use POSIX semantics of implying -l but omitting the owner's
  name.

- Change -n to imply -l.

The -o option remains unchanged (POSIX defines -o as a complement to
-g that implies -l but omits group names whereas BSD defines -o to add
file flags to -l).  This compromise is the same used by both NetBSD
and OpenBSD.

PR:		70813
Reviewed by:	jhb, Pau Amma <pauamma@gundo.com>
Co-authored-by:	John Baldwin <jhb@FreeBSD.org>
Differential Revision:	https://reviews.freebsd.org/D34747
This commit is contained in:
Minsoo Choo 2023-07-18 09:49:59 -07:00 committed by John Baldwin
parent d5e2d0f140
commit 3bfbb521fe
5 changed files with 28 additions and 21 deletions

View file

@ -32,7 +32,7 @@
.\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" @(#)ls.1 8.7 (Berkeley) 7/29/94
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd October 31, 2022 .Dd July 18, 2023
.Dt LS 1 .Dt LS 1
.Os .Os
.Sh NAME .Sh NAME
@ -301,14 +301,9 @@ and
.Fl s .Fl s
options. options.
.It Fl g .It Fl g
This option has no effect. Display the long
It is only available for compatibility with
.Bx 4.3 ,
where it was used to display the group name in the long
.Pq Fl l .Pq Fl l
format output. format output without the file owner's name or number.
This option is incompatible with
.St -p1003.1-2008 .
.It Fl h .It Fl h
When used with the When used with the
.Fl l .Fl l

View file

@ -144,6 +144,7 @@ static int f_singlecol; /* use single column output */
static int f_sizesort; static int f_sizesort;
int f_slash; /* similar to f_type, but only for dirs */ int f_slash; /* similar to f_type, but only for dirs */
int f_sortacross; /* sort across rows, not down columns */ int f_sortacross; /* sort across rows, not down columns */
int f_sowner; /* disable showing owner's name */
int f_statustime; /* use time of last mode change */ int f_statustime; /* use time of last mode change */
static int f_stream; /* stream the output, separate with commas */ static int f_stream; /* stream the output, separate with commas */
int f_thousands; /* show file sizes with thousands separators */ int f_thousands; /* show file sizes with thousands separators */
@ -402,7 +403,11 @@ main(int argc, char *argv[])
f_listdir = 1; f_listdir = 1;
f_recursive = 0; f_recursive = 0;
break; break;
case 'g': /* Compatibility with 4.3BSD. */ case 'g':
f_longform = 1;
f_singlecol = 0;
f_stream = 0;
f_sowner = 1;
break; break;
case 'h': case 'h':
f_humanval = 1; f_humanval = 1;
@ -421,6 +426,9 @@ main(int argc, char *argv[])
break; break;
case 'n': case 'n':
f_numericonly = 1; f_numericonly = 1;
f_longform = 1;
f_singlecol = 0;
f_stream = 0;
break; break;
case 'o': case 'o':
f_flags = 1; f_flags = 1;

View file

@ -56,6 +56,7 @@ extern int f_sectime; /* print the real time for all files */
extern int f_size; /* list size in short listing */ extern int f_size; /* list size in short listing */
extern int f_slash; /* append a '/' if the file is a directory */ 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_sortacross; /* sort across rows, not down columns */
extern int f_sowner; /* disable showing the owner's name */
extern int f_statustime; /* use time of last mode change */ extern int f_statustime; /* use time of last mode change */
extern int f_thousands; /* show file sizes with thousands separators */ extern int f_thousands; /* show file sizes with thousands separators */
extern char *f_timeformat; /* user-specified time format */ extern char *f_timeformat; /* user-specified time format */

View file

@ -234,9 +234,11 @@ printlong(const DISPLAY *dp)
strmode(sp->st_mode, buf); strmode(sp->st_mode, buf);
aclmode(buf, p); aclmode(buf, p);
np = p->fts_pointer; np = p->fts_pointer;
(void)printf("%s %*ju %-*s %-*s ", buf, dp->s_nlink, (void)printf("%s %*ju ", buf, dp->s_nlink,
(uintmax_t)sp->st_nlink, dp->s_user, np->user, dp->s_group, (uintmax_t)sp->st_nlink);
np->group); if (!f_sowner)
(void)printf("%-*s ", dp->s_user, np->user);
(void)printf("%-*s ", dp->s_group, np->group);
if (f_flags) if (f_flags)
(void)printf("%-*s ", dp->s_flags, np->flags); (void)printf("%-*s ", dp->s_flags, np->flags);
if (f_label) if (f_label)

View file

@ -525,18 +525,19 @@ f_flag_body()
atf_test_case g_flag atf_test_case g_flag
g_flag_head() g_flag_head()
{ {
atf_set "descr" "Verify that -g does nothing (compatibility flag)" atf_set "descr" "Verify that -g implies -l but omits the owner name field"
} }
g_flag_body() g_flag_body()
{ {
create_test_inputs2 atf_check -e empty -o empty -s exit:0 touch a.file
for file in $files; do
atf_check -e empty -o match:"$(ls -a $file)" -s exit:0 \ mtime_in_secs=$(stat -f "%m" -t "%s" a.file)
ls -ag $file mtime=$(date -j -f "%s" $mtime_in_secs +"%b[[:space:]]+%e[[:space:]]+%H:%M")
atf_check -e empty -o match:"$(ls -la $file)" -s exit:0 \
ls -alg $file expected_output=$(stat -f "%Sp[[:space:]]+%l[[:space:]]+%Sg[[:space:]]+%z[[:space:]]+$mtime[[:space:]]+a\\.file" a.file)
done
atf_check -e empty -o match:"$expected_output" -s exit:0 ls -g a.file
} }
atf_test_case h_flag atf_test_case h_flag
@ -689,7 +690,7 @@ n_flag_body()
atf_check -e empty \ atf_check -e empty \
-o match:'\-rw\-r\-\-r\-\-[[:space:]]+1[[:space:]]+'"$nobody_uid[[:space:]]+$daemon_gid"'[[:space:]]+.+a\.file' \ -o match:'\-rw\-r\-\-r\-\-[[:space:]]+1[[:space:]]+'"$nobody_uid[[:space:]]+$daemon_gid"'[[:space:]]+.+a\.file' \
ls -ln a.file ls -n a.file
} }