diff options
| author | rsc <rsc> | 2006-09-06 18:19:11 +0000 | 
|---|---|---|
| committer | rsc <rsc> | 2006-09-06 18:19:11 +0000 | 
| commit | 2685309fb47a0f60d3b59138d8029c5d901fde91 (patch) | |
| tree | cce8197ed0d7d31a4068297e58920bb3ef239164 | |
| parent | 61d03d0eeff3137a6453a773dfe8a51746804920 (diff) | |
| download | xv6-labs-2685309fb47a0f60d3b59138d8029c5d901fde91.tar.gz xv6-labs-2685309fb47a0f60d3b59138d8029c5d901fde91.tar.bz2 xv6-labs-2685309fb47a0f60d3b59138d8029c5d901fde91.zip | |
split syscall.c into sysfile.c and sysproc.c
| -rw-r--r-- | defs.h | 5 | ||||
| -rw-r--r-- | syscall.c | 536 | ||||
| -rw-r--r-- | syscall.h | 34 | ||||
| -rw-r--r-- | sysfile.c | 477 | ||||
| -rw-r--r-- | sysproc.c | 72 | 
5 files changed, 590 insertions, 534 deletions
| @@ -42,6 +42,11 @@ int strncmp(const char*, const char*, uint);  // syscall.c  void syscall(void); +int fetchint(struct proc*, uint, int*); +int fetchbyte(struct proc*, uint, char*); +int fetcharg(int, void*); +int checkstring(uint); +int putint(struct proc*, uint, int);  // picirq.c  void pic_init(void); @@ -81,523 +81,25 @@ putint(struct proc *p, uint addr, int x)    return 0;  } -int -sys_pipe(void) -{ -  struct fd *rfd = 0, *wfd = 0; -  int f1 = -1, f2 = -1; -  struct proc *p = curproc[cpu()]; -  uint fdp; - -  if(pipe_alloc(&rfd, &wfd) < 0) -    goto oops; -  if((f1 = fd_ualloc()) < 0) -    goto oops; -  p->fds[f1] = rfd; -  if((f2 = fd_ualloc()) < 0) -    goto oops; -  p->fds[f2] = wfd; -  if(fetcharg(0, &fdp) < 0) -    goto oops; -  if(putint(p, fdp, f1) < 0) -    goto oops; -  if(putint(p, fdp+4, f2) < 0) -    goto oops; -  return 0; - - oops: -  if(rfd) -    fd_close(rfd); -  if(wfd) -    fd_close(wfd); -  if(f1 >= 0) -    p->fds[f1] = 0; -  if(f2 >= 0) -    p->fds[f2] = 0; -  return -1; -} - -int -sys_write(void) -{ -  int fd, n, ret; -  uint addr; -  struct proc *p = curproc[cpu()]; - -  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0) -    return -1; -  if(fd < 0 || fd >= NOFILE) -    return -1; -  if(p->fds[fd] == 0) -    return -1; -  if(addr + n > p->sz) -    return -1; - -  ret = fd_write(p->fds[fd], p->mem + addr, n); -  return ret; -} - -int -sys_read(void) -{ -  int fd, n, ret; -  uint addr; -  struct proc *p = curproc[cpu()]; - -  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0) -    return -1; -  if(fd < 0 || fd >= NOFILE) -    return -1; -  if(p->fds[fd] == 0) -    return -1; -  if(addr + n > p->sz) -    return -1; -  ret = fd_read(p->fds[fd], p->mem + addr, n); -  return ret; -} - -int -sys_close(void) -{ -  int fd; -  struct proc *p = curproc[cpu()]; - -  if(fetcharg(0, &fd) < 0) -    return -1; -  if(fd < 0 || fd >= NOFILE) -    return -1; -  if(p->fds[fd] == 0) -    return -1; -  fd_close(p->fds[fd]); -  p->fds[fd] = 0; -  return 0; -} - -int -sys_fork(void) -{ -  struct proc *np; - -  if((np = copyproc(curproc[cpu()])) == 0) -    return -1; -  np->state = RUNNABLE; -  return np->pid; -} - -int -sys_exit(void) -{ -  proc_exit(); -  return 0;  // not reached -} - -int -sys_wait(void) -{ -  return proc_wait(); -} - -int -sys_kill(void) -{ -  int pid; - -  if(fetcharg(0, &pid) < 0) -    return -1; -  return proc_kill(pid); -} - -int -sys_open(void) -{ -  struct proc *cp = curproc[cpu()]; -  struct inode *ip, *dp; -  uint arg0, arg1; -  int ufd; -  struct fd *fd; -  int l; -  char *last; - -  if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0) -    return -1; -  if((l = checkstring(arg0)) < 0) -    return -1; - -  if(arg1 & O_CREATE){ -    dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, &ip); -    if(dp){ -      ip = mknod1(dp, last, T_FILE, 0, 0); -      iput(dp); -      if(ip == 0) -        return -1; -    } else if(ip == 0){ -      return -1; -    } else if(ip->type == T_DIR){ -      iput(ip); -      return -1; -    } -  } else { -    ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0); -    if(ip == 0) -      return -1; -  } -  if(ip->type == T_DIR && ((arg1 & O_RDWR) || (arg1 & O_WRONLY))){ -    iput(ip); -    return -1; -  } - -  if((fd = fd_alloc()) == 0){ -    iput(ip); -    return -1; -  } -  if((ufd = fd_ualloc()) < 0){ -    iput(ip); -    fd_close(fd); -    return -1; -  } - -  iunlock(ip); -  fd->type = FD_FILE; -  if(arg1 & O_RDWR) { -    fd->readable = 1; -    fd->writable = 1; -  } else if(arg1 & O_WRONLY) { -    fd->readable = 0; -    fd->writable = 1; -  } else { -    fd->readable = 1; -    fd->writable = 0; -  } -  fd->ip = ip; -  fd->off = 0; -  cp->fds[ufd] = fd; - -  return ufd; -} - -int -sys_mknod(void) -{ -  struct proc *cp = curproc[cpu()]; -  struct inode *nip; -  uint arg0, arg1, arg2, arg3; -  int l; - -  if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 || -     fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0) -    return -1; - -  if((l = checkstring(arg0)) < 0) -    return -1; - -  if(l >= DIRSIZ) -    return -1; - -  nip = mknod(cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3); -  if(nip) -    iput(nip); -  return (nip == 0) ? -1 : 0; -} - -int -sys_mkdir(void) -{ -  struct proc *cp = curproc[cpu()]; -  struct inode *nip; -  struct inode *dp; -  uint arg0; -  int l; -  struct dirent de; -  char *last; - -  if(fetcharg(0, &arg0) < 0) -    return -1; - -  if((l = checkstring(arg0)) < 0) -    return -1; - -  dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, 0); -  if(dp == 0) -    return -1; - -  nip = mknod1(dp, last, T_DIR, 0, 0); -  if(nip == 0){ -    iput(dp); -    return -1; -  } - -  dp->nlink += 1; -  iupdate(dp); - -  memset(de.name, '\0', DIRSIZ); -  de.name[0] = '.'; -  de.inum = nip->inum; -  writei(nip, (char*) &de, 0, sizeof(de)); - -  de.inum = dp->inum; -  de.name[1] = '.'; -  writei(nip, (char*) &de, sizeof(de), sizeof(de)); - -  iput(dp); -  iput(nip); - -  return 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((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0) -    return -1; - -  if(ip == cp->cwd) { -    iput(ip); -    return 0; -  } - -  if(ip->type != T_DIR) { -    iput(ip); -    return -1; -  } - -  idecref(cp->cwd); -  cp->cwd = ip; -  iunlock(cp->cwd); -  return 0; -} - -int -sys_unlink(void) -{ -  struct proc *cp = curproc[cpu()]; -  uint arg0; -  int r; - -  if(fetcharg(0, &arg0) < 0) -    return -1; -  if(checkstring(arg0) < 0) -    return -1; -  r = unlink(cp->mem + arg0); -  return r; -} - -int -sys_fstat(void) -{ -  struct proc *cp = curproc[cpu()]; -  uint fd, addr; -  int r; - -  if(fetcharg(0, &fd) < 0) -    return -1; -  if(fetcharg(1, &addr) < 0) -    return -1; -  if(fd < 0 || fd >= NOFILE) -    return -1; -  if(cp->fds[fd] == 0) -    return -1; -  if(addr + sizeof(struct stat) > cp->sz) -    return -1; -  r = fd_stat(cp->fds[fd], (struct stat*)(cp->mem + addr)); -  return r; -} - -int -sys_dup(void) -{ -  struct proc *cp = curproc[cpu()]; -  uint fd, ufd1; - -  if(fetcharg(0, &fd) < 0) -    return -1; -  if(fd < 0 || fd >= NOFILE) -    return -1; -  if(cp->fds[fd] == 0) -    return -1; -  if((ufd1 = fd_ualloc()) < 0) -    return -1; -  cp->fds[ufd1] = cp->fds[fd]; -  fd_incref(cp->fds[ufd1]); -  return ufd1; -} - -int -sys_link(void) -{ -  struct proc *cp = curproc[cpu()]; -  uint name1, name2; -  int r; - -  if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0) -    return -1; -  if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0) -    return -1; -  r = link(cp->mem + name1, cp->mem + name2); -  return r; -} - -int -sys_getpid(void) -{ -  struct proc *cp = curproc[cpu()]; -  return cp->pid; -} - - -int -sys_sbrk(void) -{ -  uint addr; -  int n; -  struct proc *cp = curproc[cpu()]; - -  if(fetcharg(0, &n) < 0) -    return -1; -  if((addr = growproc(n)) == 0xffffffff) -    return -1; -  setupsegs(cp); -  return addr; -} - -int -sys_exec(void) -{ -  struct proc *cp = curproc[cpu()]; -  uint arg0, arg1, sz=0, ap, sp, p1, p2; -  int i, nargs, argbytes, len; -  struct inode *ip; -  struct elfhdr elf; -  struct proghdr ph; -  char *mem = 0; - -  if(fetcharg(0, &arg0) < 0) -    return -1; -  if(fetcharg(1, &arg1) < 0) -    return -1; -  if(checkstring(arg0) < 0) -    return -1; -  ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0); -  if(ip == 0) -    return -1; - -  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) -    goto bad; - -  if(elf.magic != ELF_MAGIC) -    goto bad; - -  sz = 0; -  for(i = 0; i < elf.phnum; i++){ -    if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph), -             sizeof(ph)) != sizeof(ph)) -      goto bad; -    if(ph.type != ELF_PROG_LOAD) -      continue; -    if(ph.memsz < ph.filesz) -      goto bad; -    sz += ph.memsz; -  } - -  sz += 4096 - (sz % 4096); -  sz += 4096; - -  mem = kalloc(sz); -  if(mem == 0) -    goto bad; -  memset(mem, 0, sz); - -  // arg1 is a pointer to an array of pointers to string. -  nargs = 0; -  argbytes = 0; -  for(i = 0; ; i++){ -    if(fetchint(cp, arg1 + 4*i, &ap) < 0) -      goto bad; -    if(ap == 0) -      break; -    len = checkstring(ap); -    if(len < 0) -      goto bad; -    nargs++; -    argbytes += len + 1; -  } - -  // argn\0 -  // ... -  // arg0\0 -  // 0 -  // ptr to argn -  // ... -  // 12: ptr to arg0 -  //  8: argv (points to ptr to arg0) -  //  4: argc -  //  0: fake return pc -  sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4; -  *(uint*)(mem + sp) = 0xffffffff; -  *(uint*)(mem + sp + 4) = nargs; -  *(uint*)(mem + sp + 8) = (uint)(sp + 12); - -  p1 = sp + 12; -  p2 = sp + 12 + (nargs + 1) * 4; -  for(i = 0; i < nargs; i++){ -    fetchint(cp, arg1 + 4*i, &ap); -    len = checkstring(ap); -    memmove(mem + p2, cp->mem + ap, len + 1); -    *(uint*)(mem + p1) = p2; -    p1 += 4; -    p2 += len + 1; -  } -  *(uint*)(mem + p1) = 0; - -  // commit to the new image. -  kfree(cp->mem, cp->sz); -  cp->sz = sz; -  cp->mem = mem; -  mem = 0; - -  for(i = 0; i < elf.phnum; i++){ -    if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph), -             sizeof(ph)) != sizeof(ph)) -      goto bad2; -    if(ph.type != ELF_PROG_LOAD) -      continue; -    if(ph.va + ph.memsz > sz) -      goto bad2; -    if(readi(ip, cp->mem + ph.va, ph.offset, ph.filesz) != ph.filesz) -      goto bad2; -    memset(cp->mem + ph.va + ph.filesz, 0, ph.memsz - ph.filesz); -  } - -  iput(ip); - -  cp->tf->eip = elf.entry; -  cp->tf->esp = sp; -  setupsegs(cp); - -  return 0; - - bad: -  if(mem) -    kfree(mem, sz); -  iput(ip); -  return -1; - - bad2: -  iput(ip); -  proc_exit(); -  return 0; -} +extern int sys_chdir(void); +extern int sys_close(void); +extern int sys_dup(void); +extern int sys_exec(void); +extern int sys_exit(void); +extern int sys_fork(void); +extern int sys_fstat(void); +extern int sys_getpid(void); +extern int sys_kill(void); +extern int sys_link(void); +extern int sys_mkdir(void); +extern int sys_mknod(void); +extern int sys_open(void); +extern int sys_pipe(void); +extern int sys_read(void); +extern int sys_sbrk(void); +extern int sys_unlink(void); +extern int sys_wait(void); +extern int sys_write(void);  void  syscall(void) @@ -1,20 +1,20 @@ -#define SYS_fork 1 -#define SYS_exit 2 -#define SYS_wait 3 -#define SYS_pipe 4 -#define SYS_write 5 -#define SYS_read 6 -#define SYS_close 7 -#define SYS_kill 9 -#define SYS_exec 10 -#define SYS_open 11 -#define SYS_mknod 12 +#define SYS_fork    1 +#define SYS_exit    2 +#define SYS_wait    3 +#define SYS_pipe    4 +#define SYS_write   5 +#define SYS_read    6 +#define SYS_close   7 +#define SYS_kill    9 +#define SYS_exec   10 +#define SYS_open   11 +#define SYS_mknod  12  #define SYS_unlink 13 -#define SYS_fstat 14 -#define SYS_link 15 -#define SYS_mkdir 16 -#define SYS_chdir 17 -#define SYS_dup 18 +#define SYS_fstat  14 +#define SYS_link   15 +#define SYS_mkdir  16 +#define SYS_chdir  17 +#define SYS_dup    18  #define SYS_getpid 19 -#define SYS_sbrk 20 +#define SYS_sbrk   20 diff --git a/sysfile.c b/sysfile.c new file mode 100644 index 0000000..f533e01 --- /dev/null +++ b/sysfile.c @@ -0,0 +1,477 @@ +#include "types.h" +#include "stat.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "defs.h" +#include "x86.h" +#include "traps.h" +#include "syscall.h" +#include "spinlock.h" +#include "buf.h" +#include "fs.h" +#include "fsvar.h" +#include "elf.h" +#include "fd.h" +#include "fcntl.h" + +int +sys_pipe(void) +{ +  struct fd *rfd = 0, *wfd = 0; +  int f1 = -1, f2 = -1; +  struct proc *p = curproc[cpu()]; +  uint fdp; + +  if(pipe_alloc(&rfd, &wfd) < 0) +    goto oops; +  if((f1 = fd_ualloc()) < 0) +    goto oops; +  p->fds[f1] = rfd; +  if((f2 = fd_ualloc()) < 0) +    goto oops; +  p->fds[f2] = wfd; +  if(fetcharg(0, &fdp) < 0) +    goto oops; +  if(putint(p, fdp, f1) < 0) +    goto oops; +  if(putint(p, fdp+4, f2) < 0) +    goto oops; +  return 0; + + oops: +  if(rfd) +    fd_close(rfd); +  if(wfd) +    fd_close(wfd); +  if(f1 >= 0) +    p->fds[f1] = 0; +  if(f2 >= 0) +    p->fds[f2] = 0; +  return -1; +} + +int +sys_write(void) +{ +  int fd, n, ret; +  uint addr; +  struct proc *p = curproc[cpu()]; + +  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(p->fds[fd] == 0) +    return -1; +  if(addr + n > p->sz) +    return -1; + +  ret = fd_write(p->fds[fd], p->mem + addr, n); +  return ret; +} + +int +sys_read(void) +{ +  int fd, n, ret; +  uint addr; +  struct proc *p = curproc[cpu()]; + +  if(fetcharg(0, &fd) < 0 || fetcharg(1, &addr) < 0 || fetcharg(2, &n) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(p->fds[fd] == 0) +    return -1; +  if(addr + n > p->sz) +    return -1; +  ret = fd_read(p->fds[fd], p->mem + addr, n); +  return ret; +} + +int +sys_close(void) +{ +  int fd; +  struct proc *p = curproc[cpu()]; + +  if(fetcharg(0, &fd) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(p->fds[fd] == 0) +    return -1; +  fd_close(p->fds[fd]); +  p->fds[fd] = 0; +  return 0; +} + +int +sys_open(void) +{ +  struct proc *cp = curproc[cpu()]; +  struct inode *ip, *dp; +  uint arg0, arg1; +  int ufd; +  struct fd *fd; +  int l; +  char *last; + +  if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0) +    return -1; +  if((l = checkstring(arg0)) < 0) +    return -1; + +  if(arg1 & O_CREATE){ +    dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, &ip); +    if(dp){ +      ip = mknod1(dp, last, T_FILE, 0, 0); +      iput(dp); +      if(ip == 0) +        return -1; +    } else if(ip == 0){ +      return -1; +    } else if(ip->type == T_DIR){ +      iput(ip); +      return -1; +    } +  } else { +    ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0); +    if(ip == 0) +      return -1; +  } +  if(ip->type == T_DIR && ((arg1 & O_RDWR) || (arg1 & O_WRONLY))){ +    iput(ip); +    return -1; +  } + +  if((fd = fd_alloc()) == 0){ +    iput(ip); +    return -1; +  } +  if((ufd = fd_ualloc()) < 0){ +    iput(ip); +    fd_close(fd); +    return -1; +  } + +  iunlock(ip); +  fd->type = FD_FILE; +  if(arg1 & O_RDWR) { +    fd->readable = 1; +    fd->writable = 1; +  } else if(arg1 & O_WRONLY) { +    fd->readable = 0; +    fd->writable = 1; +  } else { +    fd->readable = 1; +    fd->writable = 0; +  } +  fd->ip = ip; +  fd->off = 0; +  cp->fds[ufd] = fd; + +  return ufd; +} + +int +sys_mknod(void) +{ +  struct proc *cp = curproc[cpu()]; +  struct inode *nip; +  uint arg0, arg1, arg2, arg3; +  int l; + +  if(fetcharg(0, &arg0) < 0 || fetcharg(1, &arg1) < 0 || +     fetcharg(2, &arg2) < 0 || fetcharg(3, &arg3) < 0) +    return -1; + +  if((l = checkstring(arg0)) < 0) +    return -1; + +  if(l >= DIRSIZ) +    return -1; + +  nip = mknod(cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3); +  if(nip) +    iput(nip); +  return (nip == 0) ? -1 : 0; +} + +int +sys_mkdir(void) +{ +  struct proc *cp = curproc[cpu()]; +  struct inode *nip; +  struct inode *dp; +  uint arg0; +  int l; +  struct dirent de; +  char *last; + +  if(fetcharg(0, &arg0) < 0) +    return -1; + +  if((l = checkstring(arg0)) < 0) +    return -1; + +  dp = namei(cp->mem + arg0, NAMEI_CREATE, 0, &last, 0); +  if(dp == 0) +    return -1; + +  nip = mknod1(dp, last, T_DIR, 0, 0); +  if(nip == 0){ +    iput(dp); +    return -1; +  } + +  dp->nlink += 1; +  iupdate(dp); + +  memset(de.name, '\0', DIRSIZ); +  de.name[0] = '.'; +  de.inum = nip->inum; +  writei(nip, (char*) &de, 0, sizeof(de)); + +  de.inum = dp->inum; +  de.name[1] = '.'; +  writei(nip, (char*) &de, sizeof(de), sizeof(de)); + +  iput(dp); +  iput(nip); + +  return 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((ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0)) == 0) +    return -1; + +  if(ip == cp->cwd) { +    iput(ip); +    return 0; +  } + +  if(ip->type != T_DIR) { +    iput(ip); +    return -1; +  } + +  idecref(cp->cwd); +  cp->cwd = ip; +  iunlock(cp->cwd); +  return 0; +} + +int +sys_unlink(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint arg0; +  int r; + +  if(fetcharg(0, &arg0) < 0) +    return -1; +  if(checkstring(arg0) < 0) +    return -1; +  r = unlink(cp->mem + arg0); +  return r; +} + +int +sys_fstat(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint fd, addr; +  int r; + +  if(fetcharg(0, &fd) < 0) +    return -1; +  if(fetcharg(1, &addr) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(cp->fds[fd] == 0) +    return -1; +  if(addr + sizeof(struct stat) > cp->sz) +    return -1; +  r = fd_stat(cp->fds[fd], (struct stat*)(cp->mem + addr)); +  return r; +} + +int +sys_dup(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint fd, ufd1; + +  if(fetcharg(0, &fd) < 0) +    return -1; +  if(fd < 0 || fd >= NOFILE) +    return -1; +  if(cp->fds[fd] == 0) +    return -1; +  if((ufd1 = fd_ualloc()) < 0) +    return -1; +  cp->fds[ufd1] = cp->fds[fd]; +  fd_incref(cp->fds[ufd1]); +  return ufd1; +} + +int +sys_link(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint name1, name2; +  int r; + +  if(fetcharg(0, &name1) < 0 || checkstring(name1) < 0) +    return -1; +  if(fetcharg(1, &name2) < 0 || checkstring(name2) < 0) +    return -1; +  r = link(cp->mem + name1, cp->mem + name2); +  return r; +} + +int +sys_exec(void) +{ +  struct proc *cp = curproc[cpu()]; +  uint arg0, arg1, sz=0, ap, sp, p1, p2; +  int i, nargs, argbytes, len; +  struct inode *ip; +  struct elfhdr elf; +  struct proghdr ph; +  char *mem = 0; + +  if(fetcharg(0, &arg0) < 0) +    return -1; +  if(fetcharg(1, &arg1) < 0) +    return -1; +  if(checkstring(arg0) < 0) +    return -1; +  ip = namei(cp->mem + arg0, NAMEI_LOOKUP, 0, 0, 0); +  if(ip == 0) +    return -1; + +  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf)) +    goto bad; + +  if(elf.magic != ELF_MAGIC) +    goto bad; + +  sz = 0; +  for(i = 0; i < elf.phnum; i++){ +    if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph), +             sizeof(ph)) != sizeof(ph)) +      goto bad; +    if(ph.type != ELF_PROG_LOAD) +      continue; +    if(ph.memsz < ph.filesz) +      goto bad; +    sz += ph.memsz; +  } + +  sz += 4096 - (sz % 4096); +  sz += 4096; + +  mem = kalloc(sz); +  if(mem == 0) +    goto bad; +  memset(mem, 0, sz); + +  // arg1 is a pointer to an array of pointers to string. +  nargs = 0; +  argbytes = 0; +  for(i = 0; ; i++){ +    if(fetchint(cp, arg1 + 4*i, &ap) < 0) +      goto bad; +    if(ap == 0) +      break; +    len = checkstring(ap); +    if(len < 0) +      goto bad; +    nargs++; +    argbytes += len + 1; +  } + +  // argn\0 +  // ... +  // arg0\0 +  // 0 +  // ptr to argn +  // ... +  // 12: ptr to arg0 +  //  8: argv (points to ptr to arg0) +  //  4: argc +  //  0: fake return pc +  sp = sz - argbytes - (nargs+1)*4 - 4 - 4 - 4; +  *(uint*)(mem + sp) = 0xffffffff; +  *(uint*)(mem + sp + 4) = nargs; +  *(uint*)(mem + sp + 8) = (uint)(sp + 12); + +  p1 = sp + 12; +  p2 = sp + 12 + (nargs + 1) * 4; +  for(i = 0; i < nargs; i++){ +    fetchint(cp, arg1 + 4*i, &ap); +    len = checkstring(ap); +    memmove(mem + p2, cp->mem + ap, len + 1); +    *(uint*)(mem + p1) = p2; +    p1 += 4; +    p2 += len + 1; +  } +  *(uint*)(mem + p1) = 0; + +  // commit to the new image. +  kfree(cp->mem, cp->sz); +  cp->sz = sz; +  cp->mem = mem; +  mem = 0; + +  for(i = 0; i < elf.phnum; i++){ +    if(readi(ip, (char*)&ph, elf.phoff + i * sizeof(ph), +             sizeof(ph)) != sizeof(ph)) +      goto bad2; +    if(ph.type != ELF_PROG_LOAD) +      continue; +    if(ph.va + ph.memsz > sz) +      goto bad2; +    if(readi(ip, cp->mem + ph.va, ph.offset, ph.filesz) != ph.filesz) +      goto bad2; +    memset(cp->mem + ph.va + ph.filesz, 0, ph.memsz - ph.filesz); +  } + +  iput(ip); + +  cp->tf->eip = elf.entry; +  cp->tf->esp = sp; +  setupsegs(cp); + +  return 0; + + bad: +  if(mem) +    kfree(mem, sz); +  iput(ip); +  return -1; + + bad2: +  iput(ip); +  proc_exit(); +  return 0; +} diff --git a/sysproc.c b/sysproc.c new file mode 100644 index 0000000..f648c0e --- /dev/null +++ b/sysproc.c @@ -0,0 +1,72 @@ +#include "types.h" +#include "stat.h" +#include "param.h" +#include "mmu.h" +#include "proc.h" +#include "defs.h" +#include "x86.h" +#include "traps.h" +#include "syscall.h" +#include "spinlock.h" +#include "buf.h" +#include "fs.h" +#include "fsvar.h" +#include "elf.h" +#include "fd.h" +#include "fcntl.h" + +int +sys_fork(void) +{ +  struct proc *np; + +  if((np = copyproc(curproc[cpu()])) == 0) +    return -1; +  np->state = RUNNABLE; +  return np->pid; +} + +int +sys_exit(void) +{ +  proc_exit(); +  return 0;  // not reached +} + +int +sys_wait(void) +{ +  return proc_wait(); +} + +int +sys_kill(void) +{ +  int pid; + +  if(fetcharg(0, &pid) < 0) +    return -1; +  return proc_kill(pid); +} + +int +sys_getpid(void) +{ +  struct proc *cp = curproc[cpu()]; +  return cp->pid; +} + +int +sys_sbrk(void) +{ +  uint addr; +  int n; +  struct proc *cp = curproc[cpu()]; + +  if(fetcharg(0, &n) < 0) +    return -1; +  if((addr = growproc(n)) == 0xffffffff) +    return -1; +  setupsegs(cp); +  return addr; +} | 
