From 2685309fb47a0f60d3b59138d8029c5d901fde91 Mon Sep 17 00:00:00 2001 From: rsc Date: Wed, 6 Sep 2006 18:19:11 +0000 Subject: [PATCH] split syscall.c into sysfile.c and sysproc.c --- defs.h | 5 + syscall.c | 536 ++---------------------------------------------------- syscall.h | 34 ++-- sysfile.c | 477 ++++++++++++++++++++++++++++++++++++++++++++++++ sysproc.c | 72 ++++++++ 5 files changed, 590 insertions(+), 534 deletions(-) create mode 100644 sysfile.c create mode 100644 sysproc.c diff --git a/defs.h b/defs.h index 693fc20..8731c27 100644 --- a/defs.h +++ b/defs.h @@ -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); diff --git a/syscall.c b/syscall.c index c6d4599..f75714a 100644 --- a/syscall.c +++ b/syscall.c @@ -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) diff --git a/syscall.h b/syscall.h index 4efd255..0ef0c87 100644 --- a/syscall.h +++ b/syscall.h @@ -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; +}