ls: print filenames on the fly rather than in a buffer
This commit is contained in:
parent
60da4fb049
commit
441f73a518
48
ls.c
48
ls.c
|
@ -113,25 +113,20 @@ indicator(mode_t mode)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static void
|
||||||
makeprint(char *name)
|
printname(const char *name)
|
||||||
{
|
{
|
||||||
char *c, *u, *print = emalloc(strlen(name) + 1);
|
const char *c;
|
||||||
Rune r;
|
Rune r;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
for (c = print, u = name; *u; u += l) {
|
for (c = name; *c; c += l) {
|
||||||
l = chartorune(&r, u);
|
l = chartorune(&r, c);
|
||||||
if (isprintrune(r)) {
|
if (!qflag || isprintrune(r))
|
||||||
memcpy(c, u, l);
|
fwrite(c, 1, l, stdout);
|
||||||
c += l;
|
else
|
||||||
} else {
|
putchar('?');
|
||||||
*c++ = '?';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*c = '\0';
|
|
||||||
|
|
||||||
return print;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -142,14 +137,14 @@ output(const struct entry *ent)
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
char *fmt, buf[BUFSIZ], pwname[_SC_LOGIN_NAME_MAX],
|
char *fmt, buf[BUFSIZ], pwname[_SC_LOGIN_NAME_MAX],
|
||||||
grname[_SC_LOGIN_NAME_MAX], mode[] = "----------",
|
grname[_SC_LOGIN_NAME_MAX], mode[] = "----------";
|
||||||
*name = qflag ? makeprint(ent->name) : ent->name;
|
|
||||||
|
|
||||||
if (iflag)
|
if (iflag)
|
||||||
printf("%lu ", (unsigned long)ent->ino);
|
printf("%lu ", (unsigned long)ent->ino);
|
||||||
if (!lflag) {
|
if (!lflag) {
|
||||||
printf("%s%s\n", name, indicator(ent->mode));
|
printname(ent->name);
|
||||||
goto cleanup;
|
puts(indicator(ent->mode));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (S_ISREG(ent->mode))
|
if (S_ISREG(ent->mode))
|
||||||
mode[0] = '-';
|
mode[0] = '-';
|
||||||
|
@ -209,7 +204,9 @@ output(const struct entry *ent)
|
||||||
printf("%10s ", humansize(ent->size));
|
printf("%10s ", humansize(ent->size));
|
||||||
else
|
else
|
||||||
printf("%10lu ", (unsigned long)ent->size);
|
printf("%10lu ", (unsigned long)ent->size);
|
||||||
printf("%s %s%s", buf, name, indicator(ent->mode));
|
printf("%s ", buf);
|
||||||
|
printname(ent->name);
|
||||||
|
fputs(indicator(ent->mode), stdout);
|
||||||
if (S_ISLNK(ent->mode)) {
|
if (S_ISLNK(ent->mode)) {
|
||||||
if ((len = readlink(ent->name, buf, sizeof(buf) - 1)) < 0)
|
if ((len = readlink(ent->name, buf, sizeof(buf) - 1)) < 0)
|
||||||
eprintf("readlink %s:", ent->name);
|
eprintf("readlink %s:", ent->name);
|
||||||
|
@ -217,10 +214,6 @@ output(const struct entry *ent)
|
||||||
printf(" -> %s%s", buf, indicator(ent->tmode));
|
printf(" -> %s%s", buf, indicator(ent->tmode));
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (qflag)
|
|
||||||
free(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -252,7 +245,7 @@ lsdir(const char *path, const struct entry *dir)
|
||||||
struct entry *ent, *ents = NULL;
|
struct entry *ent, *ents = NULL;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
size_t i, n = 0;
|
size_t i, n = 0;
|
||||||
char prefix[PATH_MAX], *name;
|
char prefix[PATH_MAX];
|
||||||
|
|
||||||
if (!(dp = opendir(dir->name))) {
|
if (!(dp = opendir(dir->name))) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
@ -280,10 +273,9 @@ lsdir(const char *path, const struct entry *dir)
|
||||||
qsort(ents, n, sizeof(*ents), entcmp);
|
qsort(ents, n, sizeof(*ents), entcmp);
|
||||||
|
|
||||||
if (path[0] || showdirs) {
|
if (path[0] || showdirs) {
|
||||||
name = qflag ? makeprint(dir->name) : dir->name;
|
fputs(path, stdout);
|
||||||
printf("%s%s:\n", path, name);
|
printname(dir->name);
|
||||||
if (qflag)
|
puts(":");
|
||||||
free(name);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
output(&ents[i]);
|
output(&ents[i]);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user