mirror of
https://github.com/SmallPond/MIT6.828_OS.git
synced 2026-04-29 21:31:05 +08:00
my solution to lab5
This commit is contained in:
91
lab/user/ls.c
Normal file
91
lab/user/ls.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#include <inc/lib.h>
|
||||
|
||||
int flag[256];
|
||||
|
||||
void lsdir(const char*, const char*);
|
||||
void ls1(const char*, bool, off_t, const char*);
|
||||
|
||||
void
|
||||
ls(const char *path, const char *prefix)
|
||||
{
|
||||
int r;
|
||||
struct Stat st;
|
||||
|
||||
if ((r = stat(path, &st)) < 0)
|
||||
panic("stat %s: %e", path, r);
|
||||
if (st.st_isdir && !flag['d'])
|
||||
lsdir(path, prefix);
|
||||
else
|
||||
ls1(0, st.st_isdir, st.st_size, path);
|
||||
}
|
||||
|
||||
void
|
||||
lsdir(const char *path, const char *prefix)
|
||||
{
|
||||
int fd, n;
|
||||
struct File f;
|
||||
|
||||
if ((fd = open(path, O_RDONLY)) < 0)
|
||||
panic("open %s: %e", path, fd);
|
||||
while ((n = readn(fd, &f, sizeof f)) == sizeof f)
|
||||
if (f.f_name[0])
|
||||
ls1(prefix, f.f_type==FTYPE_DIR, f.f_size, f.f_name);
|
||||
if (n > 0)
|
||||
panic("short read in directory %s", path);
|
||||
if (n < 0)
|
||||
panic("error reading directory %s: %e", path, n);
|
||||
}
|
||||
|
||||
void
|
||||
ls1(const char *prefix, bool isdir, off_t size, const char *name)
|
||||
{
|
||||
const char *sep;
|
||||
|
||||
if(flag['l'])
|
||||
printf("%11d %c ", size, isdir ? 'd' : '-');
|
||||
if(prefix) {
|
||||
if (prefix[0] && prefix[strlen(prefix)-1] != '/')
|
||||
sep = "/";
|
||||
else
|
||||
sep = "";
|
||||
printf("%s%s", prefix, sep);
|
||||
}
|
||||
printf("%s", name);
|
||||
if(flag['F'] && isdir)
|
||||
printf("/");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf("usage: ls [-dFl] [file...]\n");
|
||||
exit();
|
||||
}
|
||||
|
||||
void
|
||||
umain(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
struct Argstate args;
|
||||
|
||||
argstart(&argc, argv, &args);
|
||||
while ((i = argnext(&args)) >= 0)
|
||||
switch (i) {
|
||||
case 'd':
|
||||
case 'F':
|
||||
case 'l':
|
||||
flag[i]++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
ls("/", "");
|
||||
else {
|
||||
for (i = 1; i < argc; i++)
|
||||
ls(argv[i], argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user