Appearance
ls.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"
#include "kernel/fcntl.h"
TIP
格式化文件名
char*
fmtname(char *path)
{
static char buf[DIRSIZ+1];
char *p;
TIP
找到最后一个斜杠后面的第一个字符
for(p=path+strlen(path); p >= path && *p != '/'; p--)
;
p++;
TIP
返回用空格填充的名称
if(strlen(p) >= DIRSIZ)
return p;
memmove(buf, p, strlen(p));
memset(buf+strlen(p), ' ', DIRSIZ-strlen(p));
return buf;
}
TIP
列出目录内容
void
ls(char *path)
{
char buf[512], *p;
int fd;
struct dirent de;
struct stat st;
TIP
打开路径
if((fd = open(path, O_RDONLY)) < 0){
fprintf(2, "ls: cannot open %s\n", path);
return;
}
TIP
获取文件状态
if(fstat(fd, &st) < 0){
fprintf(2, "ls: cannot stat %s\n", path);
close(fd);
return;
}
switch(st.type){
case T_DEVICE:
case T_FILE:
printf("%s %d %d %d\n", fmtname(path), st.type, st.ino, (int) st.size);
break;
case T_DIR:
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
printf("ls: path too long\n");
break;
}
strcpy(buf, path);
p = buf+strlen(buf);
*p++ = '/';TIP
读取目录项
while(read(fd, &de, sizeof(de)) == sizeof(de)){
if(de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;TIP
获取目录项的状态
if(stat(buf, &st) < 0){
printf("ls: cannot stat %s\n", buf);
continue;
}
printf("%s %d %d %d\n", fmtname(buf), st.type, st.ino, (int) st.size);
}
break;
}
close(fd);
}
TIP
程序入口
int
main(int argc, char *argv[])
{
int i;
TIP
如果没有参数,则列出当前目录
if(argc < 2){
ls(".");
exit(0);
}TIP
遍历所有参数(路径)
for(i=1; i<argc; i++)
ls(argv[i]);
exit(0);
}