diff --git a/defs.h b/defs.h index 18ff4f1..2928428 100644 --- a/defs.h +++ b/defs.h @@ -94,7 +94,6 @@ int fd_read(struct fd *fd, char *addr, int n); int fd_write(struct fd *fd, char *addr, int n); int fd_stat(struct fd *fd, struct stat *); void fd_incref(struct fd *fd); -int fd_dup(struct fd *fd); // ide.c void ide_init(void); diff --git a/fd.c b/fd.c index 7de4d55..e61cab2 100644 --- a/fd.c +++ b/fd.c @@ -149,9 +149,3 @@ fd_incref(struct fd *fd) fd->ref++; release(&fd_table_lock); } - -int -fd_dup(struct fd *fd) -{ - return -1; -} diff --git a/syscall.c b/syscall.c index 5b857bd..80d5d8e 100644 --- a/syscall.c +++ b/syscall.c @@ -402,17 +402,36 @@ int sys_dup(void) { struct proc *cp = curproc[cpu()]; - uint fd; - int r; + uint fd, ufd1; + struct fd *fd1; if(fetcharg(0, &fd) < 0) return -1; if(fd < 0 || fd >= NOFILE) return -1; - if(cp->fds[fd] == 0) + if(cp->fds[fd] == 0) return -1; - r = fd_dup (cp->fds[fd]); - return r; + if (cp->fds[fd]->type != FD_PIPE && cp->fds[fd]->type != FD_FILE) + return -1; + + if ((fd1 = fd_alloc()) == 0) { + return -1; + } + if ((ufd1 = fd_ualloc()) < 0) { + fd_close(fd1); + return -1; + } + fd1->type = cp->fds[fd]->type; + fd1->readable = cp->fds[fd]->readable; + fd1->writeable = cp->fds[fd]->writeable; + if (cp->fds[fd]->type == FD_FILE) { + fd1->ip = cp->fds[fd]->ip; + iincref(fd1->ip); + } else if (cp->fds[fd]->type == FD_PIPE) { + fd1->pipe = cp->fds[fd]->pipe; + } + fd1->off = cp->fds[fd]->off; + return ufd1; } int