chdir
cd in shell nits in mkdir, ls, etc.
This commit is contained in:
parent
ceb0e42796
commit
8787cd01df
11 changed files with 90 additions and 20 deletions
8
fs.c
8
fs.c
|
@ -385,6 +385,7 @@ struct inode *
|
||||||
namei(char *path, int mode, uint *ret_off)
|
namei(char *path, int mode, uint *ret_off)
|
||||||
{
|
{
|
||||||
struct inode *dp;
|
struct inode *dp;
|
||||||
|
struct proc *p = curproc[cpu()];
|
||||||
char *cp = path, *cp1;
|
char *cp = path, *cp1;
|
||||||
uint off, dev;
|
uint off, dev;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
@ -392,7 +393,12 @@ namei(char *path, int mode, uint *ret_off)
|
||||||
int i, atend;
|
int i, atend;
|
||||||
unsigned ninum;
|
unsigned ninum;
|
||||||
|
|
||||||
dp = iget(rootdev, 1);
|
if (*cp == '/') dp = iget(rootdev, 1);
|
||||||
|
else {
|
||||||
|
dp = p->cwd;
|
||||||
|
iincref(dp);
|
||||||
|
ilock(dp);
|
||||||
|
}
|
||||||
|
|
||||||
while(*cp == '/')
|
while(*cp == '/')
|
||||||
cp++;
|
cp++;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "stat.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
|
|
||||||
|
|
30
ls.c
30
ls.c
|
@ -15,22 +15,31 @@ main(int argc, char *argv[])
|
||||||
uint sz;
|
uint sz;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if(argc > 1){
|
if(argc > 2){
|
||||||
puts("Usage: ls\n");
|
puts("Usage: ls [dir]\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(".", 0);
|
if (argc == 2) {
|
||||||
if(fd < 0){
|
fd = open(argv[1], 0);
|
||||||
printf(2, "ls: cannot open .\n");
|
if(fd < 0){
|
||||||
exit();
|
printf(2, "ls: cannot open dir %s\n", argv[1]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fd = open(".", 0);
|
||||||
|
if(fd < 0){
|
||||||
|
printf(2, "ls: cannot open .\n");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, &st) < 0) {
|
if (fstat(fd, &st) < 0) {
|
||||||
printf(2, "ls: cannot open .\n");
|
printf(2, "ls: cannot stat dir\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
if (st.st_type != T_DIR) {
|
if (st.st_type != T_DIR) {
|
||||||
printf(2, "ls: . is not a dir\n");
|
printf(2, "ls: dir is not a directory\n");
|
||||||
}
|
}
|
||||||
sz = st.st_size;
|
sz = st.st_size;
|
||||||
for(off = 0; off < sz; off += sizeof(struct dirent)) {
|
for(off = 0; off < sz; off += sizeof(struct dirent)) {
|
||||||
|
@ -39,9 +48,10 @@ main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dirent.inum != 0) {
|
if (dirent.inum != 0) {
|
||||||
|
// xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..)
|
||||||
if (stat (dirent.name, &st) < 0) {
|
if (stat (dirent.name, &st) < 0) {
|
||||||
printf(1, "stat: failed\n");
|
printf(1, "stat: failed %s\n", dirent.name);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
for (i = 0; i < DIRSIZ; i++) {
|
for (i = 0; i < DIRSIZ; i++) {
|
||||||
if (dirent.name[i] != '\0')
|
if (dirent.name[i] != '\0')
|
||||||
|
|
4
proc.c
4
proc.c
|
@ -132,8 +132,8 @@ copyproc(struct proc* p)
|
||||||
fd_incref(np->fds[i]);
|
fd_incref(np->fds[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// np->cwd = p->cwd;
|
np->cwd = p->cwd;
|
||||||
// iincref(p->cwd);
|
iincref(p->cwd);
|
||||||
|
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
14
sh.c
14
sh.c
|
@ -15,15 +15,20 @@ main(void)
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
puts("$ ");
|
puts("$ ");
|
||||||
|
memset (buf, '\0', sizeof(buf));
|
||||||
gets(buf, sizeof(buf));
|
gets(buf, sizeof(buf));
|
||||||
if(buf[0] == '\0')
|
if(buf[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid == 0){
|
||||||
parse(buf);
|
parse(buf);
|
||||||
exec(buf, args);
|
if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == '\0') { // cd
|
||||||
printf(1, "%s: not found\n", buf);
|
chdir(&buf[3]);
|
||||||
exit();
|
} else {
|
||||||
|
exec(buf, args);
|
||||||
|
printf(1, "%s: not found\n", buf);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(pid > 0)
|
if(pid > 0)
|
||||||
wait();
|
wait();
|
||||||
|
@ -39,11 +44,12 @@ parse(char buf[])
|
||||||
for (i = 0; buf[i] != '\0'; i++) {
|
for (i = 0; buf[i] != '\0'; i++) {
|
||||||
if (buf[i] == ' ') {
|
if (buf[i] == ' ') {
|
||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
args[j++] = buf + i+1;
|
args[j++] = buf + i + 1;
|
||||||
if (j >= 100) {
|
if (j >= 100) {
|
||||||
printf(2, "too many args\n");
|
printf(2, "too many args\n");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
args[j] = '\0';
|
||||||
}
|
}
|
||||||
|
|
41
syscall.c
41
syscall.c
|
@ -310,6 +310,7 @@ sys_mkdir(void)
|
||||||
|
|
||||||
nip = mknod (cp->mem + arg0, T_DIR, 0, 0);
|
nip = mknod (cp->mem + arg0, T_DIR, 0, 0);
|
||||||
|
|
||||||
|
memset (de.name, '\0', DIRSIZ);
|
||||||
de.name[0] = '.';
|
de.name[0] = '.';
|
||||||
de.inum = nip->inum;
|
de.inum = nip->inum;
|
||||||
writei (nip, (char *) &de, 0, sizeof(de));
|
writei (nip, (char *) &de, 0, sizeof(de));
|
||||||
|
@ -324,6 +325,43 @@ sys_mkdir(void)
|
||||||
return (nip == 0) ? -1 : 0;
|
return (nip == 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sys_chdir(void)
|
||||||
|
{
|
||||||
|
struct proc *cp = curproc[cpu()];
|
||||||
|
struct inode *ip;
|
||||||
|
uint arg0;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
if(fetcharg(0, &arg0) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if((l = checkstring(arg0)) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if(l >= DIRSIZ)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0)) == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ip == cp->cwd) {
|
||||||
|
iput (ip);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip->type != T_DIR) {
|
||||||
|
iput(ip);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
idecref(cp->cwd);
|
||||||
|
cp->cwd = ip;
|
||||||
|
iunlock(cp->cwd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sys_unlink(void)
|
sys_unlink(void)
|
||||||
{
|
{
|
||||||
|
@ -599,6 +637,9 @@ syscall(void)
|
||||||
case SYS_mkdir:
|
case SYS_mkdir:
|
||||||
ret = sys_mkdir();
|
ret = sys_mkdir();
|
||||||
break;
|
break;
|
||||||
|
case SYS_chdir:
|
||||||
|
ret = sys_chdir();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cprintf("unknown sys call %d\n", num);
|
cprintf("unknown sys call %d\n", num);
|
||||||
// XXX fault
|
// XXX fault
|
||||||
|
|
|
@ -14,4 +14,5 @@
|
||||||
#define SYS_fstat 17
|
#define SYS_fstat 17
|
||||||
#define SYS_link 18
|
#define SYS_link 18
|
||||||
#define SYS_mkdir 19
|
#define SYS_mkdir 19
|
||||||
|
#define SYS_chdir 20
|
||||||
|
|
||||||
|
|
2
trap.c
2
trap.c
|
@ -128,7 +128,7 @@ trap(struct trapframe *tf)
|
||||||
cprintf("trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);
|
cprintf("trap %d from cpu %d eip %x\n", v, cpu(), tf->eip);
|
||||||
if(curproc[cpu()])
|
if(curproc[cpu()])
|
||||||
cprintf("pid %d\n", curproc[cpu()]->pid);
|
cprintf("pid %d\n", curproc[cpu()]->pid);
|
||||||
panic("trap");
|
// panic("trap");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
3
user.h
3
user.h
|
@ -17,8 +17,9 @@ int unlink (char*);
|
||||||
int fstat (int fd, struct stat *stat);
|
int fstat (int fd, struct stat *stat);
|
||||||
int link(char *, char *);
|
int link(char *, char *);
|
||||||
int mkdir(char *);
|
int mkdir(char *);
|
||||||
int stat(char *, struct stat *stat);
|
int chdir(char *);
|
||||||
|
|
||||||
|
int stat(char *, struct stat *stat);
|
||||||
int puts(char*);
|
int puts(char*);
|
||||||
char* strcpy(char*, char*);
|
char* strcpy(char*, char*);
|
||||||
void printf(int fd, char *fmt, ...);
|
void printf(int fd, char *fmt, ...);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include "types.h"
|
||||||
|
#include "stat.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "fcntl.h"
|
#include "fcntl.h"
|
||||||
|
|
||||||
|
|
1
usys.S
1
usys.S
|
@ -24,3 +24,4 @@ STUB(unlink)
|
||||||
STUB(fstat)
|
STUB(fstat)
|
||||||
STUB(link)
|
STUB(link)
|
||||||
STUB(mkdir)
|
STUB(mkdir)
|
||||||
|
STUB(chdir)
|
||||||
|
|
Loading…
Reference in a new issue