Project

General

Profile

Bug #5613

odd ls -U behaviour if output is not a terminal

Added by Hans Rosenfeld over 5 years ago. Updated over 5 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Start date:
2015-02-13
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:

Description

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
...
#1

Updated by Gary Mills over 5 years ago

  • Status changed from New to Feedback
  • Assignee set to Gary Mills

I'll investigate this one.

#2

Updated by Gary Mills over 5 years ago

  • % Done changed from 0 to 80

Here's a simpler test:

$ cd /usr/include
$ /usr/bin/ls -U1 ar.h archives.h
garbage
garbage

This is it after the fix:

$ /tmp/ls -U1 ar.h archives.h
ar.h
archives.h
#3

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.

#4

Updated by Electric Monk over 5 years ago

  • Status changed from Feedback to Closed
  • % Done changed from 80 to 100

git commit b9c817386d7607f906fe86b2b0f46bcfe80cf82d

commit  b9c817386d7607f906fe86b2b0f46bcfe80cf82d
Author: Gary Mills <gary_mills@fastmail.fm>
Date:   2015-03-11T19:12:20.000Z

    5613 odd ls -U behaviour if output is not a terminal
    Reviewed by: Dan McDonald <danmcd@omniti.com>
    Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
    Approved by: Robert Mustacchi <rm@joyent.com>

Also available in: Atom PDF