Index: emulation/linux/linux_file.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/linux_file.c,v retrieving revision 1.9 diff -u -u -r1.9 linux_file.c --- emulation/linux/linux_file.c 15 Aug 2003 06:32:51 -0000 1.9 +++ emulation/linux/linux_file.c 13 Oct 2003 09:16:40 -0000 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -915,108 +916,54 @@ #endif static int -fcntl_common(struct linux_fcntl64_args *args) +linux_fcntl_common(struct linux_fcntl64_args *args) { struct proc *p = curproc; struct l_flock linux_flock; - struct flock *bsd_flock; - struct fcntl_args fcntl_args; struct filedesc *fdp; struct file *fp; - int error, result; - caddr_t sg; - - sg = stackgap_init(); - bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(bsd_flock)); - - fcntl_args.fd = args->fd; - fcntl_args.sysmsg_result = 0; + union fcntl_dat dat; + int error, cmd; switch (args->cmd) { case LINUX_F_DUPFD: - fcntl_args.cmd = F_DUPFD; - fcntl_args.arg = args->arg; + cmd = F_DUPFD; + dat.fc_fd = args->arg; break; case LINUX_F_GETFD: - fcntl_args.cmd = F_GETFD; + cmd = F_GETFD; break; case LINUX_F_SETFD: - fcntl_args.cmd = F_SETFD; - fcntl_args.arg = args->arg; + cmd = F_SETFD; + dat.fc_cloexec = args->arg; break; case LINUX_F_GETFL: - fcntl_args.cmd = F_GETFL; - error = fcntl(&fcntl_args); - result = fcntl_args.sysmsg_result; - args->sysmsg_result = 0; - if (result & O_RDONLY) - args->sysmsg_result |= LINUX_O_RDONLY; - if (result & O_WRONLY) - args->sysmsg_result |= LINUX_O_WRONLY; - if (result & O_RDWR) - args->sysmsg_result |= LINUX_O_RDWR; - if (result & O_NDELAY) - args->sysmsg_result |= LINUX_O_NONBLOCK; - if (result & O_APPEND) - args->sysmsg_result |= LINUX_O_APPEND; - if (result & O_FSYNC) - args->sysmsg_result |= LINUX_O_SYNC; - if (result & O_ASYNC) - args->sysmsg_result |= LINUX_FASYNC; - return (error); - + cmd = F_GETFL; + break; case LINUX_F_SETFL: - fcntl_args.arg = 0; + cmd = F_SETFL; + dat.fc_flags = 0; if (args->arg & LINUX_O_NDELAY) - fcntl_args.arg |= O_NONBLOCK; + dat.fc_flags |= O_NONBLOCK; if (args->arg & LINUX_O_APPEND) - fcntl_args.arg |= O_APPEND; + dat.fc_flags |= O_APPEND; if (args->arg & LINUX_O_SYNC) - fcntl_args.arg |= O_FSYNC; + dat.fc_flags |= O_FSYNC; if (args->arg & LINUX_FASYNC) - fcntl_args.arg |= O_ASYNC; - fcntl_args.cmd = F_SETFL; + dat.fc_flags |= O_ASYNC; break; - case LINUX_F_GETLK: - error = copyin((caddr_t)args->arg, &linux_flock, - sizeof(linux_flock)); - if (error) - return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_GETLK; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(&fcntl_args); - args->sysmsg_result = fcntl_args.sysmsg_result; - if (error) - return (error); - bsd_to_linux_flock(bsd_flock, &linux_flock); - return (copyout(&linux_flock, (caddr_t)args->arg, - sizeof(linux_flock))); - case LINUX_F_SETLK: - error = copyin((caddr_t)args->arg, &linux_flock, - sizeof(linux_flock)); - if (error) - return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLK; - fcntl_args.arg = (long)bsd_flock; - break; case LINUX_F_SETLKW: + cmd = F_GETLK; error = copyin((caddr_t)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLKW; - fcntl_args.arg = (long)bsd_flock; + linux_to_bsd_flock(&linux_flock, &dat.fc_flock); break; case LINUX_F_GETOWN: - fcntl_args.cmd = F_GETOWN; + cmd = F_GETOWN; break; case LINUX_F_SETOWN: /* @@ -1030,14 +977,58 @@ return (EBADF); if (fp->f_type == DTYPE_PIPE) return (EINVAL); - fcntl_args.cmd = F_SETOWN; - fcntl_args.arg = args->arg; + cmd = F_SETOWN; + dat.fc_owner = args->arg; break; default: return (EINVAL); } - error = fcntl(&fcntl_args); - args->sysmsg_result = fcntl_args.sysmsg_result; + + error = kern_fcntl(args->fd, cmd, &dat); + + if (error == 0) { + switch (args->cmd) { + case LINUX_F_DUPFD: + args->sysmsg_result = dat.fc_fd; + break; + case LINUX_F_GETFD: + args->sysmsg_result = dat.fc_cloexec; + break; + case LINUX_F_SETFD: + break; + case LINUX_F_GETFL: + args->sysmsg_result = 0; + if (dat.fc_flags & O_RDONLY) + args->sysmsg_result |= LINUX_O_RDONLY; + if (dat.fc_flags & O_WRONLY) + args->sysmsg_result |= LINUX_O_WRONLY; + if (dat.fc_flags & O_RDWR) + args->sysmsg_result |= LINUX_O_RDWR; + if (dat.fc_flags & O_NDELAY) + args->sysmsg_result |= LINUX_O_NONBLOCK; + if (dat.fc_flags & O_APPEND) + args->sysmsg_result |= LINUX_O_APPEND; + if (dat.fc_flags & O_FSYNC) + args->sysmsg_result |= LINUX_O_SYNC; + if (dat.fc_flags & O_ASYNC) + args->sysmsg_result |= LINUX_FASYNC; + break; + case LINUX_F_GETLK: + bsd_to_linux_flock(&dat.fc_flock, &linux_flock); + error = copyout(&linux_flock, (caddr_t)args->arg, + sizeof(linux_flock)); + break; + case LINUX_F_SETLK: + case LINUX_F_SETLKW: + break; + case LINUX_F_GETOWN: + args->sysmsg_result = dat.fc_owner; + break; + case LINUX_F_SETOWN: + break; + } + } + return(error); } @@ -1056,7 +1047,7 @@ args64.cmd = args->cmd; args64.arg = args->arg; args64.sysmsg_result = 0; - error = fcntl_common(&args64); + error = linux_fcntl_common(&args64); args->sysmsg_result = args64.sysmsg_result; return(error); } @@ -1065,67 +1056,46 @@ int linux_fcntl64(struct linux_fcntl64_args *args) { - struct fcntl_args fcntl_args; struct l_flock64 linux_flock; - struct flock *bsd_flock; - int error; - caddr_t sg; - - sg = stackgap_init(); - bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(bsd_flock)); + union fcntl_dat dat; + int error, cmd = 0; #ifdef DEBUG if (ldebug(fcntl64)) printf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd); #endif - fcntl_args.sysmsg_result = 0; + if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 || + args->cmd == LINUX_F_SETLKW64) { + switch (args->cmd) { + case LINUX_F_GETLK64: + cmd = F_GETLK; + break; + case LINUX_F_SETLK64: + cmd = F_SETLK; + break; + case LINUX_F_SETLKW64: + cmd = F_SETLKW; + break; + } - switch (args->cmd) { - case LINUX_F_GETLK64: error = copyin((caddr_t)args->arg, &linux_flock, sizeof(linux_flock)); if (error) return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_GETLK; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(&fcntl_args); - args->sysmsg_result = fcntl_args.sysmsg_result; - if (error) - return (error); - bsd_to_linux_flock64(bsd_flock, &linux_flock); - return (copyout(&linux_flock, (caddr_t)args->arg, - sizeof(linux_flock))); + linux_to_bsd_flock64(&linux_flock, &dat.fc_flock); - case LINUX_F_SETLK64: - error = copyin((caddr_t)args->arg, &linux_flock, - sizeof(linux_flock)); - if (error) - return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLK; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(&fcntl_args); - args->sysmsg_result = fcntl_args.sysmsg_result; - return(error); + error = kern_fcntl(args->fd, cmd, &dat); - case LINUX_F_SETLKW64: - error = copyin((caddr_t)args->arg, &linux_flock, - sizeof(linux_flock)); - if (error) - return (error); - linux_to_bsd_flock64(&linux_flock, bsd_flock); - fcntl_args.fd = args->fd; - fcntl_args.cmd = F_SETLKW; - fcntl_args.arg = (long)bsd_flock; - error = fcntl(&fcntl_args); - args->sysmsg_result = fcntl_args.sysmsg_result; - return(error); + if (error == 0 && args->cmd == LINUX_F_GETLK64) { + bsd_to_linux_flock64(&dat.fc_flock, &linux_flock); + error = copyout(&linux_flock, (caddr_t)args->arg, + sizeof(linux_flock)); + } + } else { + error = linux_fcntl_common(args); } - return (fcntl_common(args)); + return (error); } #endif /* __i386__ */ Index: emulation/linux/linux_socket.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/emulation/linux/linux_socket.c,v retrieving revision 1.14 diff -u -u -r1.14 linux_socket.c --- emulation/linux/linux_socket.c 13 Oct 2003 04:58:13 -0000 1.14 +++ emulation/linux/linux_socket.c 13 Oct 2003 09:19:27 -0000 @@ -421,11 +421,6 @@ linux_accept(struct linux_accept_args *args, int *res) { struct linux_accept_args linux_args; - struct fcntl_args /* { - int fd; - int cmd; - long arg; - } */ f_args; struct sockaddr *sa = NULL; int error, sa_len; @@ -470,10 +465,7 @@ * accepted one, so we must clear the flags in the new descriptor. * Ignore any errors, because we already have an open fd. */ - f_args.fd = *res; - f_args.cmd = F_SETFL; - f_args.arg = 0; - (void)fcntl(&f_args); + kern_fcntl(*res, F_SETFL, 0); return (0); } Index: kern/kern_descrip.c =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/kern/kern_descrip.c,v retrieving revision 1.15 diff -u -u -r1.15 kern_descrip.c --- kern/kern_descrip.c 13 Oct 2003 21:15:43 -0000 1.15 +++ kern/kern_descrip.c 14 Oct 2003 00:52:32 -0000 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -94,7 +95,6 @@ /* psize */ nopsize }; -static int do_dup (struct filedesc *fdp, int old, int new, register_t *retval, struct proc *p); static int badfo_readwrite (struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct thread *td); static int badfo_ioctl (struct file *fp, u_long com, caddr_t data, @@ -136,31 +136,11 @@ int dup2(struct dup2_args *uap) { - struct proc *p = curproc; - struct filedesc *fdp = p->p_fd; - u_int old = uap->from, new = uap->to; - int i, error; + int error; -retry: - if (old >= fdp->fd_nfiles || - fdp->fd_ofiles[old] == NULL || - new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || - new >= maxfilesperproc) { - return (EBADF); - } - if (old == new) { - uap->sysmsg_result = new; - return (0); - } - if (new >= fdp->fd_nfiles) { - if ((error = fdalloc(p, new, &i))) - return (error); - /* - * fdalloc() may block, retest everything. - */ - goto retry; - } - return (do_dup(fdp, (int)old, (int)new, uap->sysmsg_fds, p)); + error = kern_dup(DUP_FIXED, uap->from, uap->to, uap->sysmsg_fds); + + return (error); } /* @@ -170,26 +150,15 @@ int dup(struct dup_args *uap) { - struct proc *p = curproc; - struct filedesc *fdp; - u_int old; - int new, error; + int error; - old = uap->fd; - fdp = p->p_fd; - if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) - return (EBADF); - if ((error = fdalloc(p, 0, &new))) - return (error); - return (do_dup(fdp, (int)old, new, uap->sysmsg_fds, p)); + error = kern_dup(DUP_VARIABLE, uap->fd, 0, uap->sysmsg_fds); + + return (error); } -/* - * The file control system call. - */ -/* ARGSUSED */ int -fcntl(struct fcntl_args *uap) +kern_fcntl(int fd, int cmd, union fcntl_dat *dat) { struct thread *td = curthread; struct proc *p = td->td_proc; @@ -197,44 +166,42 @@ struct file *fp; char *pop; struct vnode *vp; - int i, tmp, error, flg = F_POSIX; - struct flock fl; u_int newmin; + int tmp, error, flg = F_POSIX; KKASSERT(p); - if ((unsigned)uap->fd >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[uap->fd]) == NULL) + if ((unsigned)fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) return (EBADF); - pop = &fdp->fd_ofileflags[uap->fd]; + pop = &fdp->fd_ofileflags[fd]; - switch (uap->cmd) { + switch (cmd) { case F_DUPFD: - newmin = uap->arg; + newmin = dat->fc_fd; if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || - newmin >= maxfilesperproc) + newmin > maxfilesperproc) return (EINVAL); - if ((error = fdalloc(p, newmin, &i))) - return (error); - return (do_dup(fdp, uap->fd, i, uap->sysmsg_fds, p)); + error = kern_dup(DUP_VARIABLE, fd, newmin, &dat->fc_fd); + return (error); case F_GETFD: - uap->sysmsg_result = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; + dat->fc_cloexec = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; return (0); case F_SETFD: *pop = (*pop &~ UF_EXCLOSE) | - (uap->arg & FD_CLOEXEC ? UF_EXCLOSE : 0); + (dat->fc_cloexec & FD_CLOEXEC ? UF_EXCLOSE : 0); return (0); case F_GETFL: - uap->sysmsg_result = OFLAGS(fp->f_flag); + dat->fc_flags = OFLAGS(fp->f_flag); return (0); case F_SETFL: fhold(fp); fp->f_flag &= ~FCNTLFLAGS; - fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; + fp->f_flag |= FFLAGS(dat->fc_flags & ~O_ACCMODE) & FCNTLFLAGS; tmp = fp->f_flag & FNONBLOCK; error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); if (error) { @@ -249,19 +216,19 @@ } fp->f_flag &= ~FNONBLOCK; tmp = 0; - (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); + fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); fdrop(fp, td); return (error); case F_GETOWN: fhold(fp); - error = fo_ioctl(fp, FIOGETOWN, (caddr_t)uap->sysmsg_fds, td); + error = fo_ioctl(fp, FIOGETOWN, (caddr_t)&dat->fc_owner, td); fdrop(fp, td); return(error); case F_SETOWN: fhold(fp); - error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, td); + error = fo_ioctl(fp, FIOSETOWN, (caddr_t)&dat->fc_owner, td); fdrop(fp, td); return(error); @@ -278,17 +245,10 @@ * copyin/lockop may block */ fhold(fp); - /* Copy in the lock structure */ - error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, - sizeof(fl)); - if (error) { - fdrop(fp, td); - return (error); - } - if (fl.l_whence == SEEK_CUR) - fl.l_start += fp->f_offset; + if (dat->fc_flock.l_whence == SEEK_CUR) + dat->fc_flock.l_start += fp->f_offset; - switch (fl.l_type) { + switch (dat->fc_flock.l_type) { case F_RDLCK: if ((fp->f_flag & FREAD) == 0) { error = EBADF; @@ -296,7 +256,7 @@ } p->p_leader->p_flag |= P_ADVLOCK; error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, - &fl, flg); + &dat->fc_flock, flg); break; case F_WRLCK: if ((fp->f_flag & FWRITE) == 0) { @@ -305,25 +265,25 @@ } p->p_leader->p_flag |= P_ADVLOCK; error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, - &fl, flg); + &dat->fc_flock, flg); break; case F_UNLCK: error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, - &fl, F_POSIX); + &dat->fc_flock, F_POSIX); break; default: error = EINVAL; break; } /* Check for race with close */ - if ((unsigned) uap->fd >= fdp->fd_nfiles || - fp != fdp->fd_ofiles[uap->fd]) { - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_type = F_UNLCK; + if ((unsigned) fd >= fdp->fd_nfiles || + fp != fdp->fd_ofiles[fd]) { + dat->fc_flock.l_whence = SEEK_SET; + dat->fc_flock.l_start = 0; + dat->fc_flock.l_len = 0; + dat->fc_flock.l_type = F_UNLCK; (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, - F_UNLCK, &fl, F_POSIX); + F_UNLCK, &dat->fc_flock, F_POSIX); } fdrop(fp, td); return(error); @@ -336,27 +296,17 @@ * copyin/lockop may block */ fhold(fp); - /* Copy in the lock structure */ - error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, - sizeof(fl)); - if (error) { - fdrop(fp, td); - return (error); - } - if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK && - fl.l_type != F_UNLCK) { + if (dat->fc_flock.l_type != F_RDLCK && + dat->fc_flock.l_type != F_WRLCK && + dat->fc_flock.l_type != F_UNLCK) { fdrop(fp, td); return (EINVAL); } - if (fl.l_whence == SEEK_CUR) - fl.l_start += fp->f_offset; + if (dat->fc_flock.l_whence == SEEK_CUR) + dat->fc_flock.l_start += fp->f_offset; error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_GETLK, - &fl, F_POSIX); + &dat->fc_flock, F_POSIX); fdrop(fp, td); - if (error == 0) { - error = copyout((caddr_t)&fl, - (caddr_t)(intptr_t)uap->arg, sizeof(fl)); - } return(error); default: return (EINVAL); @@ -365,19 +315,128 @@ } /* + * The file control system call. + */ +int +fcntl(struct fcntl_args *uap) +{ + union fcntl_dat dat; + int error; + + switch (uap->cmd) { + case F_DUPFD: + dat.fc_fd = uap->arg; + break; + case F_SETFD: + dat.fc_cloexec = uap->arg; + break; + case F_SETFL: + dat.fc_flags = uap->arg; + break; + case F_SETOWN: + dat.fc_owner = uap->arg; + break; + case F_SETLKW: + case F_SETLK: + case F_GETLK: + error = copyin((caddr_t)uap->arg, &dat.fc_flock, + sizeof(struct flock)); + if (error) + return (error); + break; + } + + error = kern_fcntl(uap->fd, uap->cmd, &dat); + + if (error == 0) { + switch (uap->cmd) { + case F_DUPFD: + uap->sysmsg_result = dat.fc_fd; + break; + case F_GETFD: + uap->sysmsg_result = dat.fc_cloexec; + break; + case F_GETFL: + uap->sysmsg_result = dat.fc_flags; + break; + case F_GETOWN: + uap->sysmsg_result = dat.fc_owner; + case F_GETLK: + error = copyout(&dat.fc_flock, (caddr_t)uap->arg, + sizeof(struct flock)); + break; + } + } + + return (error); +} + +/* * Common code for dup, dup2, and fcntl(F_DUPFD). + * + * The type flag can be either DUP_FIXED or DUP_VARIABLE. DUP_FIXED tells + * kern_dup() to destructively dup over an existing file descriptor if new + * is already open. DUP_VARIABLE tells kern_dup() to find the lowest + * unused file descriptor that is greater than or equal to new. */ -static int -do_dup(fdp, old, new, retval, p) - struct filedesc *fdp; - int old, new; - register_t *retval; - struct proc *p; +int +kern_dup(enum dup_type type, int old, int new, int *res) { - struct thread *td = p->p_thread; + struct thread *td = curthread; + struct proc *p = td->td_proc; + struct filedesc *fdp = p->p_fd; struct file *fp; struct file *delfp; int holdleaders; + int error, newfd; + + /* + * Verify that we have a valid descriptor to dup from and + * possibly to dup to. + */ + if (old < 0 || new < 0 || new > p->p_rlimit[RLIMIT_NOFILE].rlim_cur || + new >= maxfilesperproc) + return (EBADF); + if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) + return (EBADF); + if (type == DUP_FIXED && old == new) { + *res = new; + return (0); + } + fp = fdp->fd_ofiles[old]; + fhold(fp); + + /* + * Expand the table for the new descriptor if needed. This may + * block and drop and reacquire the fidedesc lock. + */ + if (type == DUP_VARIABLE || new >= fdp->fd_nfiles) { + error = fdalloc(p, new, &newfd); + if (error) { + fdrop(fp, td); + return (error); + } + } + if (type == DUP_VARIABLE) + new = newfd; + + /* + * If the old file changed out from under us then treat it as a + * bad file descriptor. Userland should do its own locking to + * avoid this case. + */ + if (fdp->fd_ofiles[old] != fp) { + if (fdp->fd_ofiles[new] == NULL) { + if (new < fdp->fd_freefile) + fdp->fd_freefile = new; + while (fdp->fd_lastfile > 0 && + fdp->fd_ofiles[fdp->fd_lastfile] == NULL) + fdp->fd_lastfile--; + } + fdrop(fp, td); + return (EBADF); + } + KASSERT(old != new, ("new fd is same as old")); /* * Save info on the descriptor being overwritten. We have @@ -394,6 +453,8 @@ holdleaders = 1; } else holdleaders = 0; + KASSERT(delfp == NULL || type == DUP_FIXED, + ("dup() picked an open file")); #if 0 if (delfp && (fdp->fd_ofileflags[new] & UF_MAPPED)) (void) munmapfd(p, new); @@ -402,13 +463,11 @@ /* * Duplicate the source descriptor, update lastfile */ - fp = fdp->fd_ofiles[old]; fdp->fd_ofiles[new] = fp; fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; - fhold(fp); if (new > fdp->fd_lastfile) fdp->fd_lastfile = new; - *retval = new; + *res = new; /* * If we dup'd over a valid file, we now own the reference to it @@ -752,10 +811,7 @@ SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, ""); int -fdalloc(p, want, result) - struct proc *p; - int want; - int *result; +fdalloc(struct proc *p, int want, int *result) { struct filedesc *fdp = p->p_fd; int i; @@ -1331,10 +1387,7 @@ VOP_UNLOCK(nd.ni_vp, 0, td); devnull = fd; } else { - error = fdalloc(p, 0, &fd); - if (error != 0) - break; - error = do_dup(fdp, devnull, fd, &retval, p); + error = kern_dup(DUP_FIXED, devnull, i, &retval); if (error != 0) break; } Index: sys/fcntl.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/fcntl.h,v retrieving revision 1.4 diff -u -u -r1.4 fcntl.h --- sys/fcntl.h 13 Oct 2003 21:15:48 -0000 1.4 +++ sys/fcntl.h 14 Oct 2003 00:11:43 -0000 @@ -190,6 +190,16 @@ short l_whence; /* type of l_start */ }; +#ifdef _KERNEL +union fcntl_dat { + int fc_fd; /* F_DUPFD */ + int fc_cloexec; /* F_GETFD/F_SETFD */ + int fc_flags; /* F_GETFL/F_SETFL */ + int fc_owner; /* F_GETOWN/F_SETOWN */ + struct flock fc_flock; /* F_GETLK/F_SETLK */ +}; +#endif /* _KERNEL */ + #ifndef _POSIX_SOURCE /* lock operations for flock(2) */ Index: sys/kern_syscall.h =================================================================== RCS file: /nfs/daver/cvs-repos/cvs-dragonflybsd/src/sys/sys/kern_syscall.h,v retrieving revision 1.5 diff -u -u -r1.5 kern_syscall.h --- sys/kern_syscall.h 8 Oct 2003 01:30:32 -0000 1.5 +++ sys/kern_syscall.h 13 Oct 2003 23:40:34 -0000 @@ -31,6 +31,18 @@ #ifndef _SYS_KERN_SYSCALL_H_ #define _SYS_KERN_SYSCALL_H_ +/* + * Prototypes for syscalls in kern/kern_descrip.c + */ +enum dup_type {DUP_FIXED, DUP_VARIABLE}; +union fcntl_dat; + +int kern_dup(enum dup_type type, int old, int new, int *res); +int kern_fcntl(int fd, int cmd, union fcntl_dat *dat); + +/* + * Prototypes for syscalls in kern/uipc_syscalls.c + */ struct mbuf; struct msghdr; struct sf_hdtr;