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.h>
70 #include <sys/socket.h>
71 #include <sys/socketvar.h>
73 #include <sys/ioctl.h>
74 #include <sys/fcntl.h>
75 #include <sys/malloc.h>
76 #include <sys/syslog.h>
77 #include <sys/unistd.h>
78 #include <sys/resourcevar.h>
79 #include <sys/aio_kern.h>
81 #include <bsm/audit_kernel.h>
83 #include <sys/mount.h>
86 * Descriptor management.
88 struct filelist filehead
; /* head of list of open files */
89 int nfiles
; /* actual number of open files */
91 static int frele_internal(struct file
*);
94 * System calls on descriptors.
98 getdtablesize(p
, uap
, retval
)
103 *retval
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
109 ogetdtablesize(p
, uap
, retval
)
114 *retval
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, NOFILE
);
119 void _fdrelse(fdp
, fd
)
120 register struct filedesc
*fdp
;
123 if (fd
< fdp
->fd_freefile
)
124 fdp
->fd_freefile
= fd
;
126 if (fd
> fdp
->fd_lastfile
)
127 panic("fdrelse: fd_lastfile inconsistent");
129 fdp
->fd_ofiles
[fd
] = NULL
;
130 fdp
->fd_ofileflags
[fd
] = 0;
131 while ((fd
= fdp
->fd_lastfile
) > 0 &&
132 fdp
->fd_ofiles
[fd
] == NULL
&&
133 !(fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
138 * Duplicate a file descriptor.
147 struct dup_args
*uap
;
150 register struct filedesc
*fdp
= p
->p_fd
;
151 register int old
= uap
->fd
;
154 if ((u_int
)old
>= fdp
->fd_nfiles
||
155 fdp
->fd_ofiles
[old
] == NULL
||
156 (fdp
->fd_ofileflags
[old
] & UF_RESERVED
))
158 if (error
= fdalloc(p
, 0, &new))
160 return (finishdup(fdp
, old
, new, retval
));
164 * Duplicate a file descriptor to a particular value.
174 struct dup2_args
*uap
;
177 register struct filedesc
*fdp
= p
->p_fd
;
178 register int old
= uap
->from
, new = uap
->to
;
181 if ((u_int
)old
>= fdp
->fd_nfiles
||
182 fdp
->fd_ofiles
[old
] == NULL
||
183 (fdp
->fd_ofileflags
[old
] & UF_RESERVED
) ||
184 (u_int
)new >= p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
||
185 (u_int
)new >= maxfiles
)
191 if ((u_int
)new >= fdp
->fd_nfiles
) {
192 if (error
= fdalloc(p
, new, &i
))
202 if ((flags
= fdp
->fd_ofileflags
[new]) & UF_RESERVED
)
204 fdp
->fd_ofileflags
[new] = (flags
& ~UF_MAPPED
) | UF_RESERVED
;
206 * dup2() must succeed even if the close has an error.
208 if (*(fpp
= &fdp
->fd_ofiles
[new])) {
209 struct file
*fp
= *fpp
;
212 (void) closef(fp
, p
);
215 return (finishdup(fdp
, old
, new, retval
));
219 * The file control system call.
228 fcntl(p
, uap
, retval
)
230 register struct fcntl_args
*uap
;
234 register struct filedesc
*fdp
= p
->p_fd
;
235 register struct file
*fp
;
237 struct vnode
*vp
, *devvp
;
238 int i
, tmp
, error
, error2
, flg
= F_POSIX
;
240 fstore_t alloc_struct
; /* structure for allocate command */
241 u_int32_t alloc_flags
= 0;
242 off_t offset
; /* used for F_SETSIZE */
244 struct radvisory ra_struct
;
245 fbootstraptransfer_t fbt_struct
; /* for F_READBOOTSTRAP and F_WRITEBOOTSTRAP */
246 struct log2phys l2p_struct
; /* structure for allocate command */
248 int devBlockSize
= 0;
250 AUDIT_ARG(fd
, uap
->fd
);
251 AUDIT_ARG(cmd
, uap
->cmd
);
252 if ((u_int
)fd
>= fdp
->fd_nfiles
||
253 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
254 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
256 pop
= &fdp
->fd_ofileflags
[fd
];
261 newmin
= (long)uap
->arg
;
262 if ((u_int
)newmin
>= p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
||
263 (u_int
)newmin
>= maxfiles
)
265 if (error
= fdalloc(p
, newmin
, &i
))
267 return (finishdup(fdp
, fd
, i
, retval
));
270 *retval
= (*pop
& UF_EXCLOSE
)? 1 : 0;
274 *pop
= (*pop
&~ UF_EXCLOSE
) |
275 ((long)(uap
->arg
) & 1)? UF_EXCLOSE
: 0;
279 *retval
= OFLAGS(fp
->f_flag
);
283 fp
->f_flag
&= ~FCNTLFLAGS
;
284 fp
->f_flag
|= FFLAGS((long)uap
->arg
) & FCNTLFLAGS
;
285 tmp
= fp
->f_flag
& FNONBLOCK
;
286 error
= fo_ioctl(fp
, FIONBIO
, (caddr_t
)&tmp
, p
);
289 tmp
= fp
->f_flag
& FASYNC
;
290 error
= fo_ioctl(fp
, FIOASYNC
, (caddr_t
)&tmp
, p
);
293 fp
->f_flag
&= ~FNONBLOCK
;
295 (void)fo_ioctl(fp
, FIONBIO
, (caddr_t
)&tmp
, p
);
299 if (fp
->f_type
== DTYPE_SOCKET
) {
300 *retval
= ((struct socket
*)fp
->f_data
)->so_pgid
;
303 error
= fo_ioctl(fp
, (int)TIOCGPGRP
, (caddr_t
)retval
, p
);
308 if (fp
->f_type
== DTYPE_SOCKET
) {
309 ((struct socket
*)fp
->f_data
)->so_pgid
=
313 if ((long)uap
->arg
<= 0) {
314 uap
->arg
= (int)(-(long)(uap
->arg
));
316 struct proc
*p1
= pfind((long)uap
->arg
);
319 uap
->arg
= (int)p1
->p_pgrp
->pg_id
;
321 return (fo_ioctl(fp
, (int)TIOCSPGRP
, (caddr_t
)&uap
->arg
, p
));
325 /* Fall into F_SETLK */
328 if (fp
->f_type
!= DTYPE_VNODE
)
330 vp
= (struct vnode
*)fp
->f_data
;
332 /* Copy in the lock structure */
333 error
= copyin((caddr_t
)uap
->arg
, (caddr_t
)&fl
, sizeof (fl
));
336 if (fl
.l_whence
== SEEK_CUR
)
337 fl
.l_start
+= fp
->f_offset
;
341 if ((fp
->f_flag
& FREAD
) != 0) {
342 p
->p_flag
|= P_ADVLOCK
;
343 error
= VOP_ADVLOCK(vp
, (caddr_t
)p
, F_SETLK
, &fl
, flg
);
349 if ((fp
->f_flag
& FWRITE
) != 0) {
350 p
->p_flag
|= P_ADVLOCK
;
351 error
= VOP_ADVLOCK(vp
, (caddr_t
)p
, F_SETLK
, &fl
, flg
);
357 error
= VOP_ADVLOCK(vp
, (caddr_t
)p
, F_UNLCK
, &fl
, F_POSIX
);
367 if (fp
->f_type
!= DTYPE_VNODE
)
369 vp
= (struct vnode
*)fp
->f_data
;
371 /* Copy in the lock structure */
372 error
= copyin((caddr_t
)uap
->arg
, (caddr_t
)&fl
, sizeof (fl
));
375 if (fl
.l_whence
== SEEK_CUR
)
376 fl
.l_start
+= fp
->f_offset
;
377 error
= VOP_ADVLOCK(vp
, (caddr_t
)p
, F_GETLK
, &fl
, F_POSIX
);
380 error
= copyout((caddr_t
)&fl
, (caddr_t
)uap
->arg
, sizeof (fl
));
384 if (fp
->f_type
!= DTYPE_VNODE
)
386 vp
= (struct vnode
*)fp
->f_data
;
388 /* make sure that we have write permission */
389 if ((fp
->f_flag
& FWRITE
) == 0) {
394 error
= copyin((caddr_t
)uap
->arg
, (caddr_t
)&alloc_struct
,
395 sizeof (alloc_struct
));
399 /* now set the space allocated to 0 */
400 alloc_struct
.fst_bytesalloc
= 0;
403 * Do some simple parameter checking
406 /* set up the flags */
408 alloc_flags
|= PREALLOCATE
;
410 if (alloc_struct
.fst_flags
& F_ALLOCATECONTIG
)
411 alloc_flags
|= ALLOCATECONTIG
;
413 if (alloc_struct
.fst_flags
& F_ALLOCATEALL
)
414 alloc_flags
|= ALLOCATEALL
;
417 * Do any position mode specific stuff. The only
418 * position mode supported now is PEOFPOSMODE
421 switch (alloc_struct
.fst_posmode
) {
424 if (alloc_struct
.fst_offset
== 0)
425 alloc_flags
|= ALLOCATEFROMPEOF
;
431 if (alloc_struct
.fst_offset
> 0)
432 alloc_flags
|= ALLOCATEFROMVOL
;
445 /* lock the vnode and call allocate to get the space */
446 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
449 error
= VOP_ALLOCATE(vp
,alloc_struct
.fst_length
,alloc_flags
,
450 &alloc_struct
.fst_bytesalloc
, alloc_struct
.fst_offset
,
452 VOP_UNLOCK(vp
, 0, p
);
454 if (error2
= copyout((caddr_t
)&alloc_struct
,
456 sizeof (alloc_struct
))) {
463 if (fp
->f_type
!= DTYPE_VNODE
)
465 vp
= (struct vnode
*)fp
->f_data
;
467 error
= copyin((caddr_t
)uap
->arg
, (caddr_t
)&offset
,
473 * Make sure that we are root. Growing a file
474 * without zero filling the data is a security hole
475 * root would have access anyway so we'll allow it
483 /* lock the vnode and call allocate to get the space */
484 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
487 error
= VOP_TRUNCATE(vp
,offset
,IO_NOZEROFILL
,fp
->f_cred
,p
);
492 if (fp
->f_type
!= DTYPE_VNODE
)
494 vp
= (struct vnode
*)fp
->f_data
;
496 simple_lock(&vp
->v_interlock
);
498 vp
->v_flag
&= ~VRAOFF
;
500 vp
->v_flag
|= VRAOFF
;
501 simple_unlock(&vp
->v_interlock
);
506 if (fp
->f_type
!= DTYPE_VNODE
)
508 vp
= (struct vnode
*)fp
->f_data
;
510 simple_lock(&vp
->v_interlock
);
512 vp
->v_flag
|= VNOCACHE_DATA
;
514 vp
->v_flag
&= ~VNOCACHE_DATA
;
515 simple_unlock(&vp
->v_interlock
);
520 if (fp
->f_type
!= DTYPE_VNODE
)
522 vp
= (struct vnode
*)fp
->f_data
;
524 if (error
= copyin((caddr_t
)uap
->arg
,
525 (caddr_t
)&ra_struct
, sizeof (ra_struct
)))
527 error
= VOP_IOCTL(vp
, 1, (caddr_t
)&ra_struct
, 0, fp
->f_cred
, p
);
532 * used by regression test to determine if
533 * all the dirty pages (via write) have been cleaned
534 * after a call to 'fsysnc'.
536 if (fp
->f_type
!= DTYPE_VNODE
)
538 vp
= (struct vnode
*)fp
->f_data
;
540 error
= VOP_IOCTL(vp
, 5, 0, 0, fp
->f_cred
, p
);
543 case F_READBOOTSTRAP
:
544 case F_WRITEBOOTSTRAP
:
545 if (fp
->f_type
!= DTYPE_VNODE
)
547 vp
= (struct vnode
*)fp
->f_data
;
549 error
= copyin((caddr_t
)uap
->arg
, (caddr_t
)&fbt_struct
,
550 sizeof (fbt_struct
));
554 if (uap
->cmd
== F_WRITEBOOTSTRAP
) {
556 * Make sure that we are root. Updating the
557 * bootstrap on a disk could be a security hole
565 if (vp
->v_tag
!= VT_HFS
) /* XXX */
568 /* lock the vnode and call VOP_IOCTL to handle the I/O */
569 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
572 error
= VOP_IOCTL(vp
, (uap
->cmd
== F_WRITEBOOTSTRAP
) ? 3 : 2,
573 (caddr_t
)&fbt_struct
, 0, fp
->f_cred
, p
);
579 if (fp
->f_type
!= DTYPE_VNODE
)
581 vp
= (struct vnode
*)fp
->f_data
;
583 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
586 error
= VOP_OFFTOBLK(vp
, fp
->f_offset
, &lbn
);
589 error
= VOP_BLKTOOFF(vp
, lbn
, &offset
);
592 error
= VOP_BMAP(vp
, lbn
, &devvp
, &bn
, 0);
593 VOP_DEVBLOCKSIZE(devvp
, &devBlockSize
);
594 VOP_UNLOCK(vp
, 0, p
);
596 l2p_struct
.l2p_flags
= 0; /* for now */
597 l2p_struct
.l2p_contigbytes
= 0; /* for now */
598 l2p_struct
.l2p_devoffset
= bn
* devBlockSize
;
599 l2p_struct
.l2p_devoffset
+= fp
->f_offset
- offset
;
600 error
= copyout((caddr_t
)&l2p_struct
,
602 sizeof (l2p_struct
));
609 extern int vn_getpath(struct vnode
*vp
, char *pathbuf
, int *len
);
611 if (fp
->f_type
!= DTYPE_VNODE
)
613 vp
= (struct vnode
*)fp
->f_data
;
616 MALLOC(pathbuf
, char *, len
, M_TEMP
, M_WAITOK
);
618 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
620 FREE(pathbuf
, M_TEMP
);
623 error
= vn_getpath(vp
, pathbuf
, &len
);
625 error
= copyout((caddr_t
)pathbuf
, (caddr_t
)uap
->arg
, len
);
626 VOP_UNLOCK(vp
, 0, p
);
627 FREE(pathbuf
, M_TEMP
);
632 if (fp
->f_type
!= DTYPE_VNODE
)
634 vp
= (struct vnode
*)fp
->f_data
;
636 error
= vn_lock(vp
, LK_EXCLUSIVE
|LK_RETRY
, p
);
640 error
= VOP_IOCTL(vp
, 6, (caddr_t
)NULL
, 0, fp
->f_cred
, p
);
641 VOP_UNLOCK(vp
, 0, p
);
650 * Fall thru to here for all vnode operations.
651 * We audit the path after the call to avoid
652 * triggering file table state changes during
653 * the audit pathname allocation.
655 AUDIT_ARG(vnpath
, vp
, ARG_VNODE1
);
660 * Common code for dup, dup2, and fcntl(F_DUPFD).
663 finishdup(fdp
, old
, new, retval
)
664 register struct filedesc
*fdp
;
665 register int old
, new;
668 register struct file
*fp
;
670 if ((fp
= fdp
->fd_ofiles
[old
]) == NULL
||
671 (fdp
->fd_ofileflags
[old
] & UF_RESERVED
)) {
675 fdp
->fd_ofiles
[new] = fp
;
676 fdp
->fd_ofileflags
[new] = fdp
->fd_ofileflags
[old
] &~ UF_EXCLOSE
;
678 if (new > fdp
->fd_lastfile
)
679 fdp
->fd_lastfile
= new;
685 * Close a file descriptor.
692 close(p
, uap
, retval
)
694 struct close_args
*uap
;
698 register struct filedesc
*fdp
= p
->p_fd
;
699 register struct file
*fp
;
701 AUDIT_SYSCLOSE(p
, fd
);
702 if ((u_int
)fd
>= fdp
->fd_nfiles
||
703 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
704 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
707 /* Keep people from using the filedesc while we are closing it */
708 fdp
->fd_ofileflags
[fd
] |= UF_RESERVED
;
710 /* cancel all async IO requests that can be cancelled. */
713 if (fd
< fdp
->fd_knlistsize
)
714 knote_fdclose(p
, fd
);
717 return (closef(fp
, p
));
721 * Return status information about a file descriptor.
729 fstat(p
, uap
, retval
)
731 register struct fstat_args
*uap
;
735 register struct filedesc
*fdp
= p
->p_fd
;
736 register struct file
*fp
;
740 AUDIT_ARG(fd
, uap
->fd
);
741 if ((u_int
)fd
>= fdp
->fd_nfiles
||
742 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
743 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
745 switch (fp
->f_type
) {
748 error
= vn_stat((struct vnode
*)fp
->f_data
, &ub
, p
);
750 AUDIT_ARG(vnpath
, (struct vnode
*)fp
->f_data
, ARG_VNODE1
);
755 error
= soo_stat((struct socket
*)fp
->f_data
, &ub
);
759 error
= pshm_stat((void *)fp
->f_data
, &ub
);
763 error
= kqueue_stat(fp
, &ub
, p
);
771 error
= copyout((caddr_t
)&ub
, (caddr_t
)uap
->sb
,
778 * Return status information about a file descriptor.
785 ofstat(p
, uap
, retval
)
787 register struct ofstat_args
*uap
;
791 register struct filedesc
*fdp
= p
->p_fd
;
792 register struct file
*fp
;
797 if ((u_int
)fd
>= fdp
->fd_nfiles
||
798 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
799 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
801 switch (fp
->f_type
) {
804 error
= vn_stat((struct vnode
*)fp
->f_data
, &ub
, p
);
808 error
= soo_stat((struct socket
*)fp
->f_data
, &ub
);
817 error
= copyout((caddr_t
)&oub
, (caddr_t
)uap
->sb
,
821 #endif /* COMPAT_43 */
824 * Return pathconf information about a file descriptor.
826 struct fpathconf_args
{
831 fpathconf(p
, uap
, retval
)
833 register struct fpathconf_args
*uap
;
837 struct filedesc
*fdp
= p
->p_fd
;
841 AUDIT_ARG(fd
, uap
->fd
);
842 if ((u_int
)fd
>= fdp
->fd_nfiles
||
843 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
844 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
846 switch (fp
->f_type
) {
849 if (uap
->name
!= _PC_PIPE_BUF
)
855 vp
= (struct vnode
*)fp
->f_data
;
856 AUDIT_ARG(vnpath
, vp
, ARG_VNODE1
);
858 return (VOP_PATHCONF(vp
, uap
->name
, retval
));
867 * Allocate a file descriptor for the process.
872 fdalloc(p
, want
, result
)
877 register struct filedesc
*fdp
= p
->p_fd
;
879 int lim
, last
, nfiles
, oldnfiles
;
880 struct file
**newofiles
, **ofiles
;
881 char *newofileflags
, *ofileflags
;
884 * Search for a free descriptor starting at the higher
885 * of want or fd_freefile. If that fails, consider
886 * expanding the ofile array.
888 lim
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
890 last
= min(fdp
->fd_nfiles
, lim
);
891 if ((i
= want
) < fdp
->fd_freefile
)
892 i
= fdp
->fd_freefile
;
893 ofiles
= &fdp
->fd_ofiles
[i
];
894 ofileflags
= &fdp
->fd_ofileflags
[i
];
895 for (; i
< last
; i
++) {
896 if (*ofiles
== NULL
&& !(*ofileflags
& UF_RESERVED
)) {
897 *ofileflags
= UF_RESERVED
;
898 if (i
> fdp
->fd_lastfile
)
899 fdp
->fd_lastfile
= i
;
900 if (want
<= fdp
->fd_freefile
)
901 fdp
->fd_freefile
= i
;
905 ofiles
++; ofileflags
++;
909 * No space in current array. Expand?
911 if (fdp
->fd_nfiles
>= lim
)
913 if (fdp
->fd_nfiles
< NDEXTENT
)
916 nfiles
= 2 * fdp
->fd_nfiles
;
920 MALLOC_ZONE(newofiles
, struct file
**,
921 nfiles
* OFILESIZE
, M_OFILETABL
, M_WAITOK
);
922 if (fdp
->fd_nfiles
>= nfiles
) {
923 FREE_ZONE(newofiles
, nfiles
* OFILESIZE
, M_OFILETABL
);
926 newofileflags
= (char *) &newofiles
[nfiles
];
928 * Copy the existing ofile and ofileflags arrays
929 * and zero the new portion of each array.
931 oldnfiles
= fdp
->fd_nfiles
;
932 (void) memcpy(newofiles
, fdp
->fd_ofiles
,
933 oldnfiles
* sizeof *fdp
->fd_ofiles
);
934 (void) memset(&newofiles
[oldnfiles
], 0,
935 (nfiles
- oldnfiles
) * sizeof *fdp
->fd_ofiles
);
937 (void) memcpy(newofileflags
, fdp
->fd_ofileflags
,
938 oldnfiles
* sizeof *fdp
->fd_ofileflags
);
939 (void) memset(&newofileflags
[oldnfiles
], 0,
940 (nfiles
- oldnfiles
) *
941 sizeof *fdp
->fd_ofileflags
);
942 ofiles
= fdp
->fd_ofiles
;
943 fdp
->fd_ofiles
= newofiles
;
944 fdp
->fd_ofileflags
= newofileflags
;
945 fdp
->fd_nfiles
= nfiles
;
946 FREE_ZONE(ofiles
, oldnfiles
* OFILESIZE
, M_OFILETABL
);
952 * Check to see whether n user file descriptors
953 * are available to the process p.
960 register struct filedesc
*fdp
= p
->p_fd
;
961 register struct file
**fpp
;
962 register char *flags
;
965 lim
= min((int)p
->p_rlimit
[RLIMIT_NOFILE
].rlim_cur
, maxfiles
);
966 if ((i
= lim
- fdp
->fd_nfiles
) > 0 && (n
-= i
) <= 0)
968 fpp
= &fdp
->fd_ofiles
[fdp
->fd_freefile
];
969 flags
= &fdp
->fd_ofileflags
[fdp
->fd_freefile
];
970 for (i
= fdp
->fd_nfiles
- fdp
->fd_freefile
; --i
>= 0; fpp
++, flags
++)
971 if (*fpp
== NULL
&& !(*flags
& UF_RESERVED
) && --n
<= 0)
981 _fdrelse(p
->p_fd
, fd
);
985 fdgetf(p
, fd
, resultfp
)
986 register struct proc
*p
;
988 struct file
**resultfp
;
990 register struct filedesc
*fdp
= p
->p_fd
;
993 if ((u_int
)fd
>= fdp
->fd_nfiles
||
994 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
995 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
1004 * Create a new open file structure and allocate
1005 * a file decriptor for the process that refers to it.
1008 falloc(p
, resultfp
, resultfd
)
1009 register struct proc
*p
;
1010 struct file
**resultfp
;
1013 register struct file
*fp
, *fq
;
1016 if (error
= fdalloc(p
, 0, &i
))
1018 if (nfiles
>= maxfiles
) {
1023 * Allocate a new file descriptor.
1024 * If the process has file descriptor zero open, add to the list
1025 * of open files at that point, otherwise put it at the front of
1026 * the list of open files.
1029 MALLOC_ZONE(fp
, struct file
*, sizeof(struct file
), M_FILE
, M_WAITOK
);
1030 bzero(fp
, sizeof(struct file
));
1031 p
->p_fd
->fd_ofiles
[i
] = fp
;
1033 fp
->f_cred
= p
->p_ucred
;
1039 if (fq
= p
->p_fd
->fd_ofiles
[0]) {
1040 LIST_INSERT_AFTER(fq
, fp
, f_list
);
1042 LIST_INSERT_HEAD(&filehead
, fp
, f_list
);
1048 * Free a file structure.
1052 register struct file
*fp
;
1054 register struct file
*fq
;
1057 LIST_REMOVE(fp
, f_list
);
1059 if (cred
!= NOCRED
) {
1060 fp
->f_cred
= NOCRED
;
1065 memset(fp
, 0xff, sizeof *fp
);
1066 fp
->f_count
= (short)0xffff;
1068 FREE_ZONE(fp
, sizeof *fp
, M_FILE
);
1075 register struct filedesc
*fdp
= p
->p_fd
;
1076 register int i
= fdp
->fd_lastfile
;
1077 register struct file
**fpp
= &fdp
->fd_ofiles
[i
];
1078 register char *flags
= &fdp
->fd_ofileflags
[i
];
1081 if ((*flags
& (UF_RESERVED
|UF_EXCLOSE
)) == UF_EXCLOSE
) {
1082 register struct file
*fp
= *fpp
;
1084 if (i
< fdp
->fd_knlistsize
)
1085 knote_fdclose(p
, i
);
1087 *fpp
= NULL
; *flags
= 0;
1088 if (i
== fdp
->fd_lastfile
&& i
> 0)
1093 *flags
&= ~UF_MAPPED
;
1095 i
--; fpp
--; flags
--;
1100 * Copy a filedesc structure.
1106 register struct filedesc
*newfdp
, *fdp
= p
->p_fd
;
1109 MALLOC_ZONE(newfdp
, struct filedesc
*,
1110 sizeof *newfdp
, M_FILEDESC
, M_WAITOK
);
1111 (void) memcpy(newfdp
, fdp
, sizeof *newfdp
);
1112 VREF(newfdp
->fd_cdir
);
1113 if (newfdp
->fd_rdir
)
1114 VREF(newfdp
->fd_rdir
);
1115 newfdp
->fd_refcnt
= 1;
1118 * If the number of open files fits in the internal arrays
1119 * of the open file structure, use them, otherwise allocate
1120 * additional memory for the number of descriptors currently
1123 if (newfdp
->fd_lastfile
< NDFILE
)
1127 * Compute the smallest multiple of NDEXTENT needed
1128 * for the file descriptors currently in use,
1129 * allowing the table to shrink.
1131 i
= newfdp
->fd_nfiles
;
1132 while (i
> 2 * NDEXTENT
&& i
> newfdp
->fd_lastfile
* 2)
1135 MALLOC_ZONE(newfdp
->fd_ofiles
, struct file
**,
1136 i
* OFILESIZE
, M_OFILETABL
, M_WAITOK
);
1137 newfdp
->fd_ofileflags
= (char *) &newfdp
->fd_ofiles
[i
];
1138 newfdp
->fd_nfiles
= i
;
1139 if (fdp
->fd_nfiles
> 0) {
1140 register struct file
**fpp
;
1141 register char *flags
;
1143 (void) memcpy(newfdp
->fd_ofiles
, fdp
->fd_ofiles
,
1144 i
* sizeof *fdp
->fd_ofiles
);
1145 (void) memcpy(newfdp
->fd_ofileflags
, fdp
->fd_ofileflags
,
1146 i
* sizeof *fdp
->fd_ofileflags
);
1149 * kq descriptors cannot be copied.
1151 if (newfdp
->fd_knlistsize
!= -1) {
1152 fpp
= &newfdp
->fd_ofiles
[newfdp
->fd_lastfile
];
1153 for (i
= newfdp
->fd_lastfile
; i
>= 0; i
--, fpp
--) {
1154 if (*fpp
!= NULL
&& (*fpp
)->f_type
== DTYPE_KQUEUE
) {
1156 if (i
< newfdp
->fd_freefile
)
1157 newfdp
->fd_freefile
= i
;
1159 if (*fpp
== NULL
&& i
== newfdp
->fd_lastfile
&& i
> 0)
1160 newfdp
->fd_lastfile
--;
1162 newfdp
->fd_knlist
= NULL
;
1163 newfdp
->fd_knlistsize
= -1;
1164 newfdp
->fd_knhash
= NULL
;
1165 newfdp
->fd_knhashmask
= 0;
1168 fpp
= newfdp
->fd_ofiles
;
1169 flags
= newfdp
->fd_ofileflags
;
1170 for (i
= newfdp
->fd_lastfile
; i
-- >= 0; fpp
++, flags
++)
1171 if (*fpp
!= NULL
&& !(*flags
& UF_RESERVED
)) {
1178 (void) memset(newfdp
->fd_ofiles
, 0, i
* OFILESIZE
);
1184 * Release a filedesc structure.
1190 struct filedesc
*fdp
;
1195 /* Certain daemons might not have file descriptors */
1196 if ((fdp
= p
->p_fd
) == NULL
)
1199 if (--fdp
->fd_refcnt
> 0)
1202 /* Last reference: the structure can't change out from under us */
1203 if (fdp
->fd_nfiles
> 0) {
1204 for (i
= fdp
->fd_lastfile
; i
>= 0; i
--)
1205 #if 1 /* WORKAROUND */
1207 * Merlot: need to remove the bogus f_data check
1208 * from the following "if" statement. It's there
1209 * because of the network/kernel funnel race on a
1210 * close of a socket vs. fdfree on exit. See
1211 * Radar rdar://problem/3365650 for details, but
1212 * the sort version is the commment before the "if"
1213 * above is wrong under certain circumstances.
1215 * We have to do this twice, in case knote_fdclose()
1216 * results in a block.
1218 * This works because an fdfree() will set all fields
1219 * in the struct file to -1.
1221 if ((fp
= fdp
->fd_ofiles
[i
]) != NULL
&&
1222 fp
->f_data
!= (caddr_t
)-1) {
1223 if (i
< fdp
->fd_knlistsize
)
1224 knote_fdclose(p
, i
);
1225 if (fp
->f_data
!= (caddr_t
)-1)
1226 (void) closef(fp
, p
);
1228 #else /* !WORKAROUND */
1229 if ((fp
= fdp
->fd_ofiles
[i
]) != NULL
) {
1230 if (i
< fdp
->fd_knlistsize
)
1231 knote_fdclose(p
, i
);
1232 (void) closef(fp
, p
);
1234 #endif /* !WORKAROUND */
1235 FREE_ZONE(fdp
->fd_ofiles
,
1236 fdp
->fd_nfiles
* OFILESIZE
, M_OFILETABL
);
1240 fdp
->fd_cdir
= NULL
;
1245 fdp
->fd_rdir
= NULL
;
1250 FREE(fdp
->fd_knlist
, M_KQUEUE
);
1252 FREE(fdp
->fd_knhash
, M_KQUEUE
);
1254 FREE_ZONE(fdp
, sizeof *fdp
, M_FILEDESC
);
1258 void clean_up_fmod_watch(struct proc
*p
);
1259 clean_up_fmod_watch(p
);
1264 closef_finish(fp
, p
)
1265 register struct file
*fp
;
1266 register struct proc
*p
;
1272 if ((fp
->f_flag
& FHASLOCK
) && fp
->f_type
== DTYPE_VNODE
) {
1273 lf
.l_whence
= SEEK_SET
;
1276 lf
.l_type
= F_UNLCK
;
1277 vp
= (struct vnode
*)fp
->f_data
;
1278 (void) VOP_ADVLOCK(vp
, (caddr_t
)fp
, F_UNLCK
, &lf
, F_FLOCK
);
1281 error
= fo_close(fp
, p
);
1289 * Internal form of close.
1290 * Decrement reference count on file structure.
1291 * Note: p may be NULL when closing a file
1292 * that was being passed in a message.
1296 register struct file
*fp
;
1297 register struct proc
*p
;
1306 * POSIX record locking dictates that any close releases ALL
1307 * locks owned by this process. This is handled by setting
1308 * a flag in the unlock to free ONLY locks obeying POSIX
1309 * semantics, and not to free BSD-style file locks.
1310 * If the descriptor was in a message, POSIX-style locks
1311 * aren't passed with the descriptor.
1313 if (p
&& (p
->p_flag
& P_ADVLOCK
) && fp
->f_type
== DTYPE_VNODE
) {
1314 lf
.l_whence
= SEEK_SET
;
1317 lf
.l_type
= F_UNLCK
;
1318 vp
= (struct vnode
*)fp
->f_data
;
1319 (void) VOP_ADVLOCK(vp
, (caddr_t
)p
, F_UNLCK
, &lf
, F_POSIX
);
1321 if (frele_internal(fp
) > 0)
1323 return(closef_finish(fp
, p
));
1327 * Apply an advisory lock on a file descriptor.
1329 * Just attempt to get a record lock of the requested type on
1330 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1338 flock(p
, uap
, retval
)
1340 register struct flock_args
*uap
;
1345 register struct filedesc
*fdp
= p
->p_fd
;
1346 register struct file
*fp
;
1350 AUDIT_ARG(fd
, uap
->fd
);
1351 if ((u_int
)fd
>= fdp
->fd_nfiles
||
1352 (fp
= fdp
->fd_ofiles
[fd
]) == NULL
||
1353 (fdp
->fd_ofileflags
[fd
] & UF_RESERVED
))
1355 if (fp
->f_type
!= DTYPE_VNODE
)
1356 return (EOPNOTSUPP
);
1357 vp
= (struct vnode
*)fp
->f_data
;
1358 AUDIT_ARG(vnpath
, vp
, ARG_VNODE1
);
1359 lf
.l_whence
= SEEK_SET
;
1362 if (how
& LOCK_UN
) {
1363 lf
.l_type
= F_UNLCK
;
1364 fp
->f_flag
&= ~FHASLOCK
;
1365 return (VOP_ADVLOCK(vp
, (caddr_t
)fp
, F_UNLCK
, &lf
, F_FLOCK
));
1368 lf
.l_type
= F_WRLCK
;
1369 else if (how
& LOCK_SH
)
1370 lf
.l_type
= F_RDLCK
;
1373 fp
->f_flag
|= FHASLOCK
;
1375 return (VOP_ADVLOCK(vp
, (caddr_t
)fp
, F_SETLK
, &lf
, F_FLOCK
));
1376 return (VOP_ADVLOCK(vp
, (caddr_t
)fp
, F_SETLK
, &lf
, F_FLOCK
|F_WAIT
));
1380 * File Descriptor pseudo-device driver (/dev/fd/).
1382 * Opening minor device N dup()s the file (if any) connected to file
1383 * descriptor N belonging to the calling process. Note that this driver
1384 * consists of only the ``open()'' routine, because all subsequent
1385 * references to this file will be direct to the other driver.
1389 fdopen(dev
, mode
, type
, p
)
1396 * XXX Kludge: set curproc->p_dupfd to contain the value of the
1397 * the file descriptor being sought for duplication. The error
1398 * return ensures that the vnode for this device will be released
1399 * by vn_open. Open will detect this special error and take the
1400 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1401 * will simply report the error.
1403 p
->p_dupfd
= minor(dev
);
1408 * Duplicate the specified descriptor to a free descriptor.
1411 dupfdopen(fdp
, indx
, dfd
, mode
, error
)
1412 register struct filedesc
*fdp
;
1413 register int indx
, dfd
;
1417 register struct file
*wfp
;
1421 * If the to-be-dup'd fd number is greater than the allowed number
1422 * of file descriptors, or the fd to be dup'd has already been
1423 * closed, reject. Note, check for new == old is necessary as
1424 * falloc could allocate an already closed to-be-dup'd descriptor
1425 * as the new descriptor.
1427 fp
= fdp
->fd_ofiles
[indx
];
1428 if ((u_int
)dfd
>= fdp
->fd_nfiles
||
1429 (wfp
= fdp
->fd_ofiles
[dfd
]) == NULL
|| wfp
== fp
||
1430 (fdp
->fd_ofileflags
[dfd
] & UF_RESERVED
))
1434 * There are two cases of interest here.
1436 * For ENODEV simply dup (dfd) to file descriptor
1437 * (indx) and return.
1439 * For ENXIO steal away the file structure from (dfd) and
1440 * store it in (indx). (dfd) is effectively closed by
1443 * Any other error code is just returned.
1448 * Check that the mode the file is being opened for is a
1449 * subset of the mode of the existing descriptor.
1451 if (((mode
& (FREAD
|FWRITE
)) | wfp
->f_flag
) != wfp
->f_flag
)
1454 if (indx
> fdp
->fd_lastfile
)
1455 fdp
->fd_lastfile
= indx
;;
1456 fdp
->fd_ofiles
[indx
] = wfp
;
1457 fdp
->fd_ofileflags
[indx
] = fdp
->fd_ofileflags
[dfd
];
1462 * Steal away the file pointer from dfd, and stuff it into indx.
1464 if (indx
> fdp
->fd_lastfile
)
1465 fdp
->fd_lastfile
= indx
;;
1466 fdp
->fd_ofiles
[indx
] = fdp
->fd_ofiles
[dfd
];
1467 fdp
->fd_ofileflags
[indx
] = fdp
->fd_ofileflags
[dfd
];
1477 /* Reference manipulation routines for the file structure */
1480 fref(struct file
*fp
)
1482 if (fp
->f_count
== (short)0xffff)
1484 if (++fp
->f_count
<= 0)
1485 panic("fref: f_count");
1486 return ((int)fp
->f_count
);
1490 frele_internal(struct file
*fp
)
1492 if (fp
->f_count
== (short)0xffff)
1493 panic("frele: stale");
1494 if (--fp
->f_count
< 0)
1495 panic("frele: count < 0");
1496 return ((int)fp
->f_count
);
1501 frele(struct file
*fp
)
1505 extern int disable_funnel
;
1507 fnl
= thread_funnel_get();
1509 * If the funnels are merged then atleast a funnel should be held
1510 * else frele should come in with kernel funnel only
1512 if (!disable_funnel
&& (fnl
!= kernel_flock
)) {
1513 panic("frele: kernel funnel not held");
1515 } else if (fnl
== THR_FUNNEL_NULL
) {
1516 panic("frele: no funnel held");
1519 if ((count
= frele_internal(fp
)) == 0) {
1520 /* some one closed the fd while we were blocked */
1521 (void)closef_finish(fp
, current_proc());
1527 fcount(struct file
*fp
)
1529 if (fp
->f_count
== (short)0xffff)
1530 panic("fcount: stale");
1531 return ((int)fp
->f_count
);