From 8787cd01dfa6080d219f3dd7bbf03f3eb988a74e Mon Sep 17 00:00:00 2001 From: kaashoek Date: Sat, 19 Aug 2006 23:41:34 +0000 Subject: [PATCH] chdir cd in shell nits in mkdir, ls, etc. --- fs.c | 8 +++++++- fstests.c | 2 ++ ls.c | 30 ++++++++++++++++++++---------- proc.c | 4 ++-- sh.c | 14 ++++++++++---- syscall.c | 43 ++++++++++++++++++++++++++++++++++++++++++- syscall.h | 1 + trap.c | 2 +- user.h | 3 ++- usertests.c | 2 ++ usys.S | 1 + 11 files changed, 90 insertions(+), 20 deletions(-) diff --git a/fs.c b/fs.c index 530ef03..ed62970 100644 --- a/fs.c +++ b/fs.c @@ -385,6 +385,7 @@ struct inode * namei(char *path, int mode, uint *ret_off) { struct inode *dp; + struct proc *p = curproc[cpu()]; char *cp = path, *cp1; uint off, dev; struct buf *bp; @@ -392,7 +393,12 @@ namei(char *path, int mode, uint *ret_off) int i, atend; unsigned ninum; - dp = iget(rootdev, 1); + if (*cp == '/') dp = iget(rootdev, 1); + else { + dp = p->cwd; + iincref(dp); + ilock(dp); + } while(*cp == '/') cp++; diff --git a/fstests.c b/fstests.c index d6f630e..e428519 100644 --- a/fstests.c +++ b/fstests.c @@ -1,3 +1,5 @@ +#include "types.h" +#include "stat.h" #include "user.h" #include "fcntl.h" diff --git a/ls.c b/ls.c index 607a857..3441eba 100644 --- a/ls.c +++ b/ls.c @@ -15,22 +15,31 @@ main(int argc, char *argv[]) uint sz; int i; - if(argc > 1){ - puts("Usage: ls\n"); + if(argc > 2){ + puts("Usage: ls [dir]\n"); exit(); } - fd = open(".", 0); - if(fd < 0){ - printf(2, "ls: cannot open .\n"); - exit(); + if (argc == 2) { + fd = open(argv[1], 0); + if(fd < 0){ + 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) { - printf(2, "ls: cannot open .\n"); + printf(2, "ls: cannot stat dir\n"); exit(); } 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; for(off = 0; off < sz; off += sizeof(struct dirent)) { @@ -39,9 +48,10 @@ main(int argc, char *argv[]) break; } if (dirent.inum != 0) { + // xxx prepend to name the pathname supplied to ls (e.g. .. in ls ..) if (stat (dirent.name, &st) < 0) { - printf(1, "stat: failed\n"); - break; + printf(1, "stat: failed %s\n", dirent.name); + continue; } for (i = 0; i < DIRSIZ; i++) { if (dirent.name[i] != '\0') diff --git a/proc.c b/proc.c index a7908e2..9f7064f 100644 --- a/proc.c +++ b/proc.c @@ -132,8 +132,8 @@ copyproc(struct proc* p) fd_incref(np->fds[i]); } - // np->cwd = p->cwd; - // iincref(p->cwd); + np->cwd = p->cwd; + iincref(p->cwd); return np; } diff --git a/sh.c b/sh.c index e2b8959..9e0cb3f 100644 --- a/sh.c +++ b/sh.c @@ -15,15 +15,20 @@ main(void) while(1){ puts("$ "); + memset (buf, '\0', sizeof(buf)); gets(buf, sizeof(buf)); if(buf[0] == '\0') continue; pid = fork(); if(pid == 0){ parse(buf); - exec(buf, args); - printf(1, "%s: not found\n", buf); - exit(); + if (buf[0] == 'c' && buf[1] == 'd' && buf[2] == '\0') { // cd + chdir(&buf[3]); + } else { + exec(buf, args); + printf(1, "%s: not found\n", buf); + exit(); + } } if(pid > 0) wait(); @@ -39,11 +44,12 @@ parse(char buf[]) for (i = 0; buf[i] != '\0'; i++) { if (buf[i] == ' ') { buf[i] = '\0'; - args[j++] = buf + i+1; + args[j++] = buf + i + 1; if (j >= 100) { printf(2, "too many args\n"); exit(); } } } + args[j] = '\0'; } diff --git a/syscall.c b/syscall.c index 0a017c7..31b6189 100644 --- a/syscall.c +++ b/syscall.c @@ -309,7 +309,8 @@ sys_mkdir(void) return -1; nip = mknod (cp->mem + arg0, T_DIR, 0, 0); - + + memset (de.name, '\0', DIRSIZ); de.name[0] = '.'; de.inum = nip->inum; writei (nip, (char *) &de, 0, sizeof(de)); @@ -324,6 +325,43 @@ sys_mkdir(void) 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 sys_unlink(void) { @@ -599,6 +637,9 @@ syscall(void) case SYS_mkdir: ret = sys_mkdir(); break; + case SYS_chdir: + ret = sys_chdir(); + break; default: cprintf("unknown sys call %d\n", num); // XXX fault diff --git a/syscall.h b/syscall.h index d5e2dbe..2209cf2 100644 --- a/syscall.h +++ b/syscall.h @@ -14,4 +14,5 @@ #define SYS_fstat 17 #define SYS_link 18 #define SYS_mkdir 19 +#define SYS_chdir 20 diff --git a/trap.c b/trap.c index 9d1482f..d201990 100644 --- a/trap.c +++ b/trap.c @@ -128,7 +128,7 @@ trap(struct trapframe *tf) cprintf("trap %d from cpu %d eip %x\n", v, cpu(), tf->eip); if(curproc[cpu()]) cprintf("pid %d\n", curproc[cpu()]->pid); - panic("trap"); + // panic("trap"); return; } diff --git a/user.h b/user.h index 6022bc9..27f2cfb 100644 --- a/user.h +++ b/user.h @@ -17,8 +17,9 @@ int unlink (char*); int fstat (int fd, struct stat *stat); int link(char *, char *); int mkdir(char *); -int stat(char *, struct stat *stat); +int chdir(char *); +int stat(char *, struct stat *stat); int puts(char*); char* strcpy(char*, char*); void printf(int fd, char *fmt, ...); diff --git a/usertests.c b/usertests.c index 20155c2..0d3e2bc 100644 --- a/usertests.c +++ b/usertests.c @@ -1,3 +1,5 @@ +#include "types.h" +#include "stat.h" #include "user.h" #include "fcntl.h" diff --git a/usys.S b/usys.S index 8f93713..16d84e7 100644 --- a/usys.S +++ b/usys.S @@ -24,3 +24,4 @@ STUB(unlink) STUB(fstat) STUB(link) STUB(mkdir) +STUB(chdir)