diff options
Diffstat (limited to 'syscall.c')
-rw-r--r-- | syscall.c | 93 |
1 files changed, 92 insertions, 1 deletions
@@ -43,6 +43,88 @@ fetcharg(int argno, int *ip) } int +putint(struct proc *p, unsigned addr, int ip) +{ + if(addr > p->sz - 4) + return 0; + memcpy(p->mem + addr, &ip, 4); + return 1; +} + +int +sys_pipe() +{ + struct fd *rfd = 0, *wfd = 0; + int f1 = -1, f2 = -1; + struct proc *p = curproc[cpu()]; + unsigned 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: + cprintf("sys_pipe failed\n"); + 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() +{ + int fd, n; + unsigned 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; + return fd_write(p->fds[fd], p->mem + addr, n); +} + +int +sys_read() +{ + int fd, n; + unsigned 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; + return fd_read(p->fds[fd], p->mem + addr, n); +} + +int sys_fork() { struct proc *np; @@ -122,7 +204,7 @@ syscall() int num = cp->tf->tf_regs.reg_eax; int ret = -1; - cprintf("%x sys %d\n", cp, num); + //cprintf("%x sys %d\n", cp, num); switch(num){ case SYS_fork: ret = sys_fork(); @@ -136,6 +218,15 @@ syscall() case SYS_cons_putc: ret = sys_cons_putc(); break; + case SYS_pipe: + ret = sys_pipe(); + break; + case SYS_write: + ret = sys_write(); + break; + case SYS_read: + ret = sys_read(); + break; default: cprintf("unknown sys call %d\n", num); // XXX fault |