Opimizing tar, adding U flag
This commit is contained in:
parent
c5f10c4b06
commit
cd1526715f
5
ls.1
5
ls.1
|
@ -3,7 +3,7 @@
|
||||||
ls \- list directory contents
|
ls \- list directory contents
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B ls
|
.B ls
|
||||||
.RB [ \-adlt ]
|
.RB [ \-adltU ]
|
||||||
.RI [ file ...]
|
.RI [ file ...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B ls
|
.B ls
|
||||||
|
@ -23,5 +23,8 @@ links, owner, group, size, and modification time.
|
||||||
.TP
|
.TP
|
||||||
.B \-t
|
.B \-t
|
||||||
sorts files by modification time instead of by name.
|
sorts files by modification time instead of by name.
|
||||||
|
.TP
|
||||||
|
.B \-U
|
||||||
|
keeps the list unsorted.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.IR stat (2)
|
.IR stat (2)
|
||||||
|
|
100
ls.c
100
ls.c
|
@ -22,29 +22,30 @@ typedef struct {
|
||||||
time_t mtime;
|
time_t mtime;
|
||||||
} Entry;
|
} Entry;
|
||||||
|
|
||||||
static int entcmp(Entry *, Entry *);
|
static int entcmp(const void *, const void *);
|
||||||
static void ls(char *);
|
static void ls(Entry *);
|
||||||
static void lsdir(const char *);
|
static void lsdir(const char *);
|
||||||
static void mkent(Entry *, char *);
|
static void mkent(Entry *, char *, bool);
|
||||||
static void output(Entry *);
|
static void output(Entry *);
|
||||||
|
|
||||||
static bool aflag = false;
|
static bool aflag = false;
|
||||||
static bool dflag = false;
|
static bool dflag = false;
|
||||||
static bool lflag = false;
|
static bool lflag = false;
|
||||||
static bool tflag = false;
|
static bool tflag = false;
|
||||||
|
static bool Uflag = false;
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
static bool many;
|
static bool many;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: %s [-adlt] [FILE...]\n", argv0);
|
eprintf("usage: %s [-adltU] [FILE...]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i, n;
|
int i;
|
||||||
Entry *ents;
|
Entry *ents;
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
|
@ -60,31 +61,33 @@ main(int argc, char *argv[])
|
||||||
case 't':
|
case 't':
|
||||||
tflag = true;
|
tflag = true;
|
||||||
break;
|
break;
|
||||||
|
case 'U':
|
||||||
|
Uflag = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
} ARGEND;
|
} ARGEND;
|
||||||
|
|
||||||
many = (argc > 1);
|
many = (argc > 1);
|
||||||
|
if(argc == 0)
|
||||||
|
*--argv = ".", argc++;
|
||||||
|
|
||||||
if((n = argc) > 0) {
|
if(!(ents = malloc(argc * sizeof *ents)))
|
||||||
if(!(ents = malloc(n * sizeof *ents)))
|
eprintf("malloc:");
|
||||||
eprintf("malloc:");
|
for(i = 0; i < argc; i++)
|
||||||
for(i = 0; i < n; i++)
|
mkent(&ents[i], argv[i], true);
|
||||||
mkent(&ents[i], argv[i]);
|
qsort(ents, argc, sizeof *ents, entcmp);
|
||||||
qsort(ents, n, sizeof *ents,
|
for(i = 0; i < argc; i++)
|
||||||
(int (*)(const void *, const void *))entcmp);
|
ls(&ents[i]);
|
||||||
for(i = 0; i < n; i++)
|
|
||||||
ls(ents[i].name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ls(".");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
entcmp(Entry *a, Entry *b)
|
entcmp(const void *va, const void *vb)
|
||||||
{
|
{
|
||||||
|
const Entry *a = va, *b = vb;
|
||||||
|
|
||||||
if(tflag)
|
if(tflag)
|
||||||
return b->mtime - a->mtime;
|
return b->mtime - a->mtime;
|
||||||
else
|
else
|
||||||
|
@ -92,15 +95,13 @@ entcmp(Entry *a, Entry *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ls(char *path)
|
ls(Entry *ent)
|
||||||
{
|
{
|
||||||
Entry ent;
|
if(S_ISDIR(ent->mode) && !dflag) {
|
||||||
|
lsdir(ent->name);
|
||||||
mkent(&ent, path);
|
} else {
|
||||||
if(S_ISDIR(ent.mode) && !dflag)
|
output(ent);
|
||||||
lsdir(path);
|
}
|
||||||
else
|
|
||||||
output(&ent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -110,7 +111,7 @@ lsdir(const char *path)
|
||||||
long i, n = 0;
|
long i, n = 0;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
Entry *ents = NULL;
|
Entry ent, *ents = NULL;
|
||||||
|
|
||||||
cwd = agetcwd();
|
cwd = agetcwd();
|
||||||
if(!(dp = opendir(path)))
|
if(!(dp = opendir(path)))
|
||||||
|
@ -118,28 +119,35 @@ lsdir(const char *path)
|
||||||
if(chdir(path) == -1)
|
if(chdir(path) == -1)
|
||||||
eprintf("chdir %s:", path);
|
eprintf("chdir %s:", path);
|
||||||
|
|
||||||
while((d = readdir(dp))) {
|
|
||||||
if(d->d_name[0] == '.' && !aflag)
|
|
||||||
continue;
|
|
||||||
if(!(ents = realloc(ents, ++n * sizeof *ents)))
|
|
||||||
eprintf("realloc:");
|
|
||||||
if(!(p = malloc(strlen(d->d_name)+1)))
|
|
||||||
eprintf("malloc:");
|
|
||||||
strcpy(p, d->d_name);
|
|
||||||
mkent(&ents[n-1], p);
|
|
||||||
}
|
|
||||||
closedir(dp);
|
|
||||||
qsort(ents, n, sizeof *ents, (int (*)(const void *, const void *))entcmp);
|
|
||||||
|
|
||||||
if(many) {
|
if(many) {
|
||||||
if(!first)
|
if(!first)
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
printf("%s:\n", path);
|
printf("%s:\n", path);
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
for(i = 0; i < n; i++) {
|
|
||||||
output(&ents[i]);
|
while((d = readdir(dp))) {
|
||||||
free(ents[i].name);
|
if(d->d_name[0] == '.' && !aflag)
|
||||||
|
continue;
|
||||||
|
if(Uflag){
|
||||||
|
mkent(&ent, d->d_name, lflag);
|
||||||
|
output(&ent);
|
||||||
|
} else {
|
||||||
|
if(!(ents = realloc(ents, ++n * sizeof *ents)))
|
||||||
|
eprintf("realloc:");
|
||||||
|
if(!(p = malloc(strlen(d->d_name)+1)))
|
||||||
|
eprintf("malloc:");
|
||||||
|
strcpy(p, d->d_name);
|
||||||
|
mkent(&ents[n-1], p, tflag || lflag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dp);
|
||||||
|
if(!Uflag){
|
||||||
|
qsort(ents, n, sizeof *ents, entcmp);
|
||||||
|
for(i = 0; i < n; i++) {
|
||||||
|
output(&ents[i]);
|
||||||
|
free(ents[i].name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(chdir(cwd) == -1)
|
if(chdir(cwd) == -1)
|
||||||
eprintf("chdir %s:", cwd);
|
eprintf("chdir %s:", cwd);
|
||||||
|
@ -148,13 +156,15 @@ lsdir(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mkent(Entry *ent, char *path)
|
mkent(Entry *ent, char *path, bool dostat)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
ent->name = path;
|
||||||
|
if(!dostat)
|
||||||
|
return;
|
||||||
if(lstat(path, &st) == -1)
|
if(lstat(path, &st) == -1)
|
||||||
eprintf("lstat %s:", path);
|
eprintf("lstat %s:", path);
|
||||||
ent->name = path;
|
|
||||||
ent->mode = st.st_mode;
|
ent->mode = st.st_mode;
|
||||||
ent->nlink = st.st_nlink;
|
ent->nlink = st.st_nlink;
|
||||||
ent->uid = st.st_uid;
|
ent->uid = st.st_uid;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user