odd ls -U behaviour if output is not a terminal
In a script I'm trying to do the following:
$ cd /usr/include $ ls -U *.h | sed ...
The ls command alone works as expected, giving an unsorted list of files that match the expression. When output is redirected into a file or piped into another tool, it's all garbled and makes no sense:
$ cd /usr/include $ ls -U *.h | cat )u 3u Eu Uu gu yu �u �u �u �u �u �u �u �u v v ,v
This happens with /usr/bin/ls and /usr/xpg4/bin/ls, but not with /usr/gnu/bin/ls or /usr/ucb/ls.
It also works when invoked without a list of files:
$ cd /usr/include $ ls -U | cat sdp.h sha2.h xlocale.h stdint.h pr29.h ...
Updated by Gary Mills over 5 years ago
The peculiar behavior was caused by two bugs in the code.
The lbuf structure contains a union that encodes two different ways to specify the name of the file. One, ln.lname, is a character array. The other, ln.namep, is a pointer to the actual name. When the flag ISARG is set in the lflags member, namep must be used.
This convention is followed in ls.c except for in the printf function call near line 1260. Adding the missing test fixed the problem.
When set, the variable `noflist' indicates a special case where only the file name will be printed.
The code in ls.c failed to initialize certain members of the lbuf structure when this variable was set, even though these members were referenced in the code. Clearing the entire structure in gstat() fixed the problem.
Updated by Electric Monk over 5 years ago
- Status changed from Feedback to Closed
- % Done changed from 80 to 100
commit b9c817386d7607f906fe86b2b0f46bcfe80cf82d Author: Gary Mills <email@example.com> Date: 2015-03-11T19:12:20.000Z 5613 odd ls -U behaviour if output is not a terminal Reviewed by: Dan McDonald <firstname.lastname@example.org> Reviewed by: Hans Rosenfeld <email@example.com> Approved by: Robert Mustacchi <firstname.lastname@example.org>