Skip to content

Commit 40ca64f

Browse files
committed
ls(1): print entries that failed with EIO or ENOTCONN
The former can be for various reasons while the latter is emitted by FUSE sometimes. If we have an entry but can't tell anything about it, print its name anyway, and in extended listing print a bunch of question marks. Fixes #11
1 parent 74791b2 commit 40ca64f

File tree

4 files changed

+167
-30
lines changed

4 files changed

+167
-30
lines changed

patches/src.freebsd.patch

Lines changed: 123 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4537,7 +4537,7 @@
45374537
{
45384538
struct stat *sp;
45394539
DISPLAY d;
4540-
@@ -744,8 +746,10 @@
4540+
@@ -744,12 +746,15 @@
45414541
size_t flen, ulen, glen;
45424542
char *initmax;
45434543
int entries, needstats;
@@ -4549,15 +4549,49 @@
45494549
char ngroup[STRBUF_SIZEOF(uid_t) + 1];
45504550
char nuser[STRBUF_SIZEOF(gid_t) + 1];
45514551
u_long width[9];
4552-
@@ -802,7 +806,6 @@
4552+
int i;
4553+
+ bool failent;
4554+
4555+
needstats = f_inode || f_longform || f_size;
4556+
flen = 0;
4557+
@@ -802,15 +807,20 @@
45534558

45544559
d.s_size = 0;
45554560
sizelen = 0;
45564561
- flags = NULL;
45574562
for (cur = list, entries = 0; cur; cur = cur->fts_link) {
45584563
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
45594564
warnx("%s: %s",
4560-
@@ -857,27 +860,33 @@
4565+
cur->fts_name, strerror(cur->fts_errno));
4566+
- cur->fts_number = NO_PRINT;
4567+
rval = 1;
4568+
- continue;
4569+
- }
4570+
+ if (cur->fts_errno != ENOTCONN && cur->fts_errno != EIO) {
4571+
+ cur->fts_number = NO_PRINT;
4572+
+ continue;
4573+
+ }
4574+
+ cur->fts_number = ERR_PRINT;
4575+
+ /* zero out the structure just in case */
4576+
+ memset(cur->fts_statp, 0, sizeof(*cur->fts_statp));
4577+
+ failent = true;
4578+
+ } else failent = false;
4579+
/*
4580+
* P is NULL if list is the argv list, to which different rules
4581+
* apply.
4582+
@@ -849,7 +859,10 @@
4583+
4584+
btotal += sp->st_blocks;
4585+
if (f_longform) {
4586+
- if (f_numericonly) {
4587+
+ if (failent) {
4588+
+ user = "?";
4589+
+ group = "?";
4590+
+ } else if (f_numericonly) {
4591+
(void)snprintf(nuser, sizeof(nuser),
4592+
"%u", sp->st_uid);
4593+
(void)snprintf(ngroup, sizeof(ngroup),
4594+
@@ -857,27 +870,33 @@
45614595
user = nuser;
45624596
group = ngroup;
45634597
} else {
@@ -4604,18 +4638,22 @@
46044638
if (f_flags) {
46054639
flags = fflagstostr(sp->st_flags);
46064640
if (flags != NULL && *flags == '\0') {
4607-
@@ -891,8 +900,10 @@
4641+
@@ -891,8 +910,13 @@
46084642
maxflags = flen;
46094643
} else
46104644
flen = 0;
46114645
+#endif
46124646
labelstr = NULL;
4613-
if (f_label) {
4647+
- if (f_label) {
4648+
+ if (f_label && failent) {
4649+
+ labelstr = strdup("?");
4650+
+ labelstrlen = 1;
4651+
+ } else if (f_label) {
46144652
+#if 0
46154653
char name[PATH_MAX + 1];
46164654
mac_t label;
46174655
int error;
4618-
@@ -938,6 +949,27 @@
4656+
@@ -938,6 +962,27 @@
46194657
}
46204658
mac_free(label);
46214659
label_out:
@@ -4643,15 +4681,15 @@
46434681
if (labelstr == NULL)
46444682
labelstr = strdup("-");
46454683
labelstrlen = strlen(labelstr);
4646-
@@ -945,7 +977,6 @@
4684+
@@ -945,7 +990,6 @@
46474685
maxlabelstr = labelstrlen;
46484686
} else
46494687
labelstrlen = 0;
46504688
-
46514689
if ((np = malloc(sizeof(NAMES) + labelstrlen +
46524690
ulen + glen + flen + 4)) == NULL)
46534691
err(1, "malloc");
4654-
@@ -955,6 +986,11 @@
4692+
@@ -955,6 +999,11 @@
46554693
np->group = &np->data[ulen + 1];
46564694
(void)strcpy(np->group, group);
46574695

@@ -4663,7 +4701,7 @@
46634701
if (S_ISCHR(sp->st_mode) ||
46644702
S_ISBLK(sp->st_mode)) {
46654703
sizelen = snprintf(NULL, 0,
4666-
@@ -963,11 +999,6 @@
4704+
@@ -963,11 +1012,6 @@
46674705
d.s_size = sizelen;
46684706
}
46694707

@@ -4675,7 +4713,7 @@
46754713
if (f_label) {
46764714
np->label = &np->data[ulen + glen + 2
46774715
+ (f_flags ? flen + 1 : 0)];
4678-
@@ -1024,7 +1055,7 @@
4716+
@@ -1024,7 +1068,7 @@
46794717
* All other levels use the sort function. Error entries remain unsorted.
46804718
*/
46814719
static int
@@ -4684,6 +4722,16 @@
46844722
{
46854723
int a_info, b_info, dir;
46864724

4725+
--- src.orig/coreutils/ls/ls.h
4726+
+++ src.freebsd/coreutils/ls/ls.h
4727+
@@ -33,6 +33,7 @@
4728+
*/
4729+
4730+
#define NO_PRINT 1
4731+
+#define ERR_PRINT 2
4732+
4733+
#define HUMANVALSTR_LEN 5
4734+
46874735
--- src.orig/coreutils/ls/print.c
46884736
+++ src.freebsd/coreutils/ls/print.c
46894737
@@ -35,6 +35,7 @@
@@ -4703,16 +4751,70 @@
47034751
#include <unistd.h>
47044752
#include <wchar.h>
47054753
#ifdef COLORLS
4706-
@@ -249,7 +250,7 @@
4707-
if (f_accesstime)
4754+
@@ -73,6 +74,7 @@
4755+
static void aclmode(char *, const FTSENT *);
4756+
4757+
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
4758+
+#define IS_ERRPRINT(p) ((p)->fts_number == ERR_PRINT)
4759+
4760+
#ifdef COLORLS
4761+
/* Most of these are taken from <sys/stat.h> */
4762+
@@ -224,17 +226,27 @@
4763+
if (IS_NOPRINT(p))
4764+
continue;
4765+
sp = p->fts_statp;
4766+
- if (f_inode)
4767+
+ if (f_inode && IS_ERRPRINT(p))
4768+
+ (void)printf("%*s ", dp->s_inode, "?");
4769+
+ else if (f_inode)
4770+
(void)printf("%*ju ",
4771+
dp->s_inode, (uintmax_t)sp->st_ino);
4772+
- if (f_size)
4773+
+ if (f_size && IS_ERRPRINT(p))
4774+
+ (void)printf("%*s ", dp->s_block, "?");
4775+
+ else if (f_size)
4776+
(void)printf(f_thousands ? "%'*jd " : "%*jd ",
4777+
dp->s_block, howmany(sp->st_blocks, blocksize));
4778+
- strmode(sp->st_mode, buf);
4779+
+ if (IS_ERRPRINT(p))
4780+
+ memset(buf, '?', 10);
4781+
+ else
4782+
+ strmode(sp->st_mode, buf);
4783+
aclmode(buf, p);
4784+
np = p->fts_pointer;
4785+
- (void)printf("%s %*ju ", buf, dp->s_nlink,
4786+
- (uintmax_t)sp->st_nlink);
4787+
+ if (IS_ERRPRINT(p))
4788+
+ (void)printf("%s %*s ", buf, dp->s_nlink, "?");
4789+
+ else
4790+
+ (void)printf("%s %*ju ", buf, dp->s_nlink,
4791+
+ (uintmax_t)sp->st_nlink);
4792+
if (!f_sowner)
4793+
(void)printf("%-*s ", dp->s_user, np->user);
4794+
(void)printf("%-*s ", dp->s_group, np->group);
4795+
@@ -242,14 +254,18 @@
4796+
(void)printf("%-*s ", dp->s_flags, np->flags);
4797+
if (f_label)
4798+
(void)printf("%-*s ", dp->s_label, np->label);
4799+
- if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
4800+
+ if (IS_ERRPRINT(p))
4801+
+ (void)printf("%*s ", dp->s_size, "?");
4802+
+ else if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
4803+
printdev(dp->s_size, sp->st_rdev);
4804+
else
4805+
printsize(dp->s_size, sp->st_size);
4806+
- if (f_accesstime)
4807+
+ if (IS_ERRPRINT(p))
4808+
+ (void)printf(" ? ");
4809+
+ else if (f_accesstime)
47084810
printtime(sp->st_atime);
47094811
else if (f_birthtime)
47104812
- printtime(sp->st_birthtime);
47114813
+ printtime(sp->st_ctime);
47124814
else if (f_statustime)
47134815
printtime(sp->st_ctime);
47144816
else
4715-
@@ -454,7 +455,7 @@
4817+
@@ -454,7 +470,7 @@
47164818
}
47174819
}
47184820
if (tm != NULL)
@@ -4721,7 +4823,7 @@
47214823
else
47224824
strlcpy(str, "bad date val", len);
47234825
}
4724-
@@ -467,8 +468,11 @@
4826+
@@ -467,8 +483,11 @@
47254827
const char *format;
47264828
static int d_first = -1;
47274829

@@ -4735,7 +4837,7 @@
47354837
if (now == 0)
47364838
now = time(NULL);
47374839

4738-
@@ -514,9 +518,6 @@
4840+
@@ -514,9 +533,6 @@
47394841
case S_IFSOCK:
47404842
(void)putchar('=');
47414843
return (1);
@@ -4745,7 +4847,7 @@
47454847
default:
47464848
break;
47474849
}
4748-
@@ -774,18 +775,12 @@
4850+
@@ -774,18 +790,15 @@
47494851
aclmode(char *buf, const FTSENT *p)
47504852
{
47514853
char name[MAXPATHLEN + 1];
@@ -4761,13 +4863,16 @@
47614863
- * XXX: ACLs are not supported on whiteouts and device files
47624864
- * residing on UFS.
47634865
- */
4866+
+ if (IS_ERRPRINT(p))
4867+
+ return;
4868+
+
47644869
if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) ||
47654870
- S_ISWHT(p->fts_statp->st_mode))
47664871
+ S_ISLNK(p->fts_statp->st_mode))
47674872
return;
47684873

47694874
if (previous_dev == p->fts_statp->st_dev && supports_acls == 0)
4770-
@@ -800,7 +795,7 @@
4875+
@@ -800,7 +813,7 @@
47714876
if (previous_dev != p->fts_statp->st_dev) {
47724877
previous_dev = p->fts_statp->st_dev;
47734878
supports_acls = 0;
@@ -4776,7 +4881,7 @@
47764881
ret = lpathconf(name, _PC_ACL_NFS4);
47774882
if (ret > 0) {
47784883
type = ACL_TYPE_NFS4;
4779-
@@ -809,30 +804,24 @@
4884+
@@ -809,30 +822,24 @@
47804885
warn("%s", name);
47814886
return;
47824887
}

src.freebsd/coreutils/ls/ls.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ display(const FTSENT *p, FTSENT *list, int options __unused)
754754
char nuser[STRBUF_SIZEOF(gid_t) + 1];
755755
u_long width[9];
756756
int i;
757+
bool failent;
757758

758759
needstats = f_inode || f_longform || f_size;
759760
flen = 0;
@@ -810,10 +811,16 @@ display(const FTSENT *p, FTSENT *list, int options __unused)
810811
if (cur->fts_info == FTS_ERR || cur->fts_info == FTS_NS) {
811812
warnx("%s: %s",
812813
cur->fts_name, strerror(cur->fts_errno));
813-
cur->fts_number = NO_PRINT;
814814
rval = 1;
815-
continue;
816-
}
815+
if (cur->fts_errno != ENOTCONN && cur->fts_errno != EIO) {
816+
cur->fts_number = NO_PRINT;
817+
continue;
818+
}
819+
cur->fts_number = ERR_PRINT;
820+
/* zero out the structure just in case */
821+
memset(cur->fts_statp, 0, sizeof(*cur->fts_statp));
822+
failent = true;
823+
} else failent = false;
817824
/*
818825
* P is NULL if list is the argv list, to which different rules
819826
* apply.
@@ -852,7 +859,10 @@ display(const FTSENT *p, FTSENT *list, int options __unused)
852859

853860
btotal += sp->st_blocks;
854861
if (f_longform) {
855-
if (f_numericonly) {
862+
if (failent) {
863+
user = "?";
864+
group = "?";
865+
} else if (f_numericonly) {
856866
(void)snprintf(nuser, sizeof(nuser),
857867
"%u", sp->st_uid);
858868
(void)snprintf(ngroup, sizeof(ngroup),
@@ -902,7 +912,10 @@ display(const FTSENT *p, FTSENT *list, int options __unused)
902912
flen = 0;
903913
#endif
904914
labelstr = NULL;
905-
if (f_label) {
915+
if (f_label && failent) {
916+
labelstr = strdup("?");
917+
labelstrlen = 1;
918+
} else if (f_label) {
906919
#if 0
907920
char name[PATH_MAX + 1];
908921
mac_t label;

src.freebsd/coreutils/ls/ls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
*/
3434

3535
#define NO_PRINT 1
36+
#define ERR_PRINT 2
3637

3738
#define HUMANVALSTR_LEN 5
3839

src.freebsd/coreutils/ls/print.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static int colortype(mode_t);
7474
static void aclmode(char *, const FTSENT *);
7575

7676
#define IS_NOPRINT(p) ((p)->fts_number == NO_PRINT)
77+
#define IS_ERRPRINT(p) ((p)->fts_number == ERR_PRINT)
7778

7879
#ifdef COLORLS
7980
/* Most of these are taken from <sys/stat.h> */
@@ -225,29 +226,43 @@ printlong(const DISPLAY *dp)
225226
if (IS_NOPRINT(p))
226227
continue;
227228
sp = p->fts_statp;
228-
if (f_inode)
229+
if (f_inode && IS_ERRPRINT(p))
230+
(void)printf("%*s ", dp->s_inode, "?");
231+
else if (f_inode)
229232
(void)printf("%*ju ",
230233
dp->s_inode, (uintmax_t)sp->st_ino);
231-
if (f_size)
234+
if (f_size && IS_ERRPRINT(p))
235+
(void)printf("%*s ", dp->s_block, "?");
236+
else if (f_size)
232237
(void)printf(f_thousands ? "%'*jd " : "%*jd ",
233238
dp->s_block, howmany(sp->st_blocks, blocksize));
234-
strmode(sp->st_mode, buf);
239+
if (IS_ERRPRINT(p))
240+
memset(buf, '?', 10);
241+
else
242+
strmode(sp->st_mode, buf);
235243
aclmode(buf, p);
236244
np = p->fts_pointer;
237-
(void)printf("%s %*ju ", buf, dp->s_nlink,
238-
(uintmax_t)sp->st_nlink);
245+
if (IS_ERRPRINT(p))
246+
(void)printf("%s %*s ", buf, dp->s_nlink, "?");
247+
else
248+
(void)printf("%s %*ju ", buf, dp->s_nlink,
249+
(uintmax_t)sp->st_nlink);
239250
if (!f_sowner)
240251
(void)printf("%-*s ", dp->s_user, np->user);
241252
(void)printf("%-*s ", dp->s_group, np->group);
242253
if (f_flags)
243254
(void)printf("%-*s ", dp->s_flags, np->flags);
244255
if (f_label)
245256
(void)printf("%-*s ", dp->s_label, np->label);
246-
if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
257+
if (IS_ERRPRINT(p))
258+
(void)printf("%*s ", dp->s_size, "?");
259+
else if (S_ISCHR(sp->st_mode) || S_ISBLK(sp->st_mode))
247260
printdev(dp->s_size, sp->st_rdev);
248261
else
249262
printsize(dp->s_size, sp->st_size);
250-
if (f_accesstime)
263+
if (IS_ERRPRINT(p))
264+
(void)printf(" ? ");
265+
else if (f_accesstime)
251266
printtime(sp->st_atime);
252267
else if (f_birthtime)
253268
printtime(sp->st_ctime);
@@ -779,6 +794,9 @@ aclmode(char *buf, const FTSENT *p)
779794
static dev_t previous_dev = (dev_t)-1;
780795
static int supports_acls = -1;
781796

797+
if (IS_ERRPRINT(p))
798+
return;
799+
782800
if (S_ISCHR(p->fts_statp->st_mode) || S_ISBLK(p->fts_statp->st_mode) ||
783801
S_ISLNK(p->fts_statp->st_mode))
784802
return;

0 commit comments

Comments
 (0)