diff options
Diffstat (limited to 'syscall.c')
-rw-r--r-- | syscall.c | 29 |
1 files changed, 24 insertions, 5 deletions
@@ -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 |