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) {
>

Reply via email to