2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1982, 1986, 1989, 1991, 1993
25 * The Regents of the University of California. All rights reserved.
26 * (c) UNIX System Laboratories, Inc.
27 * All or some portions of this file are derived from material licensed
28 * to the University of California by American Telephone and Telegraph
29 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
30 * the permission of UNIX System Laboratories, Inc.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)kern_descrip.c 8.8 (Berkeley) 2/14/95
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/filedesc.h>
66 #include <sys/kernel.h>
67 #include <sys/vnode_internal.h>
68 #include <sys/proc_internal.h>
69 #include <sys/kauth.h>
70 #include <sys/file_internal.h>
71 #include <sys/socket.h>
72 #include <sys/socketvar.h>
74 #include <sys/ioctl.h>
75 #include <sys/fcntl.h>
76 #include <sys/malloc.h>
78 #include <sys/syslog.h>
79 #include <sys/unistd.h>
80 #include <sys/resourcevar.h>
81 #include <sys/aio_kern.h>
83 #include <kern/lock.h>
85 #include <bsm/audit_kernel.h>
87 #include <sys/mount_internal.h>
88 #include <sys/kdebug.h>
89 #include <sys/sysproto.h>
91 #include <kern/kern_types.h>
92 #include <kern/kalloc.h>
93 #include <libkern/OSAtomic.h>
98 int fdopen(dev_t dev
, int mode
, int type
, struct proc
*p
);
99 int ogetdtablesize(struct proc
*p
, void *uap
, register_t
*retval
);
100 int finishdup(struct proc
* p
, struct filedesc
*fdp
, int old
, int new, register_t
*retval
);
102 int closef(struct fileglob
*fg
, struct proc
*p
);
103 int falloc_locked(struct proc
*p
, struct fileproc
**resultfp
, int *resultfd
, int locked
);
104 void fddrop(struct proc
*p
, int fd
);
105 int fdgetf_noref(struct proc
*p
, int fd
, struct fileproc
**resultfp
);
106 void fg_drop(struct fileproc
* fp
);
107 void fg_free(struct fileglob
*fg
);
108 void fg_ref(struct fileproc
* fp
);
109 int fp_getfpshm(struct proc
*p
, int fd
, struct fileproc
**resultfp
, struct pshmnode
**resultpshm
);
111 static int closef_finish(struct fileproc
*fp
, struct fileglob
*fg
, struct proc
*p
);
113 extern void file_lock_init(void);
114 extern int is_suser(void);
115 extern int kqueue_stat(struct fileproc
*fp
, struct stat
*st
, struct proc
*p
);
116 extern int soo_stat(struct socket
*so
, struct stat
*ub
);
117 extern int vn_path_package_check(vnode_t vp
, char *path
, int pathlen
, int *component
);
119 extern kauth_scope_t kauth_scope_fileop
;
121 #define f_flag f_fglob->fg_flag
122 #define f_type f_fglob->fg_type
123 #define f_msgcount f_fglob->fg_msgcount
124 #define f_cred f_fglob->fg_cred
125 #define f_ops f_fglob->fg_ops
126 #define f_offset f_fglob->fg_offset
127 #define f_data f_fglob->fg_data
129 * Descriptor management.
131 struct filelist filehead
; /* head of list of open files */
132 struct fmsglist fmsghead
; /* head of list of open files */
133 struct fmsglist fmsg_ithead
; /* head of list of open files */
134 int nfiles
; /* actual number of open files */
137 lck_grp_attr_t
* file_lck_grp_attr
;
138 lck_grp_t
* file_lck_grp
;
139 lck_attr_t
* file_lck_attr
;
141 lck_mtx_t
* uipc_lock
;
142 lck_mtx_t
* file_iterate_lcok
;
143 lck_mtx_t
* file_flist_lock
;
150 /* allocate file lock group attribute and group */
151 file_lck_grp_attr
= lck_grp_attr_alloc_init();
152 lck_grp_attr_setstat(file_lck_grp_attr
);
154 file_lck_grp
= lck_grp_alloc_init("file", file_lck_grp_attr
);
156 /* Allocate file lock attribute */
157 file_lck_attr
= lck_attr_alloc_init();
158 //lck_attr_setdebug(file_lck_attr);
160 uipc_lock
= lck_mtx_alloc_init(file_lck_grp
, file_lck_attr
);
161 file_iterate_lcok
= lck_mtx_alloc_init(file_lck_grp
, file_lck_attr
);
162 file_flist_lock
= lck_mtx_alloc_init(file_lck_grp
, file_lck_attr
);
170 proc_fdlock(struct proc
*p
)
172 lck_mtx_lock(&p
->p_fdmlock
);
176 proc_fdunlock(struct proc
*p
)
178 lck_mtx_unlock(&p
->p_fdmlock
);
182 * System calls on descriptors.
186 getdtablesize(struct proc
*p
, __unused
struct getdtablesize_args
*uap
, register_t
*retval
)
189 *retval
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
196 ogetdtablesize(struct proc
*p
, __unused
void *uap
, register_t
*retval
)
199 *retval
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, NOFILE
);
206 procfdtbl_reservefd(struct proc
* p
, int fd
)
208 p
->p_fd
->fd_ofiles
[fd
] = NULL
;
209 p
->p_fd
->fd_ofileflags
[fd
] |= UF_RESERVED
;
213 procfdtbl_markclosefd(struct proc
* p
, int fd
)
215 p
->p_fd
->fd_ofileflags
[fd
] |= (UF_RESERVED
| UF_CLOSING
);
219 procfdtbl_releasefd(struct proc
* p
, int fd
, struct fileproc
* fp
)
222 p
->p_fd
->fd_ofiles
[fd
] = fp
;
223 p
->p_fd
->fd_ofileflags
[fd
] &= ~UF_RESERVED
;
224 if ((p
->p_fd
->fd_ofileflags
[fd
] & UF_RESVWAIT
) == UF_RESVWAIT
) {
225 p
->p_fd
->fd_ofileflags
[fd
] &= ~UF_RESVWAIT
;
231 procfdtbl_waitfd(struct proc
* p
, int fd
)
233 p
->p_fd
->fd_ofileflags
[fd
] |= UF_RESVWAIT
;
234 msleep(&p
->p_fd
, &p
->p_fdmlock
, PRIBIO
, "ftbl_waitfd", NULL
);
239 procfdtbl_clearfd(struct proc
* p
, int fd
)
243 waiting
= (p
->p_fd
->fd_ofileflags
[fd
] & UF_RESVWAIT
);
244 p
->p_fd
->fd_ofiles
[fd
] = NULL
;
245 p
->p_fd
->fd_ofileflags
[fd
] = 0;
246 if ( waiting
== UF_RESVWAIT
) {
252 static __inline__
void
253 _fdrelse(struct proc
*p
, int fd
)
255 struct filedesc
*fdp
= p
->p_fd
;
258 if (fd
< fdp
->fd_freefile
)
259 fdp
->fd_freefile
= fd
;
261 if (fd
> fdp
->fd_lastfile
)
262 panic("fdrelse: fd_lastfile inconsistent");
264 procfdtbl_clearfd(p
, fd
);
266 while ((nfd
= fdp
->fd_lastfile
) > 0 &&
267 fdp
->fd_ofiles
[nfd
] == NULL
&&
268 !(fdp
->fd_ofileflags
[nfd
] & UF_RESERVED
))
273 * Duplicate a file descriptor.
279 struct dup_args
*uap
;
282 register struct filedesc
*fdp
= p
->p_fd
;
283 register int old
= uap
->fd
;
288 if ( (error
= fp_lookup(p
, old
, &fp
, 1)) ) {
292 if ( (error
= fdalloc(p
, 0, &new)) ) {
293 fp_drop(p
, old
, fp
, 1);
297 error
= finishdup(p
, fdp
, old
, new, retval
);
298 fp_drop(p
, old
, fp
, 1);
305 * Duplicate a file descriptor to a particular value.
311 struct dup2_args
*uap
;
314 register struct filedesc
*fdp
= p
->p_fd
;
315 register int old
= uap
->from
, new = uap
->to
;
317 struct fileproc
*fp
, *nfp
;
322 if ( (error
= fp_lookup(p
, old
, &fp
, 1)) ) {
327 new >= p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
||
329 fp_drop(p
, old
, fp
, 1);
334 fp_drop(p
, old
, fp
, 1);
339 if (new < 0 || new >= fdp
->fd_nfiles
) {
340 if ( (error
= fdalloc(p
, new, &i
)) ) {
341 fp_drop(p
, old
, fp
, 1);
351 while ((fdp
->fd_ofileflags
[new] & UF_RESERVED
) == UF_RESERVED
) {
352 fp_drop(p
, old
, fp
, 1);
353 procfdtbl_waitfd(p
, new);
357 if ((fdp
->fd_ofiles
[new] != NULL
) && ((error
= fp_lookup(p
, new, &nfp
, 1)) == 0)) {
358 fp_drop(p
, old
, fp
, 1);
359 close_internal(p
, new, nfp
, CLOSEINT_LOCKED
| CLOSEINT_NOFDRELSE
);
360 procfdtbl_clearfd(p
, new);
363 procfdtbl_reservefd(p
, new);
366 error
= finishdup(p
, fdp
, old
, new, retval
);
367 fp_drop(p
, old
, fp
, 1);
374 * The file control system call.
377 fcntl(p
, uap
, retval
)
379 struct fcntl_args
*uap
;
383 struct filedesc
*fdp
= p
->p_fd
;
387 int i
, tmp
, error
, error2
, flg
= F_POSIX
;
389 struct vfs_context context
;
393 int devBlockSize
= 0;
397 AUDIT_ARG(fd
, uap
->fd
);
398 AUDIT_ARG(cmd
, uap
->cmd
);
401 if ( (error
= fp_lookup(p
, fd
, &fp
, 1)) ) {
406 context
.vc_ucred
= fp
->f_cred
;
407 if (proc_is64bit(p
)) {
411 /* since the arg parameter is defined as a long but may be either
412 * a long or a pointer we must take care to handle sign extension
413 * issues. Our sys call munger will sign extend a long when we are
414 * called from a 32-bit process. Since we can never have an address
415 * greater than 32-bits from a 32-bit process we lop off the top
416 * 32-bits to avoid getting the wrong address
418 argp
= CAST_USER_ADDR_T(uap
->arg
);
421 pop
= &fdp
->fd_ofileflags
[fd
];
426 newmin
= CAST_DOWN(int, uap
->arg
);
427 if ((u_int
)newmin
>= p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
||
428 newmin
>= maxfiles
) {
432 if ( (error
= fdalloc(p
, newmin
, &i
)) )
434 error
= finishdup(p
, fdp
, fd
, i
, retval
);
438 *retval
= (*pop
& UF_EXCLOSE
)? 1 : 0;
443 *pop
= (*pop
&~ UF_EXCLOSE
) |
444 (uap
->arg
& 1)? UF_EXCLOSE
: 0;
449 *retval
= OFLAGS(fp
->f_flag
);
454 fp
->f_flag
&= ~FCNTLFLAGS
;
455 tmp
= CAST_DOWN(int, uap
->arg
);
456 fp
->f_flag
|= FFLAGS(tmp
) & FCNTLFLAGS
;
457 tmp
= fp
->f_flag
& FNONBLOCK
;
458 error
= fo_ioctl(fp
, FIONBIO
, (caddr_t
)&tmp
, p
);
461 tmp
= fp
->f_flag
& FASYNC
;
462 error
= fo_ioctl(fp
, FIOASYNC
, (caddr_t
)&tmp
, p
);
465 fp
->f_flag
&= ~FNONBLOCK
;
467 (void)fo_ioctl(fp
, FIONBIO
, (caddr_t
)&tmp
, p
);
471 if (fp
->f_type
== DTYPE_SOCKET
) {
472 *retval
= ((struct socket
*)fp
->f_data
)->so_pgid
;
476 error
= fo_ioctl(fp
, (int)TIOCGPGRP
, (caddr_t
)retval
, p
);
481 tmp
= CAST_DOWN(pid_t
, uap
->arg
);
482 if (fp
->f_type
== DTYPE_SOCKET
) {
483 ((struct socket
*)fp
->f_data
)->so_pgid
= tmp
;
487 if (fp
->f_type
== DTYPE_PIPE
) {
488 error
= fo_ioctl(fp
, (int)TIOCSPGRP
, (caddr_t
)&tmp
, p
);
495 struct proc
*p1
= pfind(tmp
);
500 tmp
= (int)p1
->p_pgrp
->pg_id
;
502 error
= fo_ioctl(fp
, (int)TIOCSPGRP
, (caddr_t
)&tmp
, p
);
507 /* Fall into F_SETLK */
510 if (fp
->f_type
!= DTYPE_VNODE
) {
514 vp
= (struct vnode
*)fp
->f_data
;
517 offset
= fp
->f_offset
;
520 /* Copy in the lock structure */
521 error
= copyin(argp
, (caddr_t
)&fl
, sizeof (fl
));
525 if ( (error
= vnode_getwithref(vp
)) ) {
528 if (fl
.l_whence
== SEEK_CUR
)
529 fl
.l_start
+= offset
;
534 if ((fflag
& FREAD
) == 0) {
539 OSBitOrAtomic(P_LADVLOCK
, &p
->p_ladvflag
);
540 error
= VNOP_ADVLOCK(vp
, (caddr_t
)p
, F_SETLK
, &fl
, flg
, &context
);
545 if ((fflag
& FWRITE
) == 0) {
550 OSBitOrAtomic(P_LADVLOCK
, &p
->p_ladvflag
);
551 error
= VNOP_ADVLOCK(vp
, (caddr_t
)p
, F_SETLK
, &fl
, flg
, &context
);
556 error
= VNOP_ADVLOCK(vp
, (caddr_t
)p
, F_UNLCK
, &fl
,
568 if (fp
->f_type
!= DTYPE_VNODE
) {
572 vp
= (struct vnode
*)fp
->f_data
;
574 offset
= fp
->f_offset
;
577 /* Copy in the lock structure */
578 error
= copyin(argp
, (caddr_t
)&fl
, sizeof (fl
));
582 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
583 if (fl
.l_whence
== SEEK_CUR
)
584 fl
.l_start
+= offset
;
586 error
= VNOP_ADVLOCK(vp
, (caddr_t
)p
, F_GETLK
, &fl
, F_POSIX
, &context
);
591 error
= copyout((caddr_t
)&fl
, argp
, sizeof (fl
));
595 case F_PREALLOCATE
: {
596 fstore_t alloc_struct
; /* structure for allocate command */
597 u_int32_t alloc_flags
= 0;
599 if (fp
->f_type
!= DTYPE_VNODE
) {
604 vp
= (struct vnode
*)fp
->f_data
;
607 /* make sure that we have write permission */
608 if ((fp
->f_flag
& FWRITE
) == 0) {
613 error
= copyin(argp
, (caddr_t
)&alloc_struct
, sizeof (alloc_struct
));
617 /* now set the space allocated to 0 */
618 alloc_struct
.fst_bytesalloc
= 0;
621 * Do some simple parameter checking
624 /* set up the flags */
626 alloc_flags
|= PREALLOCATE
;
628 if (alloc_struct
.fst_flags
& F_ALLOCATECONTIG
)
629 alloc_flags
|= ALLOCATECONTIG
;
631 if (alloc_struct
.fst_flags
& F_ALLOCATEALL
)
632 alloc_flags
|= ALLOCATEALL
;
635 * Do any position mode specific stuff. The only
636 * position mode supported now is PEOFPOSMODE
639 switch (alloc_struct
.fst_posmode
) {
642 if (alloc_struct
.fst_offset
!= 0) {
647 alloc_flags
|= ALLOCATEFROMPEOF
;
651 if (alloc_struct
.fst_offset
<= 0) {
656 alloc_flags
|= ALLOCATEFROMVOL
;
664 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
666 * call allocate to get the space
668 error
= VNOP_ALLOCATE(vp
,alloc_struct
.fst_length
,alloc_flags
,
669 &alloc_struct
.fst_bytesalloc
, alloc_struct
.fst_offset
,
673 error2
= copyout((caddr_t
)&alloc_struct
, argp
, sizeof (alloc_struct
));
682 if (fp
->f_type
!= DTYPE_VNODE
) {
688 error
= copyin(argp
, (caddr_t
)&offset
, sizeof (off_t
));
693 * Make sure that we are root. Growing a file
694 * without zero filling the data is a security hole
695 * root would have access anyway so we'll allow it
702 vp
= (struct vnode
*)fp
->f_data
;
704 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
708 error
= vnode_setsize(vp
, offset
, IO_NOZEROFILL
, &context
);
715 if (fp
->f_type
!= DTYPE_VNODE
) {
719 vp
= (struct vnode
*)fp
->f_data
;
722 if ( (error
= vnode_getwithref(vp
)) == 0) {
724 vnode_clearnoreadahead(vp
);
726 vnode_setnoreadahead(vp
);
733 if (fp
->f_type
!= DTYPE_VNODE
) {
737 vp
= (struct vnode
*)fp
->f_data
;
740 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
742 vnode_setnocache(vp
);
744 vnode_clearnocache(vp
);
750 case F_GLOBAL_NOCACHE
:
751 if (fp
->f_type
!= DTYPE_VNODE
) {
755 vp
= (struct vnode
*)fp
->f_data
;
758 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
760 *retval
= vnode_isnocache(vp
);
763 vnode_setnocache(vp
);
765 vnode_clearnocache(vp
);
772 struct radvisory ra_struct
;
774 if (fp
->f_type
!= DTYPE_VNODE
) {
778 vp
= (struct vnode
*)fp
->f_data
;
781 if ( (error
= copyin(argp
, (caddr_t
)&ra_struct
, sizeof (ra_struct
))) )
783 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
784 error
= VNOP_IOCTL(vp
, F_RDADVISE
, (caddr_t
)&ra_struct
, 0, &context
);
791 case F_READBOOTSTRAP
:
792 case F_WRITEBOOTSTRAP
: {
793 fbootstraptransfer_t fbt_struct
;
794 user_fbootstraptransfer_t user_fbt_struct
;
796 caddr_t boot_structp
;
798 if (fp
->f_type
!= DTYPE_VNODE
) {
802 vp
= (struct vnode
*)fp
->f_data
;
805 if (IS_64BIT_PROCESS(p
)) {
806 sizeof_struct
= sizeof(user_fbt_struct
);
807 boot_structp
= (caddr_t
) &user_fbt_struct
;
810 sizeof_struct
= sizeof(fbt_struct
);
811 boot_structp
= (caddr_t
) &fbt_struct
;
813 error
= copyin(argp
, boot_structp
, sizeof_struct
);
816 if ( (error
= vnode_getwithref(vp
)) ) {
819 if (uap
->cmd
== F_WRITEBOOTSTRAP
) {
821 * Make sure that we are root. Updating the
822 * bootstrap on a disk could be a security hole
830 if (strcmp(vnode_mount(vp
)->mnt_vfsstat
.f_fstypename
, "hfs") != 0) {
834 * call vnop_ioctl to handle the I/O
836 error
= VNOP_IOCTL(vp
, uap
->cmd
, boot_structp
, 0, &context
);
842 struct log2phys l2p_struct
; /* structure for allocate command */
844 if (fp
->f_type
!= DTYPE_VNODE
) {
848 vp
= (struct vnode
*)fp
->f_data
;
850 if ( (error
= vnode_getwithref(vp
)) ) {
853 error
= VNOP_OFFTOBLK(vp
, fp
->f_offset
, &lbn
);
858 error
= VNOP_BLKTOOFF(vp
, lbn
, &offset
);
863 devBlockSize
= vfs_devblocksize(vnode_mount(vp
));
865 error
= VNOP_BLOCKMAP(vp
, offset
, devBlockSize
, &bn
, NULL
, NULL
, 0, &context
);
870 l2p_struct
.l2p_flags
= 0; /* for now */
871 l2p_struct
.l2p_contigbytes
= 0; /* for now */
872 l2p_struct
.l2p_devoffset
= bn
* devBlockSize
;
873 l2p_struct
.l2p_devoffset
+= fp
->f_offset
- offset
;
874 error
= copyout((caddr_t
)&l2p_struct
, argp
, sizeof (l2p_struct
));
882 if (fp
->f_type
!= DTYPE_VNODE
) {
886 vp
= (struct vnode
*)fp
->f_data
;
889 pathlen
= MAXPATHLEN
;
890 MALLOC(pathbufp
, char *, pathlen
, M_TEMP
, M_WAITOK
);
891 if (pathbufp
== NULL
) {
895 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
896 error
= vn_getpath(vp
, pathbufp
, &pathlen
);
900 error
= copyout((caddr_t
)pathbufp
, argp
, pathlen
);
902 FREE(pathbufp
, M_TEMP
);
906 case F_PATHPKG_CHECK
: {
910 if (fp
->f_type
!= DTYPE_VNODE
) {
914 vp
= (struct vnode
*)fp
->f_data
;
917 pathlen
= MAXPATHLEN
;
918 pathbufp
= kalloc(MAXPATHLEN
);
920 if ( (error
= copyinstr(argp
, pathbufp
, MAXPATHLEN
, &pathlen
)) == 0 ) {
921 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
922 error
= vn_path_package_check(vp
, pathbufp
, pathlen
, retval
);
927 kfree(pathbufp
, MAXPATHLEN
);
931 case F_CHKCLEAN
: // used by regression tests to see if all dirty pages got cleaned by fsync()
932 case F_FULLFSYNC
: // fsync + flush the journal + DKIOCSYNCHRONIZECACHE
933 case F_FREEZE_FS
: // freeze all other fs operations for the fs of this fd
934 case F_THAW_FS
: { // thaw all frozen fs operations for the fs of this fd
935 if (fp
->f_type
!= DTYPE_VNODE
) {
939 vp
= (struct vnode
*)fp
->f_data
;
942 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
943 error
= VNOP_IOCTL(vp
, uap
->cmd
, (caddr_t
)NULL
, 0, &context
);
951 if (uap
->cmd
< FCNTL_FS_SPECIFIC_BASE
) {
956 // if it's a fs-specific fcntl() then just pass it through
958 if (fp
->f_type
!= DTYPE_VNODE
) {
962 vp
= (struct vnode
*)fp
->f_data
;
965 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
966 error
= VNOP_IOCTL(vp
, uap
->cmd
, CAST_DOWN(caddr_t
, argp
), 0, &context
);
975 AUDIT_ARG(vnpath_withref
, vp
, ARG_VNODE1
);
976 fp_drop(p
, fd
, fp
, 0);
979 fp_drop(p
, fd
, fp
, 1);
985 * Common code for dup, dup2, and fcntl(F_DUPFD).
988 finishdup(struct proc
* p
, struct filedesc
*fdp
, int old
, int new, register_t
*retval
)
990 struct fileproc
*nfp
;
991 struct fileproc
*ofp
;
993 if ((ofp
= fdp
->fd_ofiles
[old
]) == NULL
||
994 (fdp
->fd_ofileflags
[old
] & UF_RESERVED
)) {
1001 MALLOC_ZONE(nfp
, struct fileproc
*, sizeof(struct fileproc
), M_FILEPROC
, M_WAITOK
);
1002 bzero(nfp
, sizeof(struct fileproc
));
1006 nfp
->f_fglob
= ofp
->f_fglob
;
1009 if (new > fdp
->fd_lastfile
)
1010 fdp
->fd_lastfile
= new;
1011 procfdtbl_releasefd(p
, new, nfp
);
1018 close(struct proc
*p
, struct close_args
*uap
, __unused register_t
*retval
)
1020 struct fileproc
*fp
;
1024 AUDIT_SYSCLOSE(p
, fd
);
1028 if ( (error
= fp_lookup(p
,fd
,&fp
, 1)) ) {
1033 error
= close_internal(p
, fd
, fp
, CLOSEINT_LOCKED
);
1042 * Close a file descriptor.
1045 close_internal(struct proc
*p
, int fd
, struct fileproc
*fp
, int flags
)
1047 struct filedesc
*fdp
= p
->p_fd
;
1049 int locked
= flags
& CLOSEINT_LOCKED
;
1050 int waitonclose
= flags
& CLOSEINT_WAITONCLOSE
;
1051 int norelse
= flags
& CLOSEINT_NOFDRELSE
;
1052 int nofdref
= flags
& CLOSEINT_NOFDNOREF
;
1053 int slpstate
= PRIBIO
;
1058 /* Keep people from using the filedesc while we are closing it */
1059 procfdtbl_markclosefd(p
, fd
);
1060 if ((fp
->f_flags
& FP_CLOSING
) == FP_CLOSING
) {
1061 panic("close_internal_locked: being called on already closing fd\n");
1066 fp
->f_flags
|= FP_CLOSING
;
1070 if ( (fp
->f_flags
& FP_AIOISSUED
) || kauth_authorize_fileop_has_listeners() ) {
1074 if ( (fp
->f_type
== DTYPE_VNODE
) && kauth_authorize_fileop_has_listeners() ) {
1076 * call out to allow 3rd party notification of close.
1077 * Ignore result of kauth_authorize_fileop call.
1079 if (vnode_getwithref((vnode_t
)fp
->f_data
) == 0) {
1080 u_int fileop_flags
= 0;
1081 if ((fp
->f_flags
& FP_WRITTEN
) != 0)
1082 fileop_flags
|= KAUTH_FILEOP_CLOSE_MODIFIED
;
1083 kauth_authorize_fileop(fp
->f_fglob
->fg_cred
, KAUTH_FILEOP_CLOSE
,
1084 (uintptr_t)fp
->f_data
, (uintptr_t)fileop_flags
);
1085 vnode_put((vnode_t
)fp
->f_data
);
1088 if (fp
->f_flags
& FP_AIOISSUED
)
1090 * cancel all async IO requests that can be cancelled.
1092 _aio_close( p
, fd
);
1097 if (fd
< fdp
->fd_knlistsize
)
1098 knote_fdclose(p
, fd
);
1100 if (fp
->f_flags
& FP_WAITEVENT
)
1101 (void)waitevent_close(p
, fp
);
1103 if ((fp
->f_flags
& FP_INCHRREAD
) == 0)
1104 fileproc_drain(p
, fp
);
1107 error
= closef_locked(fp
, fp
->f_fglob
, p
);
1108 if ((fp
->f_flags
& FP_WAITCLOSE
) == FP_WAITCLOSE
)
1109 wakeup(&fp
->f_flags
);
1110 fp
->f_flags
&= ~(FP_WAITCLOSE
| FP_CLOSING
);
1115 FREE_ZONE(fp
, sizeof *fp
, M_FILEPROC
);
1120 * Return status information about a file descriptor.
1122 * XXX switch on node type is bogus; need a stat in struct fileops instead.
1125 fstat1(struct proc
*p
, int fd
, user_addr_t ub
, user_addr_t xsecurity
, user_addr_t xsecurity_size
)
1127 struct fileproc
*fp
;
1129 struct user_stat user_sb
;
1134 kauth_filesec_t fsec
;
1135 ssize_t xsecurity_bufsize
;
1137 struct vfs_context context
;
1142 if ((error
= fp_lookup(p
, fd
, &fp
, 0)) != 0)
1146 fsec
= KAUTH_FILESEC_NONE
;
1151 context
.vc_proc
= current_proc();
1152 context
.vc_ucred
= kauth_cred_get();
1153 if ((error
= vnode_getwithref((vnode_t
)data
)) == 0) {
1155 * If the caller has the file open, and is not requesting extended security,
1156 * we are going to let them get the basic stat information.
1158 if (xsecurity
== USER_ADDR_NULL
) {
1159 error
= vn_stat_noauth((vnode_t
)data
, &sb
, NULL
, &context
);
1161 error
= vn_stat((vnode_t
)data
, &sb
, &fsec
, &context
);
1164 AUDIT_ARG(vnpath
, (struct vnode
*)data
, ARG_VNODE1
);
1165 (void)vnode_put((vnode_t
)data
);
1170 error
= soo_stat((struct socket
*)data
, &sb
);
1174 error
= pipe_stat((void *)data
, &sb
);
1178 error
= pshm_stat((void *)data
, &sb
);
1182 funnel_state
= thread_funnel_set(kernel_flock
, TRUE
);
1183 error
= kqueue_stat(fp
, &sb
, p
);
1184 thread_funnel_set(kernel_flock
, funnel_state
);
1191 /* Zap spare fields */
1193 sb
.st_qspare
[0] = 0LL;
1194 sb
.st_qspare
[1] = 0LL;
1197 if (IS_64BIT_PROCESS(current_proc())) {
1198 munge_stat(&sb
, &user_sb
);
1199 my_size
= sizeof(user_sb
);
1200 sbp
= (caddr_t
)&user_sb
;
1203 my_size
= sizeof(sb
);
1206 error
= copyout(sbp
, ub
, my_size
);
1209 /* caller wants extended security information? */
1210 if (xsecurity
!= USER_ADDR_NULL
) {
1212 /* did we get any? */
1213 if (fsec
== KAUTH_FILESEC_NONE
) {
1214 if (susize(xsecurity_size
, 0) != 0) {
1219 /* find the user buffer size */
1220 xsecurity_bufsize
= fusize(xsecurity_size
);
1222 /* copy out the actual data size */
1223 if (susize(xsecurity_size
, KAUTH_FILESEC_COPYSIZE(fsec
)) != 0) {
1228 /* if the caller supplied enough room, copy out to it */
1229 if (xsecurity_bufsize
>= KAUTH_FILESEC_COPYSIZE(fsec
))
1230 error
= copyout(fsec
, xsecurity
, KAUTH_FILESEC_COPYSIZE(fsec
));
1234 fp_drop(p
, fd
, fp
, 0);
1236 kauth_filesec_free(fsec
);
1241 fstat_extended(struct proc
*p
, struct fstat_extended_args
*uap
, __unused register_t
*retval
)
1243 return(fstat1(p
, uap
->fd
, uap
->ub
, uap
->xsecurity
, uap
->xsecurity_size
));
1247 fstat(struct proc
*p
, register struct fstat_args
*uap
, __unused register_t
*retval
)
1249 return(fstat1(p
, uap
->fd
, uap
->ub
, 0, 0));
1253 * Return pathconf information about a file descriptor.
1256 fpathconf(p
, uap
, retval
)
1258 register struct fpathconf_args
*uap
;
1262 struct fileproc
*fp
;
1264 struct vfs_context context
;
1270 AUDIT_ARG(fd
, uap
->fd
);
1271 if ( (error
= fp_lookup(p
, fd
, &fp
, 0)) )
1279 if (uap
->name
!= _PC_PIPE_BUF
) {
1293 vp
= (struct vnode
*)data
;
1295 if ( (error
= vnode_getwithref(vp
)) == 0) {
1296 AUDIT_ARG(vnpath
, vp
, ARG_VNODE1
);
1298 context
.vc_proc
= p
;
1299 context
.vc_ucred
= kauth_cred_get();
1301 error
= vn_pathconf(vp
, uap
->name
, retval
, &context
);
1303 (void)vnode_put(vp
);
1310 case DTYPE_FSEVENTS
:
1317 fp_drop(p
, fd
, fp
, 0);
1322 * Allocate a file descriptor for the process.
1327 fdalloc(p
, want
, result
)
1332 register struct filedesc
*fdp
= p
->p_fd
;
1334 int lim
, last
, numfiles
, oldnfiles
;
1335 struct fileproc
**newofiles
, **ofiles
;
1336 char *newofileflags
;
1339 * Search for a free descriptor starting at the higher
1340 * of want or fd_freefile. If that fails, consider
1341 * expanding the ofile array.
1343 lim
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
1345 last
= min(fdp
->fd_nfiles
, lim
);
1346 if ((i
= want
) < fdp
->fd_freefile
)
1347 i
= fdp
->fd_freefile
;
1348 for (; i
< last
; i
++) {
1349 if (fdp
->fd_ofiles
[i
] == NULL
&& !(fdp
->fd_ofileflags
[i
] & UF_RESERVED
)) {
1350 procfdtbl_reservefd(p
, i
);
1351 if (i
> fdp
->fd_lastfile
)
1352 fdp
->fd_lastfile
= i
;
1353 if (want
<= fdp
->fd_freefile
)
1354 fdp
->fd_freefile
= i
;
1361 * No space in current array. Expand?
1363 if (fdp
->fd_nfiles
>= lim
)
1365 if (fdp
->fd_nfiles
< NDEXTENT
)
1366 numfiles
= NDEXTENT
;
1368 numfiles
= 2 * fdp
->fd_nfiles
;
1373 MALLOC_ZONE(newofiles
, struct fileproc
**,
1374 numfiles
* OFILESIZE
, M_OFILETABL
, M_WAITOK
);
1376 if (newofiles
== NULL
) {
1379 if (fdp
->fd_nfiles
>= numfiles
) {
1380 FREE_ZONE(newofiles
, numfiles
* OFILESIZE
, M_OFILETABL
);
1383 newofileflags
= (char *) &newofiles
[numfiles
];
1385 * Copy the existing ofile and ofileflags arrays
1386 * and zero the new portion of each array.
1388 oldnfiles
= fdp
->fd_nfiles
;
1389 (void) memcpy(newofiles
, fdp
->fd_ofiles
,
1390 oldnfiles
* sizeof *fdp
->fd_ofiles
);
1391 (void) memset(&newofiles
[oldnfiles
], 0,
1392 (numfiles
- oldnfiles
) * sizeof *fdp
->fd_ofiles
);
1394 (void) memcpy(newofileflags
, fdp
->fd_ofileflags
,
1395 oldnfiles
* sizeof *fdp
->fd_ofileflags
);
1396 (void) memset(&newofileflags
[oldnfiles
], 0,
1397 (numfiles
- oldnfiles
) *
1398 sizeof *fdp
->fd_ofileflags
);
1399 ofiles
= fdp
->fd_ofiles
;
1400 fdp
->fd_ofiles
= newofiles
;
1401 fdp
->fd_ofileflags
= newofileflags
;
1402 fdp
->fd_nfiles
= numfiles
;
1403 FREE_ZONE(ofiles
, oldnfiles
* OFILESIZE
, M_OFILETABL
);
1409 * Check to see whether n user file descriptors
1410 * are available to the process p.
1417 struct filedesc
*fdp
= p
->p_fd
;
1418 struct fileproc
**fpp
;
1422 lim
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
1423 if ((i
= lim
- fdp
->fd_nfiles
) > 0 && (n
-= i
) <= 0)
1425 fpp
= &fdp
->fd_ofiles
[fdp
->fd_freefile
];
1426 flags
= &fdp
->fd_ofileflags
[fdp
->fd_freefile
];
1427 for (i
= fdp
->fd_nfiles
- fdp
->fd_freefile
; --i
>= 0; fpp
++, flags
++)
1428 if (*fpp
== NULL
&& !(*flags
& UF_RESERVED
) && --n
<= 0)
1446 struct filedesc
*fdp
= p
->p_fd
;
1447 struct fileproc
*fp
;
1449 if (fd
< fdp
->fd_freefile
)
1450 fdp
->fd_freefile
= fd
;
1452 if (fd
> fdp
->fd_lastfile
)
1453 panic("fdrelse: fd_lastfile inconsistent");
1455 fp
= fdp
->fd_ofiles
[fd
];
1456 fdp
->fd_ofiles
[fd
] = NULL
;
1457 fdp
->fd_ofileflags
[fd
] = 0;
1459 while ((fd
= fdp
->fd_lastfile
) > 0 &&
1460 fdp
->fd_ofiles
[fd
] == NULL
&&
1461 !(fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
1463 FREE_ZONE(fp
, sizeof *fp
, M_FILEPROC
);
1468 fdgetf_noref(p
, fd
, resultfp
)
1471 struct fileproc
**resultfp
;
1473 struct filedesc
*fdp
= p
->p_fd
;
1474 struct fileproc
*fp
;
1476 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1477 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1478 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1487 /* should be called only when proc_fdlock is held */
1489 fp_setflags(proc_t p
, struct fileproc
* fp
, int flags
)
1492 fp
->f_flags
|= flags
;
1497 fp_clearflags(proc_t p
, struct fileproc
* fp
, int flags
)
1502 fp
->f_flags
&= ~flags
;
1507 fp_getfvp(p
, fd
, resultfp
, resultvp
)
1510 struct fileproc
**resultfp
;
1511 struct vnode
**resultvp
;
1513 struct filedesc
*fdp
= p
->p_fd
;
1514 struct fileproc
*fp
;
1517 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1518 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1519 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1523 if (fp
->f_type
!= DTYPE_VNODE
) {
1532 *resultvp
= (struct vnode
*)fp
->f_data
;
1540 * Returns: EBADF The file descriptor is invalid
1541 * EOPNOTSUPP The file descriptor is not a socket
1544 * Notes: EOPNOTSUPP should probably be ENOTSOCK; this function is only
1545 * ever called from accept1().
1548 fp_getfsock(p
, fd
, resultfp
, results
)
1551 struct fileproc
**resultfp
;
1552 struct socket
**results
;
1554 struct filedesc
*fdp
= p
->p_fd
;
1555 struct fileproc
*fp
;
1558 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1559 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1560 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1564 if (fp
->f_type
!= DTYPE_SOCKET
) {
1573 *results
= (struct socket
*)fp
->f_data
;
1581 fp_getfkq(p
, fd
, resultfp
, resultkq
)
1584 struct fileproc
**resultfp
;
1585 struct kqueue
**resultkq
;
1587 struct filedesc
*fdp
= p
->p_fd
;
1588 struct fileproc
*fp
;
1591 if ( fd
< 0 || fd
>= fdp
->fd_nfiles
||
1592 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1593 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1597 if (fp
->f_type
!= DTYPE_KQUEUE
) {
1606 *resultkq
= (struct kqueue
*)fp
->f_data
;
1613 fp_getfpshm(p
, fd
, resultfp
, resultpshm
)
1616 struct fileproc
**resultfp
;
1617 struct pshmnode
**resultpshm
;
1619 struct filedesc
*fdp
= p
->p_fd
;
1620 struct fileproc
*fp
;
1623 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1624 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1625 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1629 if (fp
->f_type
!= DTYPE_PSXSHM
) {
1639 *resultpshm
= (struct pshmnode
*)fp
->f_data
;
1647 fp_getfpsem(p
, fd
, resultfp
, resultpsem
)
1650 struct fileproc
**resultfp
;
1651 struct psemnode
**resultpsem
;
1653 struct filedesc
*fdp
= p
->p_fd
;
1654 struct fileproc
*fp
;
1657 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1658 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1659 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1663 if (fp
->f_type
!= DTYPE_PSXSEM
) {
1672 *resultpsem
= (struct psemnode
*)fp
->f_data
;
1678 fp_lookup(p
, fd
, resultfp
, locked
)
1681 struct fileproc
**resultfp
;
1684 struct filedesc
*fdp
= p
->p_fd
;
1685 struct fileproc
*fp
;
1689 if (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1690 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1691 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
)) {
1707 fp_drop_written(proc_t p
, int fd
, struct fileproc
*fp
)
1713 fp
->f_flags
|= FP_WRITTEN
;
1715 error
= fp_drop(p
, fd
, fp
, 1);
1724 fp_drop_event(proc_t p
, int fd
, struct fileproc
*fp
)
1730 fp
->f_flags
|= FP_WAITEVENT
;
1732 error
= fp_drop(p
, fd
, fp
, 1);
1740 fp_drop(p
, fd
, fp
, locked
)
1743 struct fileproc
*fp
;
1746 struct filedesc
*fdp
= p
->p_fd
;
1750 if ((fp
== FILEPROC_NULL
) && (fd
< 0 || fd
>= fdp
->fd_nfiles
||
1751 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1752 ((fdp
->fd_ofileflags
[fd
] & UF_RESERVED
) &&
1753 !(fdp
->fd_ofileflags
[fd
] & UF_CLOSING
)))) {
1760 if (p
->p_fpdrainwait
&& fp
->f_iocount
== 0) {
1761 p
->p_fpdrainwait
= 0;
1762 wakeup(&p
->p_fpdrainwait
);
1771 file_vnode(int fd
, struct vnode
**vpp
)
1773 struct proc
* p
= current_proc();
1774 struct fileproc
*fp
;
1778 if ( (error
= fp_lookup(p
, fd
, &fp
, 1)) ) {
1782 if (fp
->f_type
!= DTYPE_VNODE
) {
1783 fp_drop(p
, fd
, fp
,1);
1787 *vpp
= (struct vnode
*)fp
->f_data
;
1795 file_socket(int fd
, struct socket
**sp
)
1797 struct proc
* p
= current_proc();
1798 struct fileproc
*fp
;
1802 if ( (error
= fp_lookup(p
, fd
, &fp
, 1)) ) {
1806 if (fp
->f_type
!= DTYPE_SOCKET
) {
1807 fp_drop(p
, fd
, fp
,1);
1811 *sp
= (struct socket
*)fp
->f_data
;
1818 file_flags(int fd
, int * flags
)
1821 struct proc
* p
= current_proc();
1822 struct fileproc
*fp
;
1826 if ( (error
= fp_lookup(p
, fd
, &fp
, 1)) ) {
1830 *flags
= (int)fp
->f_flag
;
1831 fp_drop(p
, fd
, fp
,1);
1841 struct fileproc
*fp
;
1842 struct proc
*p
= current_proc();
1845 if (fd
< 0 || fd
>= p
->p_fd
->fd_nfiles
||
1846 (fp
= p
->p_fd
->fd_ofiles
[fd
]) == NULL
||
1847 ((p
->p_fd
->fd_ofileflags
[fd
] & UF_RESERVED
) &&
1848 !(p
->p_fd
->fd_ofileflags
[fd
] & UF_CLOSING
))) {
1854 if (p
->p_fpdrainwait
&& fp
->f_iocount
== 0) {
1855 p
->p_fpdrainwait
= 0;
1856 wakeup(&p
->p_fpdrainwait
);
1865 falloc(p
, resultfp
, resultfd
)
1867 struct fileproc
**resultfp
;
1873 error
= falloc_locked(p
, resultfp
, resultfd
, 1);
1879 * Create a new open file structure and allocate
1880 * a file decriptor for the process that refers to it.
1883 falloc_locked(p
, resultfp
, resultfd
, locked
)
1885 struct fileproc
**resultfp
;
1889 struct fileproc
*fp
, *fq
;
1890 struct fileglob
*fg
;
1895 if ( (error
= fdalloc(p
, 0, &nfd
)) ) {
1900 if (nfiles
>= maxfiles
) {
1907 * Allocate a new file descriptor.
1908 * If the process has file descriptor zero open, add to the list
1909 * of open files at that point, otherwise put it at the front of
1910 * the list of open files.
1914 MALLOC_ZONE(fp
, struct fileproc
*, sizeof(struct fileproc
), M_FILEPROC
, M_WAITOK
);
1915 MALLOC_ZONE(fg
, struct fileglob
*, sizeof(struct fileglob
), M_FILEGLOB
, M_WAITOK
);
1916 bzero(fp
, sizeof(struct fileproc
));
1917 bzero(fg
, sizeof(struct fileglob
));
1918 lck_mtx_init(&fg
->fg_lock
, file_lck_grp
, file_lck_attr
);
1926 fp
->f_cred
= kauth_cred_proc_ref(p
);
1928 lck_mtx_lock(file_flist_lock
);
1932 if ( (fq
= p
->p_fd
->fd_ofiles
[0]) ) {
1933 LIST_INSERT_AFTER(fq
->f_fglob
, fg
, f_list
);
1935 LIST_INSERT_HEAD(&filehead
, fg
, f_list
);
1937 lck_mtx_unlock(file_flist_lock
);
1939 p
->p_fd
->fd_ofiles
[nfd
] = fp
;
1953 * Free a file structure.
1957 struct fileglob
*fg
;
1961 lck_mtx_lock(file_flist_lock
);
1962 LIST_REMOVE(fg
, f_list
);
1964 lck_mtx_unlock(file_flist_lock
);
1967 if (cred
!= NOCRED
) {
1968 fg
->fg_cred
= NOCRED
;
1969 kauth_cred_rele(cred
);
1971 lck_mtx_destroy(&fg
->fg_lock
, file_lck_grp
);
1973 FREE_ZONE(fg
, sizeof *fg
, M_FILEGLOB
);
1980 struct filedesc
*fdp
= p
->p_fd
;
1981 int i
= fdp
->fd_lastfile
;
1982 struct fileproc
*fp
;
1985 funnel_state
= thread_funnel_set(kernel_flock
, FALSE
);
1989 fp
= fdp
->fd_ofiles
[i
];
1990 if ((fdp
->fd_ofileflags
[i
] & (UF_RESERVED
|UF_EXCLOSE
)) == UF_EXCLOSE
) {
1992 if (i
< fdp
->fd_knlistsize
)
1993 knote_fdclose(p
, i
);
1995 procfdtbl_clearfd(p
, i
);
1996 if (i
== fdp
->fd_lastfile
&& i
> 0)
1998 if (i
< fdp
->fd_freefile
)
1999 fdp
->fd_freefile
= i
;
2000 closef_locked(fp
, fp
->f_fglob
, p
);
2001 FREE_ZONE(fp
, sizeof *fp
, M_FILEPROC
);
2007 thread_funnel_set(kernel_flock
, funnel_state
);
2011 * Copy a filedesc structure.
2017 struct filedesc
*newfdp
, *fdp
= p
->p_fd
;
2019 struct fileproc
*ofp
, *fp
;
2022 MALLOC_ZONE(newfdp
, struct filedesc
*,
2023 sizeof(*newfdp
), M_FILEDESC
, M_WAITOK
);
2030 * the FD_CHROOT flag will be inherited via this copy
2032 (void) memcpy(newfdp
, fdp
, sizeof(*newfdp
));
2035 * for both fd_cdir and fd_rdir make sure we get
2036 * a valid reference... if we can't, than set
2037 * set the pointer(s) to NULL in the child... this
2038 * will keep us from using a non-referenced vp
2039 * and allows us to do the vnode_rele only on
2040 * a properly referenced vp
2042 if ( (v_dir
= newfdp
->fd_cdir
) ) {
2043 if (vnode_getwithref(v_dir
) == 0) {
2044 if ( (vnode_ref(v_dir
)) )
2045 newfdp
->fd_cdir
= NULL
;
2048 newfdp
->fd_cdir
= NULL
;
2050 if (newfdp
->fd_cdir
== NULL
&& fdp
->fd_cdir
) {
2052 * we couldn't get a new reference on
2053 * the current working directory being
2054 * inherited... we might as well drop
2055 * our reference from the parent also
2056 * since the vnode has gone DEAD making
2057 * it useless... by dropping it we'll
2058 * be that much closer to recyling it
2060 vnode_rele(fdp
->fd_cdir
);
2061 fdp
->fd_cdir
= NULL
;
2064 if ( (v_dir
= newfdp
->fd_rdir
) ) {
2065 if (vnode_getwithref(v_dir
) == 0) {
2066 if ( (vnode_ref(v_dir
)) )
2067 newfdp
->fd_rdir
= NULL
;
2070 newfdp
->fd_rdir
= NULL
;
2072 if (newfdp
->fd_rdir
== NULL
&& fdp
->fd_rdir
) {
2074 * we couldn't get a new reference on
2075 * the root directory being
2076 * inherited... we might as well drop
2077 * our reference from the parent also
2078 * since the vnode has gone DEAD making
2079 * it useless... by dropping it we'll
2080 * be that much closer to recyling it
2082 vnode_rele(fdp
->fd_rdir
);
2083 fdp
->fd_rdir
= NULL
;
2085 newfdp
->fd_refcnt
= 1;
2088 * If the number of open files fits in the internal arrays
2089 * of the open file structure, use them, otherwise allocate
2090 * additional memory for the number of descriptors currently
2093 if (newfdp
->fd_lastfile
< NDFILE
)
2097 * Compute the smallest multiple of NDEXTENT needed
2098 * for the file descriptors currently in use,
2099 * allowing the table to shrink.
2101 i
= newfdp
->fd_nfiles
;
2102 while (i
> 2 * NDEXTENT
&& i
> newfdp
->fd_lastfile
* 2)
2107 MALLOC_ZONE(newfdp
->fd_ofiles
, struct fileproc
**,
2108 i
* OFILESIZE
, M_OFILETABL
, M_WAITOK
);
2109 if (newfdp
->fd_ofiles
== NULL
) {
2110 if (newfdp
->fd_cdir
)
2111 vnode_rele(newfdp
->fd_cdir
);
2112 if (newfdp
->fd_rdir
)
2113 vnode_rele(newfdp
->fd_rdir
);
2115 FREE_ZONE(newfdp
, sizeof *newfdp
, M_FILEDESC
);
2118 (void) memset(newfdp
->fd_ofiles
, 0, i
* OFILESIZE
);
2121 newfdp
->fd_ofileflags
= (char *) &newfdp
->fd_ofiles
[i
];
2122 newfdp
->fd_nfiles
= i
;
2124 if (fdp
->fd_nfiles
> 0) {
2125 struct fileproc
**fpp
;
2128 (void) memcpy(newfdp
->fd_ofiles
, fdp
->fd_ofiles
,
2129 (newfdp
->fd_lastfile
+ 1) * sizeof *fdp
->fd_ofiles
);
2130 (void) memcpy(newfdp
->fd_ofileflags
, fdp
->fd_ofileflags
,
2131 (newfdp
->fd_lastfile
+ 1) * sizeof *fdp
->fd_ofileflags
);
2134 * kq descriptors cannot be copied.
2136 if (newfdp
->fd_knlistsize
!= -1) {
2137 fpp
= &newfdp
->fd_ofiles
[newfdp
->fd_lastfile
];
2138 for (i
= newfdp
->fd_lastfile
; i
>= 0; i
--, fpp
--) {
2139 if (*fpp
!= NULL
&& (*fpp
)->f_type
== DTYPE_KQUEUE
) {
2141 if (i
< newfdp
->fd_freefile
)
2142 newfdp
->fd_freefile
= i
;
2144 if (*fpp
== NULL
&& i
== newfdp
->fd_lastfile
&& i
> 0)
2145 newfdp
->fd_lastfile
--;
2147 newfdp
->fd_knlist
= NULL
;
2148 newfdp
->fd_knlistsize
= -1;
2149 newfdp
->fd_knhash
= NULL
;
2150 newfdp
->fd_knhashmask
= 0;
2152 fpp
= newfdp
->fd_ofiles
;
2153 flags
= newfdp
->fd_ofileflags
;
2155 for (i
= newfdp
->fd_lastfile
+ 1; --i
>= 0; fpp
++, flags
++)
2156 if ((ofp
= *fpp
) != NULL
&& !(*flags
& UF_RESERVED
)) {
2157 MALLOC_ZONE(fp
, struct fileproc
*, sizeof(struct fileproc
), M_FILEPROC
, M_WAITOK
);
2158 bzero(fp
, sizeof(struct fileproc
));
2159 fp
->f_flags
= ofp
->f_flags
;
2160 //fp->f_iocount = ofp->f_iocount;
2162 fp
->f_fglob
= ofp
->f_fglob
;
2166 if (i
< newfdp
->fd_freefile
)
2167 newfdp
->fd_freefile
= i
;
2178 * Release a filedesc structure.
2184 struct filedesc
*fdp
;
2185 struct fileproc
*fp
;
2190 /* Certain daemons might not have file descriptors */
2193 if ((fdp
== NULL
) || (--fdp
->fd_refcnt
> 0)) {
2197 if (fdp
->fd_refcnt
== 0xffff)
2198 panic("fdfree: bad fd_refcnt");
2200 /* Last reference: the structure can't change out from under us */
2202 if (fdp
->fd_nfiles
> 0 && fdp
->fd_ofiles
) {
2203 for (i
= fdp
->fd_lastfile
; i
>= 0; i
--) {
2204 if ((fp
= fdp
->fd_ofiles
[i
]) != NULL
) {
2206 if (fdp
->fd_ofileflags
[i
] & UF_RESERVED
)
2207 panic("fdfree: found fp with UF_RESERVED\n");
2209 /* closef drops the iocount ... */
2210 if ((fp
->f_flags
& FP_INCHRREAD
) != 0)
2212 procfdtbl_reservefd(p
, i
);
2214 if (i
< fdp
->fd_knlistsize
)
2215 knote_fdclose(p
, i
);
2216 if (fp
->f_flags
& FP_WAITEVENT
)
2217 (void)waitevent_close(p
, fp
);
2218 (void) closef_locked(fp
, fp
->f_fglob
, p
);
2219 FREE_ZONE(fp
, sizeof *fp
, M_FILEPROC
);
2222 FREE_ZONE(fdp
->fd_ofiles
, fdp
->fd_nfiles
* OFILESIZE
, M_OFILETABL
);
2223 fdp
->fd_ofiles
= NULL
;
2230 vnode_rele(fdp
->fd_cdir
);
2232 vnode_rele(fdp
->fd_rdir
);
2239 FREE(fdp
->fd_knlist
, M_KQUEUE
);
2241 FREE(fdp
->fd_knhash
, M_KQUEUE
);
2243 FREE_ZONE(fdp
, sizeof *fdp
, M_FILEDESC
);
2247 closef_finish(fp
, fg
, p
)
2248 struct fileproc
*fp
;
2249 struct fileglob
*fg
;
2255 struct vfs_context context
;
2257 if ((fg
->fg_flag
& FHASLOCK
) && fg
->fg_type
== DTYPE_VNODE
) {
2258 lf
.l_whence
= SEEK_SET
;
2261 lf
.l_type
= F_UNLCK
;
2262 vp
= (struct vnode
*)fg
->fg_data
;
2263 context
.vc_proc
= p
;
2264 context
.vc_ucred
= fg
->fg_cred
;
2266 (void) VNOP_ADVLOCK(vp
, (caddr_t
)fg
, F_UNLCK
, &lf
, F_FLOCK
, &context
);
2269 error
= fo_close(fg
, p
);
2273 if (((fp
!= (struct fileproc
*)0) && ((fp
->f_flags
& FP_INCHRREAD
) != 0))) {
2275 if ( ((fp
->f_flags
& FP_INCHRREAD
) != 0) ) {
2276 fileproc_drain(p
, fp
);
2287 struct fileglob
*fg
;
2293 error
= closef_locked((struct fileproc
*)0, fg
, p
);
2299 * Internal form of close.
2300 * Decrement reference count on file structure.
2301 * Note: p may be NULL when closing a file
2302 * that was being passed in a message.
2305 closef_locked(fp
, fg
, p
)
2306 struct fileproc
*fp
;
2307 struct fileglob
*fg
;
2312 struct vfs_context context
;
2319 * POSIX record locking dictates that any close releases ALL
2320 * locks owned by this process. This is handled by setting
2321 * a flag in the unlock to free ONLY locks obeying POSIX
2322 * semantics, and not to free BSD-style file locks.
2323 * If the descriptor was in a message, POSIX-style locks
2324 * aren't passed with the descriptor.
2326 if (p
&& (p
->p_ladvflag
& P_LADVLOCK
) && fg
->fg_type
== DTYPE_VNODE
) {
2329 lf
.l_whence
= SEEK_SET
;
2332 lf
.l_type
= F_UNLCK
;
2333 vp
= (struct vnode
*)fg
->fg_data
;
2335 if ( (error
= vnode_getwithref(vp
)) == 0 ) {
2336 context
.vc_proc
= p
;
2337 context
.vc_ucred
= fg
->fg_cred
;
2338 (void) VNOP_ADVLOCK(vp
, (caddr_t
)p
, F_UNLCK
, &lf
, F_POSIX
, &context
);
2340 (void)vnode_put(vp
);
2344 lck_mtx_lock(&fg
->fg_lock
);
2347 if (fg
->fg_count
> 0) {
2348 lck_mtx_unlock(&fg
->fg_lock
);
2351 if (fg
->fg_count
!= 0)
2352 panic("fg: being freed with bad fg_count (%d)", fg
, fg
->fg_count
);
2354 if (fp
&& (fp
->f_flags
& FP_WRITTEN
))
2355 fg
->fg_flag
|= FWASWRITTEN
;
2357 fg
->fg_lflags
|= FG_TERM
;
2358 lck_mtx_unlock(&fg
->fg_lock
);
2361 error
= closef_finish(fp
, fg
, p
);
2370 fileproc_drain(struct proc
*p
, struct fileproc
* fp
)
2372 fp
->f_iocount
-- ; /* (the one the close holds) */
2374 while (fp
->f_iocount
) {
2375 if (((fp
->f_flags
& FP_INSELECT
)== FP_INSELECT
)) {
2376 wait_queue_wakeup_all((wait_queue_t
)fp
->f_waddr
, &selwait
, THREAD_INTERRUPTED
);
2378 if (fp
->f_fglob
->fg_ops
->fo_drain
) {
2379 (*fp
->f_fglob
->fg_ops
->fo_drain
)(fp
, p
);
2382 p
->p_fpdrainwait
= 1;
2384 msleep(&p
->p_fpdrainwait
, &p
->p_fdmlock
, PRIBIO
, "fpdrain",0);
2386 //panic("successful wait after drain\n");
2391 fp_free(struct proc
* p
, int fd
, struct fileproc
* fp
)
2397 fg_free(fp
->f_fglob
);
2398 FREE_ZONE(fp
, sizeof *fp
, M_FILEPROC
);
2403 * Apply an advisory lock on a file descriptor.
2405 * Just attempt to get a record lock of the requested type on
2406 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
2409 flock(struct proc
*p
, register struct flock_args
*uap
, __unused register_t
*retval
)
2413 struct fileproc
*fp
;
2416 struct vfs_context context
;
2419 AUDIT_ARG(fd
, uap
->fd
);
2420 if ( (error
= fp_getfvp(p
, fd
, &fp
, &vp
)) ) {
2423 if ( (error
= vnode_getwithref(vp
)) ) {
2426 AUDIT_ARG(vnpath
, vp
, ARG_VNODE1
);
2428 context
.vc_proc
= p
;
2429 context
.vc_ucred
= fp
->f_cred
;
2431 lf
.l_whence
= SEEK_SET
;
2434 if (how
& LOCK_UN
) {
2435 lf
.l_type
= F_UNLCK
;
2436 fp
->f_flag
&= ~FHASLOCK
;
2437 error
= VNOP_ADVLOCK(vp
, (caddr_t
)fp
->f_fglob
, F_UNLCK
, &lf
, F_FLOCK
, &context
);
2441 lf
.l_type
= F_WRLCK
;
2442 else if (how
& LOCK_SH
)
2443 lf
.l_type
= F_RDLCK
;
2448 fp
->f_flag
|= FHASLOCK
;
2449 if (how
& LOCK_NB
) {
2450 error
= VNOP_ADVLOCK(vp
, (caddr_t
)fp
->f_fglob
, F_SETLK
, &lf
, F_FLOCK
, &context
);
2453 error
= VNOP_ADVLOCK(vp
, (caddr_t
)fp
->f_fglob
, F_SETLK
, &lf
, F_FLOCK
|F_WAIT
, &context
);
2455 (void)vnode_put(vp
);
2457 fp_drop(p
, fd
, fp
, 0);
2463 * File Descriptor pseudo-device driver (/dev/fd/).
2465 * Opening minor device N dup()s the file (if any) connected to file
2466 * descriptor N belonging to the calling process. Note that this driver
2467 * consists of only the ``open()'' routine, because all subsequent
2468 * references to this file will be direct to the other driver.
2471 fdopen(dev_t dev
, __unused
int mode
, __unused
int type
, struct proc
*p
)
2475 * XXX Kludge: set curproc->p_dupfd to contain the value of the
2476 * the file descriptor being sought for duplication. The error
2477 * return ensures that the vnode for this device will be released
2478 * by vn_open. Open will detect this special error and take the
2479 * actions in dupfdopen below. Other callers of vn_open or vnop_open
2480 * will simply report the error.
2482 p
->p_dupfd
= minor(dev
);
2487 * Duplicate the specified descriptor to a free descriptor.
2490 dupfdopen(fdp
, indx
, dfd
, mode
, error
)
2491 register struct filedesc
*fdp
;
2492 register int indx
, dfd
;
2496 struct fileproc
*wfp
;
2497 struct fileproc
*fp
;
2498 struct proc
* p
= current_proc();
2501 * If the to-be-dup'd fd number is greater than the allowed number
2502 * of file descriptors, or the fd to be dup'd has already been
2503 * closed, reject. Note, check for new == old is necessary as
2504 * falloc could allocate an already closed to-be-dup'd descriptor
2505 * as the new descriptor.
2509 fp
= fdp
->fd_ofiles
[indx
];
2510 if (dfd
< 0 || dfd
>= fdp
->fd_nfiles
||
2511 (wfp
= fdp
->fd_ofiles
[dfd
]) == NULL
|| wfp
== fp
||
2512 (fdp
->fd_ofileflags
[dfd
] & UF_RESERVED
)) {
2518 * There are two cases of interest here.
2520 * For ENODEV simply dup (dfd) to file descriptor
2521 * (indx) and return.
2523 * For ENXIO steal away the file structure from (dfd) and
2524 * store it in (indx). (dfd) is effectively closed by
2527 * Any other error code is just returned.
2532 * Check that the mode the file is being opened for is a
2533 * subset of the mode of the existing descriptor.
2535 if (((mode
& (FREAD
|FWRITE
)) | wfp
->f_flag
) != wfp
->f_flag
) {
2539 if (indx
> fdp
->fd_lastfile
)
2540 fdp
->fd_lastfile
= indx
;
2544 fg_free(fp
->f_fglob
);
2545 fp
->f_fglob
= wfp
->f_fglob
;
2547 fdp
->fd_ofileflags
[indx
] = fdp
->fd_ofileflags
[dfd
];
2560 fg_ref(struct fileproc
* fp
)
2562 struct fileglob
*fg
;
2566 lck_mtx_lock(&fg
->fg_lock
);
2568 lck_mtx_unlock(&fg
->fg_lock
);
2572 fg_drop(struct fileproc
* fp
)
2574 struct fileglob
*fg
;
2577 lck_mtx_lock(&fg
->fg_lock
);
2579 lck_mtx_unlock(&fg
->fg_lock
);
2584 fg_insertuipc(struct fileglob
* fg
)
2588 lck_mtx_lock(&fg
->fg_lock
);
2590 while (fg
->fg_lflags
& FG_RMMSGQ
) {
2591 fg
->fg_lflags
|= FG_WRMMSGQ
;
2592 msleep(&fg
->fg_lflags
, &fg
->fg_lock
, 0, "fg_insertuipc", 0);
2597 if (fg
->fg_msgcount
== 1) {
2598 fg
->fg_lflags
|= FG_INSMSGQ
;
2601 lck_mtx_unlock(&fg
->fg_lock
);
2604 lck_mtx_lock(uipc_lock
);
2606 LIST_INSERT_HEAD(&fmsghead
, fg
, f_msglist
);
2607 lck_mtx_unlock(uipc_lock
);
2608 lck_mtx_lock(&fg
->fg_lock
);
2609 fg
->fg_lflags
&= ~FG_INSMSGQ
;
2610 if (fg
->fg_lflags
& FG_WINSMSGQ
) {
2611 fg
->fg_lflags
&= ~FG_WINSMSGQ
;
2612 wakeup(&fg
->fg_lflags
);
2614 lck_mtx_unlock(&fg
->fg_lock
);
2620 fg_removeuipc(struct fileglob
* fg
)
2624 lck_mtx_lock(&fg
->fg_lock
);
2625 while (fg
->fg_lflags
& FG_INSMSGQ
) {
2626 fg
->fg_lflags
|= FG_WINSMSGQ
;
2627 msleep(&fg
->fg_lflags
, &fg
->fg_lock
, 0, "fg_removeuipc", 0);
2630 if (fg
->fg_msgcount
== 0) {
2631 fg
->fg_lflags
|= FG_RMMSGQ
;
2634 lck_mtx_unlock(&fg
->fg_lock
);
2637 lck_mtx_lock(uipc_lock
);
2639 LIST_REMOVE(fg
, f_msglist
);
2640 lck_mtx_unlock(uipc_lock
);
2641 lck_mtx_lock(&fg
->fg_lock
);
2642 fg
->fg_lflags
&= ~FG_RMMSGQ
;
2643 if (fg
->fg_lflags
& FG_WRMMSGQ
) {
2644 fg
->fg_lflags
&= ~FG_WRMMSGQ
;
2645 wakeup(&fg
->fg_lflags
);
2647 lck_mtx_unlock(&fg
->fg_lock
);
2653 fo_read(struct fileproc
*fp
, struct uio
*uio
, kauth_cred_t cred
, int flags
, struct proc
*p
)
2655 return ((*fp
->f_ops
->fo_read
)(fp
, uio
, cred
, flags
, p
));
2659 fo_write(struct fileproc
*fp
, struct uio
*uio
, kauth_cred_t cred
, int flags
, struct proc
*p
)
2661 return((*fp
->f_ops
->fo_write
)(fp
, uio
, cred
, flags
, p
));
2665 fo_ioctl(struct fileproc
*fp
, u_long com
, caddr_t data
, struct proc
*p
)
2670 error
= (*fp
->f_ops
->fo_ioctl
)(fp
, com
, data
, p
);
2676 fo_select(struct fileproc
*fp
, int which
, void *wql
, struct proc
*p
)
2678 return((*fp
->f_ops
->fo_select
)(fp
, which
, wql
, p
));
2682 fo_close(struct fileglob
*fg
, struct proc
*p
)
2684 return((*fg
->fg_ops
->fo_close
)(fg
, p
));
2688 fo_kqfilter(struct fileproc
*fp
, struct knote
*kn
, struct proc
*p
)
2690 return ((*fp
->f_ops
->fo_kqfilter
)(fp
, kn
, p
));