Hi Crystal,
Crystal Kolipe wrote on Tue, Oct 03, 2023 at 06:47:42PM -0300:
> Two display format bugs seems to have crept in to ls due to the
> addition of scaled human readable values and large minor numbers.
I think you are right that the current situation isn't good.
Thank you for bringing this up.
In general, ls(1) strives to dynamically determine the required
column width. It already does that for the file size column.
Given that device numbers use the same column, i think the solution
that is cleanest, most robust, most aesthetically pleasing, least
wasteful with respect to space, and easiest to maintain is simply
doing the same for device numbers, see the patch below.
Two remarks:
* The reason for keeping the local variable "bcfile" is that
(0, 0) represents a valid device (console). There is no
good reason why it should be in the DISPLAY struct, though.
* The line "d.s_major = d.s_minor = 3;" is likely redundant because
with bcfile == 0, nothing is supposed to use these fields.
While local variables should only be initialized when needed, i
think defensive programming recommends keeping data that is used
by (even internal) APIs initialized to reasonable values rather
than having random memory content lying around. That reduces
the risk of future code changes in *other* modules accidentally
accessing random data, if developers get confused regarding
which invariants the internal API guarantees or requires.
OK?
Ingo
$ cd /dev
$ ls -l MAKEDEV *vid*
-r-xr-xr-x 1 root wheel 12254 Oct 3 07:07 MAKEDEV
lrwxr-xr-x 1 root wheel 6 Aug 29 2016 video -> video0
crw------- 1 root wheel 44, 0 Oct 3 13:34 video0
crw------- 1 root wheel 44, 1 Oct 3 13:34 video1
$ ls -lh MAKEDEV *vid*
-r-xr-xr-x 1 root wheel 12.0K Oct 3 07:07 MAKEDEV
lrwxr-xr-x 1 root wheel 6B Aug 29 2016 video -> video0
crw------- 1 root wheel 44, 0 Oct 3 13:34 video0
crw------- 1 root wheel 44, 1 Oct 3 13:34 video1
$ ls -l null
crw-rw-rw- 1 root wheel 2, 2 Oct 5 00:32 null
$ ls -l cua00
crw-rw---- 1 root dialer 8, 128 Oct 3 13:34 cua00
Index: ls.c
===================================================================
RCS file: /cvs/src/bin/ls/ls.c,v
retrieving revision 1.54
diff -u -p -r1.54 ls.c
--- ls.c 7 Oct 2020 21:03:09 -0000 1.54
+++ ls.c 5 Oct 2023 14:47:37 -0000
@@ -436,6 +436,7 @@ display(FTSENT *p, FTSENT *list)
unsigned long long btotal;
blkcnt_t maxblock;
ino_t maxinode;
+ unsigned int maxmajor, maxminor;
int bcfile, flen, glen, ulen, maxflags, maxgroup, maxuser, maxlen;
int entries, needstats;
int width;
@@ -449,6 +450,7 @@ display(FTSENT *p, FTSENT *list)
btotal = maxblock = maxinode = maxlen = maxnlink = 0;
bcfile = 0;
maxuser = maxgroup = maxflags = 0;
+ maxmajor = maxminor = 0;
maxsize = 0;
for (cur = list, entries = 0; cur != NULL; cur = cur->fts_link) {
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
@@ -523,9 +525,13 @@ display(FTSENT *p, FTSENT *list)
(void)strlcpy(np->group, group, glen + 1);
if (S_ISCHR(sp->st_mode) ||
- S_ISBLK(sp->st_mode))
+ S_ISBLK(sp->st_mode)) {
bcfile = 1;
-
+ if (maxmajor < major(sp->st_rdev))
+ maxmajor = major(sp->st_rdev);
+ if (maxminor < minor(sp->st_rdev))
+ maxminor = minor(sp->st_rdev);
+ }
if (f_flags) {
np->flags = &np->data[ulen + 1 + glen +
1];
(void)strlcpy(np->flags, flags, flen +
1);
@@ -551,7 +557,6 @@ display(FTSENT *p, FTSENT *list)
d.entries = entries;
d.maxlen = maxlen;
if (needstats) {
- d.bcfile = bcfile;
d.btotal = btotal;
(void)snprintf(buf, sizeof(buf), "%llu",
(unsigned long long)maxblock);
@@ -570,6 +575,17 @@ display(FTSENT *p, FTSENT *list)
d.s_size = strlen(buf);
} else
d.s_size = FMT_SCALED_STRSIZE-2; /* no - or '\0' */
+ d.s_major = d.s_minor = 3;
+ if (bcfile) {
+ (void)snprintf(buf, sizeof(buf), "%u", maxmajor);
+ d.s_major = strlen(buf);
+ (void)snprintf(buf, sizeof(buf), "%u", maxminor);
+ d.s_minor = strlen(buf);
+ if (d.s_size <= d.s_major + 2 + d.s_minor)
+ d.s_size = d.s_major + 2 + d.s_minor;
+ else
+ d.s_major = d.s_size - 2 - d.s_minor;
+ }
d.s_user = maxuser;
}
Index: ls.h
===================================================================
RCS file: /cvs/src/bin/ls/ls.h,v
retrieving revision 1.9
diff -u -p -r1.9 ls.h
--- ls.h 30 May 2013 16:34:32 -0000 1.9
+++ ls.h 5 Oct 2023 14:47:37 -0000
@@ -55,7 +55,6 @@ extern int f_typedir; /* add type chara
typedef struct {
FTSENT *list;
unsigned long long btotal;
- int bcfile;
int entries;
int maxlen;
int s_block;
@@ -64,6 +63,8 @@ typedef struct {
int s_inode;
int s_nlink;
int s_size;
+ int s_major;
+ int s_minor;
int s_user;
} DISPLAY;
Index: print.c
===================================================================
RCS file: /cvs/src/bin/ls/print.c,v
retrieving revision 1.39
diff -u -p -r1.39 print.c
--- print.c 7 Oct 2020 21:03:09 -0000 1.39
+++ print.c 5 Oct 2023 14:47:37 -0000
@@ -110,12 +110,9 @@ printlong(DISPLAY *dp)
if (f_flags)
(void)printf("%-*s ", dp->s_flags, np->flags);
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
- (void)printf("%3u, %3u ",
- major(sp->st_rdev), minor(sp->st_rdev));
- else if (dp->bcfile)
- (void)printf("%*s%*lld ",
- 8 - dp->s_size, "", dp->s_size,
- (long long)sp->st_size);
+ (void)printf("%*u, %*u ",
+ dp->s_major, major(sp->st_rdev),
+ dp->s_minor, minor(sp->st_rdev));
else
printsize(dp->s_size, sp->st_size);
if (f_accesstime)