summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs.c8
-rw-r--r--fstests.c2
-rw-r--r--ls.c30
-rw-r--r--proc.c4
-rw-r--r--sh.c14
-rw-r--r--syscall.c43
-rw-r--r--syscall.h1
-rw-r--r--trap.c2
-rw-r--r--user.h3
-rw-r--r--usertests.c2
-rw-r--r--usys.S1
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)