Anyone?
- todd
> This is adapted from FreeBSD revs 130236 and 130237 which have the
> following log message:
>
> If we are asked to print the total number of blocks, do so even if we
> have no entries to print (either due to an empty directory or an
> error). This makes the -l and -s options more consistent, like
> Solaris and (Debian) Linux. To make this happen, tweak two
> optimizations on the second call to display():
>
> - Don't skip display() altogether, even if list == NULL.
> - Don't skip the call to the printfn in display() if we
> need to print the total.
>
> I've verified that both historic AT&T ls and GNU ls behave this
> way.
>
> - todd
>
> Index: bin/ls/ls.c
> ===================================================================
> RCS file: /cvs/src/bin/ls/ls.c,v
> retrieving revision 1.53
> diff -u -p -u -r1.53 ls.c
> --- bin/ls/ls.c 6 Jul 2020 00:55:05 -0000 1.53
> +++ bin/ls/ls.c 3 Oct 2020 15:18:01 -0000
> @@ -355,7 +355,13 @@ traverse(int argc, char *argv[], int opt
> fts_open(argv, options, f_nosort ? NULL : mastercmp)) == NULL)
> err(1, NULL);
>
> - display(NULL, fts_children(ftsp, 0));
> + /*
> + * We ignore errors from fts_children here since they will be
> + * replicated and signalled on the next call to fts_read() below.
> + */
> + chp = fts_children(ftsp, 0);
> + if (chp != NULL)
> + display(NULL, chp);
> if (f_listdir)
> return;
>
> @@ -438,16 +444,6 @@ display(FTSENT *p, FTSENT *list)
> char buf[21]; /* 64 bits == 20 digits */
> char *flags = NULL;
>
> - /*
> - * If list is NULL there are two possibilities: that the parent
> - * directory p has no children, or that fts_children() returned an
> - * error. We ignore the error case since it will be replicated
> - * on the next call to fts_read() on the post-order visit to the
> - * directory p, and will be signalled in traverse().
> - */
> - if (list == NULL)
> - return;
> -
> needstats = f_inode || f_longform || f_size;
> flen = 0;
> btotal = maxblock = maxinode = maxlen = maxnlink = 0;
> @@ -542,7 +538,13 @@ display(FTSENT *p, FTSENT *list)
> ++entries;
> }
>
> - if (!entries)
> + /*
> + * If there are no entries to display, we normally stop right
> + * here. However, we must continue if we have to display the
> + * total block count. In this case, we display the total only
> + * on the second (p != NULL) pass.
> + */
> + if (!entries && (!(f_longform || f_size) || p == NULL))
> return;
>
> d.list = list;
> Index: bin/ls/print.c
> ===================================================================
> RCS file: /cvs/src/bin/ls/print.c,v
> retrieving revision 1.38
> diff -u -p -u -r1.38 print.c
> --- bin/ls/print.c 5 Feb 2019 02:17:32 -0000 1.38
> +++ bin/ls/print.c 3 Oct 2020 15:13:14 -0000
> @@ -87,7 +87,8 @@ printlong(DISPLAY *dp)
> NAMES *np;
> char buf[20];
>
> - if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
> + if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
> + (f_longform || f_size))
> (void)printf("total %llu\n", howmany(dp->btotal, blocksize));
>
> for (p = dp->list; p; p = p->fts_link) {
> @@ -198,7 +199,8 @@ printcol(DISPLAY *dp)
> if (num % numcols)
> ++numrows;
>
> - if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
> + if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
> + (f_longform || f_size))
> (void)printf("total %llu\n", howmany(dp->btotal, blocksize));
> for (row = 0; row < numrows; ++row) {
> for (base = row, col = 0;;) {
> @@ -271,7 +273,8 @@ printacol(DISPLAY *dp)
> if ( (colwidth = compute_columns(dp, &numcols)) == 0)
> return;
>
> - if (dp->list->fts_level != FTS_ROOTLEVEL && (f_longform || f_size))
> + if ((dp->list == NULL || dp->list->fts_level != FTS_ROOTLEVEL) &&
> + (f_longform || f_size))
> (void)printf("total %llu\n", howmany(dp->btotal, blocksize));
> col = 0;
> for (p = dp->list; p; p = p->fts_link) {
>