kern_descrip.c (237016) | kern_descrip.c (237033) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94 35 */ 36 37#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 21 unchanged lines hidden (view full) --- 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/kern/kern_descrip.c 237016 2012-06-13 19:00:29Z pjd $"); | 38__FBSDID("$FreeBSD: head/sys/kern/kern_descrip.c 237033 2012-06-13 21:32:35Z pjd $"); |
39 40#include "opt_capsicum.h" 41#include "opt_compat.h" 42#include "opt_ddb.h" 43#include "opt_ktrace.h" 44#include "opt_procdesc.h" 45 46#include <sys/param.h> --- 2536 unchanged lines hidden (view full) --- 2583 fdrop(fp, td); 2584 VFS_UNLOCK_GIANT(vfslocked); 2585 return (error); 2586} 2587/* 2588 * Duplicate the specified descriptor to a free descriptor. 2589 */ 2590int | 39 40#include "opt_capsicum.h" 41#include "opt_compat.h" 42#include "opt_ddb.h" 43#include "opt_ktrace.h" 44#include "opt_procdesc.h" 45 46#include <sys/param.h> --- 2536 unchanged lines hidden (view full) --- 2583 fdrop(fp, td); 2584 VFS_UNLOCK_GIANT(vfslocked); 2585 return (error); 2586} 2587/* 2588 * Duplicate the specified descriptor to a free descriptor. 2589 */ 2590int |
2591dupfdopen(struct thread *td, struct filedesc *fdp, int indx, int dfd, int mode, int error) | 2591dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode, int openerror, int *indxp) |
2592{ | 2592{ |
2593 struct file *wfp; | |
2594 struct file *fp; | 2593 struct file *fp; |
2594 int error, indx; |
|
2595 | 2595 |
2596 KASSERT(error == ENODEV || error == ENXIO, 2597 ("unexpected error %d in %s", error, __func__)); | 2596 KASSERT(openerror == ENODEV || openerror == ENXIO, 2597 ("unexpected error %d in %s", openerror, __func__)); |
2598 2599 /* 2600 * If the to-be-dup'd fd number is greater than the allowed number 2601 * of file descriptors, or the fd to be dup'd has already been 2602 * closed, then reject. 2603 */ 2604 FILEDESC_XLOCK(fdp); 2605 if ((unsigned int)dfd >= fdp->fd_nfiles || | 2598 2599 /* 2600 * If the to-be-dup'd fd number is greater than the allowed number 2601 * of file descriptors, or the fd to be dup'd has already been 2602 * closed, then reject. 2603 */ 2604 FILEDESC_XLOCK(fdp); 2605 if ((unsigned int)dfd >= fdp->fd_nfiles || |
2606 (wfp = fdp->fd_ofiles[dfd]) == NULL) { | 2606 (fp = fdp->fd_ofiles[dfd]) == NULL) { |
2607 FILEDESC_XUNLOCK(fdp); 2608 return (EBADF); 2609 } 2610 | 2607 FILEDESC_XUNLOCK(fdp); 2608 return (EBADF); 2609 } 2610 |
2611 error = fdalloc(td, 0, &indx); 2612 if (error != 0) { 2613 FILEDESC_XUNLOCK(fdp); 2614 return (error); 2615 } 2616 |
|
2611 /* 2612 * There are two cases of interest here. 2613 * 2614 * For ENODEV simply dup (dfd) to file descriptor (indx) and return. 2615 * 2616 * For ENXIO steal away the file structure from (dfd) and store it in 2617 * (indx). (dfd) is effectively closed by this operation. 2618 */ | 2617 /* 2618 * There are two cases of interest here. 2619 * 2620 * For ENODEV simply dup (dfd) to file descriptor (indx) and return. 2621 * 2622 * For ENXIO steal away the file structure from (dfd) and store it in 2623 * (indx). (dfd) is effectively closed by this operation. 2624 */ |
2619 fp = fdp->fd_ofiles[indx]; 2620 switch (error) { | 2625 switch (openerror) { |
2621 case ENODEV: 2622 /* 2623 * Check that the mode the file is being opened for is a 2624 * subset of the mode of the existing descriptor. 2625 */ | 2626 case ENODEV: 2627 /* 2628 * Check that the mode the file is being opened for is a 2629 * subset of the mode of the existing descriptor. 2630 */ |
2626 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) { | 2631 if (((mode & (FREAD|FWRITE)) | fp->f_flag) != fp->f_flag) { 2632 fdunused(fdp, indx); |
2627 FILEDESC_XUNLOCK(fdp); 2628 return (EACCES); 2629 } | 2633 FILEDESC_XUNLOCK(fdp); 2634 return (EACCES); 2635 } |
2630 fdp->fd_ofiles[indx] = wfp; | 2636 fdp->fd_ofiles[indx] = fp; |
2631 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; | 2637 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; |
2632 fhold(wfp); | 2638 fhold(fp); |
2633 break; 2634 case ENXIO: 2635 /* 2636 * Steal away the file pointer from dfd and stuff it into indx. 2637 */ | 2639 break; 2640 case ENXIO: 2641 /* 2642 * Steal away the file pointer from dfd and stuff it into indx. 2643 */ |
2638 fdp->fd_ofiles[indx] = wfp; | 2644 fdp->fd_ofiles[indx] = fp; |
2639 fdp->fd_ofiles[dfd] = NULL; 2640 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 2641 fdp->fd_ofileflags[dfd] = 0; 2642 fdunused(fdp, dfd); 2643 break; 2644 } 2645 FILEDESC_XUNLOCK(fdp); | 2645 fdp->fd_ofiles[dfd] = NULL; 2646 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 2647 fdp->fd_ofileflags[dfd] = 0; 2648 fdunused(fdp, dfd); 2649 break; 2650 } 2651 FILEDESC_XUNLOCK(fdp); |
2646 /* 2647 * We now own the reference to fp that the ofiles[] array used to own. 2648 * Release it. 2649 */ 2650 fdrop(fp, td); | 2652 *indxp = indx; |
2651 return (0); 2652} 2653 2654/* 2655 * Scan all active processes and prisons to see if any of them have a current 2656 * or root directory of `olddp'. If so, replace them with the new mount point. 2657 */ 2658void --- 1207 unchanged lines hidden --- | 2653 return (0); 2654} 2655 2656/* 2657 * Scan all active processes and prisons to see if any of them have a current 2658 * or root directory of `olddp'. If so, replace them with the new mount point. 2659 */ 2660void --- 1207 unchanged lines hidden --- |