summaryrefslogtreecommitdiff
path: root/syscall.c
diff options
context:
space:
mode:
authorrtm <rtm>2006-06-27 14:35:53 +0000
committerrtm <rtm>2006-06-27 14:35:53 +0000
commitc41f1de5d41a527a3fa2d1e94215766130eac456 (patch)
tree86f6a467be8b42aec42a05299789f39ace9cc5e2 /syscall.c
parentb61c2547b8b489cab16984c0940a1cb6593a2a3d (diff)
downloadxv6-labs-c41f1de5d41a527a3fa2d1e94215766130eac456.tar.gz
xv6-labs-c41f1de5d41a527a3fa2d1e94215766130eac456.tar.bz2
xv6-labs-c41f1de5d41a527a3fa2d1e94215766130eac456.zip
file descriptors
pipes
Diffstat (limited to 'syscall.c')
-rw-r--r--syscall.c93
1 files changed, 92 insertions, 1 deletions
diff --git a/syscall.c b/syscall.c
index 1d2eb54..c27c226 100644
--- a/syscall.c
+++ b/syscall.c
@@ -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