diff options
| -rw-r--r-- | fs.c | 8 | ||||
| -rw-r--r-- | fstests.c | 2 | ||||
| -rw-r--r-- | ls.c | 30 | ||||
| -rw-r--r-- | proc.c | 4 | ||||
| -rw-r--r-- | sh.c | 14 | ||||
| -rw-r--r-- | syscall.c | 43 | ||||
| -rw-r--r-- | syscall.h | 1 | ||||
| -rw-r--r-- | trap.c | 2 | ||||
| -rw-r--r-- | user.h | 3 | ||||
| -rw-r--r-- | usertests.c | 2 | ||||
| -rw-r--r-- | usys.S | 1 | 
11 files changed, 90 insertions, 20 deletions
| @@ -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++; @@ -1,3 +1,5 @@ +#include "types.h" +#include "stat.h"  #include "user.h"  #include "fcntl.h" @@ -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') @@ -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;  } @@ -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';  } @@ -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 @@ -14,4 +14,5 @@  #define SYS_fstat 17  #define SYS_link 18  #define SYS_mkdir 19 +#define SYS_chdir 20 @@ -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;  } @@ -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" @@ -24,3 +24,4 @@ STUB(unlink)  STUB(fstat)  STUB(link)  STUB(mkdir) +STUB(chdir) | 
