Bug 237030 - ls -R produces invalid output when recursing dot directories
Summary: ls -R produces invalid output when recursing dot directories
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 11.2-STABLE
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-05 02:43 UTC by Duane
Modified: 2019-04-08 14:39 UTC (History)
1 user (show)

See Also:


Attachments
Patch to skip recursion of dot directories (363 bytes, patch)
2019-04-05 02:43 UTC, Duane
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Duane 2019-04-05 02:43:00 UTC
Created attachment 203394 [details]
Patch to skip recursion of dot directories

`ls -R` doesn't print dot directories (i.e. those with a '.' prefix) nor their contents but it still recurses through them and will print the contents of directories within.

The standard could be argued as ambiguous on this point (see bug #206192), but generally the agreement is that this is the wrong behaviour.  Note additionally that FreeBSD doesn't exhibit either of the described behaviours because it doesn't print the contents of a dot directory, only the contents of non-dot-directories contained in dot-directories.

As an example set up a directory as follows: `mkdir test; cd test; git init`

Then `ls -R` outputs the following:
<-->
    applypatch-msg.sample*     pre-applypatch.sample*     pre-rebase.sample*         update.sample*
    commit-msg.sample*         pre-commit.sample*         pre-receive.sample*
    post-update.sample*        pre-push.sample*           prepare-commit-msg.sample*

    ./.git/info:
    exclude

    ./.git/objects:
    info/ pack/

    ./.git/objects/info:

    ./.git/objects/pack:

    ./.git/refs:
    heads/ tags/

    ./.git/refs/heads:

    ./.git/refs/tags:
<-->

Now run `touch file; ls -R` and the result changes as follows:
<-->
    file

    ./.git/branches:

    ./.git/hooks:
    applypatch-msg.sample*     pre-applypatch.sample*     pre-rebase.sample*         update.sample*
    commit-msg.sample*         pre-commit.sample*         pre-receive.sample*
    post-update.sample*        pre-push.sample*           prepare-commit-msg.sample*

    ./.git/info:
    exclude

    ./.git/objects:
    info/ pack/

    ./.git/objects/info:

    ./.git/objects/pack:

    ./.git/refs:
    heads/ tags/

    ./.git/refs/heads:

    ./.git/refs/tags:
<-->

Notice the extra directories that are now output that weren't before.

The solution is quite simple, to just skip the recursion in the event that the directory's children are skipped, and attached is a patch which does just that.
Comment 1 Duane 2019-04-05 21:54:46 UTC
Just a point of interest, it appears this bug was present in the BSD4.4 sources, and Apple only just fixed it around 2014 in their fork with the same change as I have proposed.  See https://opensource.apple.com/source/file_cmds/file_cmds-242/ls/ls.c.auto.html