X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/93ca0e5053f2230aab14a009ec47ab63b380a3b0..a0002c0a8b7346933ca7c4366b654239e88ead83:/usr/src/sys/kern/kern_descrip.c?ds=inline diff --git a/usr/src/sys/kern/kern_descrip.c b/usr/src/sys/kern/kern_descrip.c index 134cc7adda..2c6c0ffffb 100644 --- a/usr/src/sys/kern/kern_descrip.c +++ b/usr/src/sys/kern/kern_descrip.c @@ -4,7 +4,7 @@ * * %sccs.include.redist.c% * - * @(#)kern_descrip.c 7.29 (Berkeley) %G% + * @(#)kern_descrip.c 7.37 (Berkeley) %G% */ #include "param.h" @@ -32,10 +32,13 @@ int nfiles; /* actual number of open files */ /* * System calls on descriptors. */ +struct getdtablesize_args { + int dummy; +}; /* ARGSUSED */ getdtablesize(p, uap, retval) struct proc *p; - struct args *uap; + struct getdtablesize_args *uap; int *retval; { @@ -46,12 +49,13 @@ getdtablesize(p, uap, retval) /* * Duplicate a file descriptor. */ +struct dup_args { + int i; +}; /* ARGSUSED */ dup(p, uap, retval) struct proc *p; - struct args { - int i; - } *uap; + struct dup_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -80,13 +84,14 @@ dup(p, uap, retval) /* * Duplicate a file descriptor to a particular value. */ +struct dup2_args { + u_int from; + u_int to; +}; /* ARGSUSED */ dup2(p, uap, retval) struct proc *p; - struct args { - u_int from; - u_int to; - } *uap; + struct dup2_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -125,14 +130,15 @@ dup2(p, uap, retval) /* * The file control system call. */ +struct fcntl_args { + int fd; + int cmd; + int arg; +}; /* ARGSUSED */ fcntl(p, uap, retval) struct proc *p; - register struct args { - int fd; - int cmd; - int arg; - } *uap; + register struct fcntl_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -273,12 +279,13 @@ fcntl(p, uap, retval) /* * Close a file descriptor. */ +struct close_args { + int fd; +}; /* ARGSUSED */ close(p, uap, retval) struct proc *p; - struct args { - int fd; - } *uap; + struct close_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -301,16 +308,61 @@ close(p, uap, retval) return (closef(fp, p)); } +#if defined(COMPAT_43) || defined(COMPAT_SUNOS) /* * Return status information about a file descriptor. */ +struct ofstat_args { + int fd; + struct ostat *sb; +}; +/* ARGSUSED */ +ofstat(p, uap, retval) + struct proc *p; + register struct ofstat_args *uap; + int *retval; +{ + register struct filedesc *fdp = p->p_fd; + register struct file *fp; + struct stat ub; + struct ostat oub; + int error; + + if ((unsigned)uap->fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[uap->fd]) == NULL) + return (EBADF); + switch (fp->f_type) { + + case DTYPE_VNODE: + error = vn_stat((struct vnode *)fp->f_data, &ub, p); + break; + + case DTYPE_SOCKET: + error = soo_stat((struct socket *)fp->f_data, &ub); + break; + + default: + panic("ofstat"); + /*NOTREACHED*/ + } + cvtstat(&ub, &oub); + if (error == 0) + error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub)); + return (error); +} +#endif /* COMPAT_43 || COMPAT_SUNOS */ + +/* + * Return status information about a file descriptor. + */ +struct fstat_args { + int fd; + struct stat *sb; +}; /* ARGSUSED */ fstat(p, uap, retval) struct proc *p; - register struct args { - int fd; - struct stat *sb; - } *uap; + register struct fstat_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -633,14 +685,14 @@ closef(fp, p) * Just attempt to get a record lock of the requested type on * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). */ - +struct flock_args { + int fd; + int how; +}; /* ARGSUSED */ flock(p, uap, retval) struct proc *p; - register struct args { - int fd; - int how; - } *uap; + register struct flock_args *uap; int *retval; { register struct filedesc *fdp = p->p_fd; @@ -684,9 +736,10 @@ flock(p, uap, retval) * references to this file will be direct to the other driver. */ /* ARGSUSED */ -fdopen(dev, mode, type) +fdopen(dev, mode, type, p) dev_t dev; int mode, type; + struct proc *p; { /* @@ -697,17 +750,18 @@ fdopen(dev, mode, type) * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN * will simply report the error. */ - curproc->p_dupfd = minor(dev); /* XXX */ + p->p_dupfd = minor(dev); return (ENODEV); } /* * Duplicate the specified descriptor to a free descriptor. */ -dupfdopen(fdp, indx, dfd, mode) +dupfdopen(fdp, indx, dfd, mode, error) register struct filedesc *fdp; register int indx, dfd; int mode; + int error; { register struct file *wfp; struct file *fp; @@ -725,15 +779,56 @@ dupfdopen(fdp, indx, dfd, mode) return (EBADF); /* - * Check that the mode the file is being opened for is a subset - * of the mode of the existing descriptor. + * There are two cases of interest here. + * + * For ENODEV simply dup (dfd) to file descriptor + * (indx) and return. + * + * For ENXIO steal away the file structure from (dfd) and + * store it in (indx). (dfd) is effectively closed by + * this operation. + * + * Any other error code is just returned. */ - if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) - return (EACCES); - fdp->fd_ofiles[indx] = wfp; - fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; - wfp->f_count++; - if (indx > fdp->fd_lastfile) - fdp->fd_lastfile = indx; - return (0); + switch (error) { + case ENODEV: + /* + * Check that the mode the file is being opened for is a + * subset of the mode of the existing descriptor. + */ + if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) + return (EACCES); + fdp->fd_ofiles[indx] = wfp; + fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; + wfp->f_count++; + if (indx > fdp->fd_lastfile) + fdp->fd_lastfile = indx; + return (0); + + case ENXIO: + /* + * Steal away the file pointer from dfd, and stuff it into indx. + */ + fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; + fdp->fd_ofiles[dfd] = NULL; + fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; + fdp->fd_ofileflags[dfd] = 0; + /* + * Complete the clean up of the filedesc structure by + * recomputing the various hints. + */ + if (indx > fdp->fd_lastfile) + fdp->fd_lastfile = indx; + else + while (fdp->fd_lastfile > 0 && + fdp->fd_ofiles[fdp->fd_lastfile] == NULL) + fdp->fd_lastfile--; + if (dfd < fdp->fd_freefile) + fdp->fd_freefile = dfd; + return (0); + + default: + return (error); + } + /* NOTREACHED */ }