Hi Tim,

> http://pubs.opengroup.org/onlinepubs/009695399/utilities/ls.html says:

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html is the
current version.  :-)

> "If no operands are specified, ls shall write the contents of the
> current directory."

    If no operands are specified, ls shall behave as if a single operand
    of dot ('.') had been specified.

> and then: "-d  [...] Do not treat directories differently than other
> types of files. [...]"

That hasn't changed.

> So it makes sense that 'ls -d .' would output '.', from the
> description of -d above.
>
> It also makes sense that 'ls' can be implemented as being equivalent
> to 'ls .' from the 'no operands' description above.

Yep × 2.

> Does this mean that 'ls -d' _must_ output '.', or is it free to be
> equivalent to 'ls -d *'?

`ls -d' must be as `ls -d .'.  The suggested `ls -d *' is equivalent to
`ls .' so that's also suggesting `-d' is ignored unless `files...' are
given?

`ls -d' being `ls -d .' is the orthogonal behaviour that gives the
simplest explanation and implementation.

    if no file... then          if no file... then
        file... = '.'               if -d then
                                        file... = glob('*')
                                    else
                                        file... = '.'

It's also handy with these questions to ask `What would 7th Ed. do?'.
:-)

    http://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/ls.c

    37  struct  lbuf    *flist[NFILES];
    38  struct  lbuf    **lastp = flist;
    39  struct  lbuf    **firstp = flist;
    40  char    *dotp   = ".";

    65                  while (*++*argv) switch (**argv) {

You don't see `*++*' much any more.

    76                  case 'd':
    77                          dflg++;
    78                          continue;

   116                  }

   132          if (argc==0) {
   133                  argc++;
   134                  argv = &dotp - 1;
   135          }

So no `files...' gives a default of `.'.  Note argv[0], that won't be
used, is probably firstp's memory, and argv[] might not be
NULL-terminated, again, not used.

   136          for (i=0; i < argc; i++) {
   137                  if ((ep = gstat(*++argv, 1))==NULL)
   138                          continue;
   139                  ep->ln.namep = *argv;
   140                  ep->lflags |= ISARG;
   141          }
   142          qsort(firstp, lastp - firstp, sizeof *lastp, compar);

The beginning of flist[] is now the items of interest, sorted, so we run
through them...

   143          slastp = lastp;
   144          for (epp=firstp; epp<slastp; epp++) {
   145                  ep = *epp;
   146                  if (ep->ltype=='d' && dflg==0 || fflg) {
   147                          if (argc>1)
   148                                  printf("\n%s:\n", ep->ln.namep);
   149                          lastp = slastp;
   150                          readdir(ep->ln.namep);

This tacks the entries of a directory that's to be listed onto the end
of the ones we're still processing in flist[].  We only recurse at most
one level, and that makes better use of the limited RAM rather than have
two arrays.

   151                          if (fflg==0)
   152                                  qsort(slastp,lastp - slastp,sizeof 
*lastp,compar);
   153                          if (lflg || sflg)
   154                                  printf("total %D\n", tblocks);
   155                          for (ep1=slastp; ep1<lastp; ep1++)
   156                                  pentry(*ep1);

No need to check dflg when we're one level down so the tacked on ones
can be simply printed.

   157                  } else
   158                          pentry(ep);
   159          }

Cheers, Ralph.

-- 
Next meeting:  Bournemouth, Tuesday, 2018-04-03 20:00
Meets, Mailing list, IRC, LinkedIn, ...  http://dorset.lug.org.uk/
New thread:  mailto:dorset@mailman.lug.org.uk / CHECK IF YOU'RE REPLYING
Reporting bugs well:  http://goo.gl/4Xue     / TO THE LIST OR THE AUTHOR

Reply via email to