]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_descrip.c
xnu-792.12.6.tar.gz
[apple/xnu.git] / bsd / kern / kern_descrip.c
1 /*
2 * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */
31 /*
32 * Copyright (c) 1982, 1986, 1989, 1991, 1993
33 * The Regents of the University of California. All rights reserved.
34 * (c) UNIX System Laboratories, Inc.
35 * All or some portions of this file are derived from material licensed
36 * to the University of California by American Telephone and Telegraph
37 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
38 * the permission of UNIX System Laboratories, Inc.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. All advertising materials mentioning features or use of this software
49 * must display the following acknowledgement:
50 * This product includes software developed by the University of
51 * California, Berkeley and its contributors.
52 * 4. Neither the name of the University nor the names of its contributors
53 * may be used to endorse or promote products derived from this software
54 * without specific prior written permission.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 *
68 * @(#)kern_descrip.c 8.8 (Berkeley) 2/14/95
69 */
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/filedesc.h>
74 #include <sys/kernel.h>
75 #include <sys/vnode_internal.h>
76 #include <sys/proc_internal.h>
77 #include <sys/kauth.h>
78 #include <sys/file_internal.h>
79 #include <sys/socket.h>
80 #include <sys/socketvar.h>
81 #include <sys/stat.h>
82 #include <sys/ioctl.h>
83 #include <sys/fcntl.h>
84 #include <sys/malloc.h>
85 #include <sys/mman.h>
86 #include <sys/syslog.h>
87 #include <sys/unistd.h>
88 #include <sys/resourcevar.h>
89 #include <sys/aio_kern.h>
90 #include <sys/ev.h>
91 #include <kern/lock.h>
92
93 #include <bsm/audit_kernel.h>
94
95 #include <sys/mount_internal.h>
96 #include <sys/kdebug.h>
97 #include <sys/sysproto.h>
98 #include <sys/pipe.h>
99 #include <kern/kern_types.h>
100 #include <kern/kalloc.h>
101 #include <libkern/OSAtomic.h>
102
103 struct psemnode;
104 struct pshmnode;
105
106 int fdopen(dev_t dev, int mode, int type, struct proc *p);
107 int ogetdtablesize(struct proc *p, void *uap, register_t *retval);
108 int finishdup(struct proc * p, struct filedesc *fdp, int old, int new, register_t *retval);
109
110 int closef(struct fileglob *fg, struct proc *p);
111 int falloc_locked(struct proc *p, struct fileproc **resultfp, int *resultfd, int locked);
112 void fddrop(struct proc *p, int fd);
113 int fdgetf_noref(struct proc *p, int fd, struct fileproc **resultfp);
114 void fg_drop(struct fileproc * fp);
115 void fg_free(struct fileglob *fg);
116 void fg_ref(struct fileproc * fp);
117 int fp_getfpshm(struct proc *p, int fd, struct fileproc **resultfp, struct pshmnode **resultpshm);
118
119 static int closef_finish(struct fileproc *fp, struct fileglob *fg, struct proc *p);
120
121 extern void file_lock_init(void);
122 extern int is_suser(void);
123 extern int kqueue_stat(struct fileproc *fp, struct stat *st, struct proc *p);
124 extern int soo_stat(struct socket *so, struct stat *ub);
125 extern int vn_path_package_check(vnode_t vp, char *path, int pathlen, int *component);
126
127 extern kauth_scope_t kauth_scope_fileop;
128
129 #define f_flag f_fglob->fg_flag
130 #define f_type f_fglob->fg_type
131 #define f_msgcount f_fglob->fg_msgcount
132 #define f_cred f_fglob->fg_cred
133 #define f_ops f_fglob->fg_ops
134 #define f_offset f_fglob->fg_offset
135 #define f_data f_fglob->fg_data
136 /*
137 * Descriptor management.
138 */
139 struct filelist filehead; /* head of list of open files */
140 struct fmsglist fmsghead; /* head of list of open files */
141 struct fmsglist fmsg_ithead; /* head of list of open files */
142 int nfiles; /* actual number of open files */
143
144
145 lck_grp_attr_t * file_lck_grp_attr;
146 lck_grp_t * file_lck_grp;
147 lck_attr_t * file_lck_attr;
148
149 lck_mtx_t * uipc_lock;
150 lck_mtx_t * file_iterate_lcok;
151 lck_mtx_t * file_flist_lock;
152
153
154 void
155 file_lock_init(void)
156 {
157
158 /* allocate file lock group attribute and group */
159 file_lck_grp_attr= lck_grp_attr_alloc_init();
160 lck_grp_attr_setstat(file_lck_grp_attr);
161
162 file_lck_grp = lck_grp_alloc_init("file", file_lck_grp_attr);
163
164 /* Allocate file lock attribute */
165 file_lck_attr = lck_attr_alloc_init();
166 //lck_attr_setdebug(file_lck_attr);
167
168 uipc_lock = lck_mtx_alloc_init(file_lck_grp, file_lck_attr);
169 file_iterate_lcok = lck_mtx_alloc_init(file_lck_grp, file_lck_attr);
170 file_flist_lock = lck_mtx_alloc_init(file_lck_grp, file_lck_attr);
171
172
173
174 }
175
176
177 void
178 proc_fdlock(struct proc *p)
179 {
180 lck_mtx_lock(&p->p_fdmlock);
181 }
182
183 void
184 proc_fdunlock(struct proc *p)
185 {
186 lck_mtx_unlock(&p->p_fdmlock);
187 }
188
189 /*
190 * System calls on descriptors.
191 */
192
193 int
194 getdtablesize(struct proc *p, __unused struct getdtablesize_args *uap, register_t *retval)
195 {
196 proc_fdlock(p);
197 *retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
198 proc_fdunlock(p);
199
200 return (0);
201 }
202
203 int
204 ogetdtablesize(struct proc *p, __unused void *uap, register_t *retval)
205 {
206 proc_fdlock(p);
207 *retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, NOFILE);
208 proc_fdunlock(p);
209
210 return (0);
211 }
212
213 static __inline__ void
214 _fdrelse(struct filedesc *fdp, int fd)
215 {
216 if (fd < fdp->fd_freefile)
217 fdp->fd_freefile = fd;
218 #if DIAGNOSTIC
219 if (fd > fdp->fd_lastfile)
220 panic("fdrelse: fd_lastfile inconsistent");
221 #endif
222 fdp->fd_ofiles[fd] = NULL;
223 fdp->fd_ofileflags[fd] = 0;
224
225 while ((fd = fdp->fd_lastfile) > 0 &&
226 fdp->fd_ofiles[fd] == NULL &&
227 !(fdp->fd_ofileflags[fd] & UF_RESERVED))
228 fdp->fd_lastfile--;
229 }
230
231 /*
232 * Duplicate a file descriptor.
233 */
234 /* ARGSUSED */
235 int
236 dup(p, uap, retval)
237 struct proc *p;
238 struct dup_args *uap;
239 register_t *retval;
240 {
241 register struct filedesc *fdp = p->p_fd;
242 register int old = uap->fd;
243 int new, error;
244 struct fileproc *fp;
245
246 proc_fdlock(p);
247 if ( (error = fp_lookup(p, old, &fp, 1)) ) {
248 proc_fdunlock(p);
249 return(error);
250 }
251 if ( (error = fdalloc(p, 0, &new)) ) {
252 fp_drop(p, old, fp, 1);
253 proc_fdunlock(p);
254 return (error);
255 }
256 error = finishdup(p, fdp, old, new, retval);
257 fp_drop(p, old, fp, 1);
258 proc_fdunlock(p);
259
260 return (error);
261 }
262
263 /*
264 * Duplicate a file descriptor to a particular value.
265 */
266 /* ARGSUSED */
267 int
268 dup2(p, uap, retval)
269 struct proc *p;
270 struct dup2_args *uap;
271 register_t *retval;
272 {
273 register struct filedesc *fdp = p->p_fd;
274 register int old = uap->from, new = uap->to;
275 int i, error;
276 struct fileproc *fp;
277
278 proc_fdlock(p);
279
280 if ( (error = fp_lookup(p, old, &fp, 1)) ) {
281 proc_fdunlock(p);
282 return(error);
283 }
284 if (new < 0 ||
285 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
286 new >= maxfiles) {
287 fp_drop(p, old, fp, 1);
288 proc_fdunlock(p);
289 return (EBADF);
290 }
291 if (old == new) {
292 fp_drop(p, old, fp, 1);
293 *retval = new;
294 proc_fdunlock(p);
295 return (0);
296 }
297 if (new < 0 || new >= fdp->fd_nfiles) {
298 if ( (error = fdalloc(p, new, &i)) ) {
299 fp_drop(p, old, fp, 1);
300 proc_fdunlock(p);
301 return (error);
302 }
303 if (new != i) {
304 _fdrelse(fdp, i);
305 goto closeit;
306 }
307 } else {
308 struct fileproc **fpp;
309 char flags;
310 closeit:
311 flags = fdp->fd_ofileflags[new];
312 if ((flags & (UF_RESERVED | UF_CLOSING)) == UF_RESERVED) {
313 fp_drop(p, old, fp, 1);
314 proc_fdunlock(p);
315 return (EBADF);
316 }
317
318 /*
319 * dup2() must succeed even if the close has an error.
320 */
321 if (*(fpp = &fdp->fd_ofiles[new])) {
322 struct fileproc *nfp = *fpp;
323
324 close_internal(p, new, nfp, (CLOSEINT_LOCKED | CLOSEINT_WAITONCLOSE | CLOSEINT_NOFDRELSE | CLOSEINT_NOFDNOREF));
325 *fpp = NULL;
326 }
327 }
328 error = finishdup(p, fdp, old, new, retval);
329 fp_drop(p, old, fp, 1);
330 proc_fdunlock(p);
331
332 return(error);
333 }
334
335 /*
336 * The file control system call.
337 */
338 int
339 fcntl(p, uap, retval)
340 struct proc *p;
341 struct fcntl_args *uap;
342 register_t *retval;
343 {
344 int fd = uap->fd;
345 struct filedesc *fdp = p->p_fd;
346 struct fileproc *fp;
347 char *pop;
348 struct vnode *vp;
349 int i, tmp, error, error2, flg = F_POSIX;
350 struct flock fl;
351 struct vfs_context context;
352 off_t offset;
353 int newmin;
354 daddr64_t lbn, bn;
355 int devBlockSize = 0;
356 unsigned int fflag;
357 user_addr_t argp;
358
359 AUDIT_ARG(fd, uap->fd);
360 AUDIT_ARG(cmd, uap->cmd);
361
362 proc_fdlock(p);
363 if ( (error = fp_lookup(p, fd, &fp, 1)) ) {
364 proc_fdunlock(p);
365 return(error);
366 }
367 context.vc_proc = p;
368 context.vc_ucred = fp->f_cred;
369 if (proc_is64bit(p)) {
370 argp = uap->arg;
371 }
372 else {
373 /* since the arg parameter is defined as a long but may be either
374 * a long or a pointer we must take care to handle sign extension
375 * issues. Our sys call munger will sign extend a long when we are
376 * called from a 32-bit process. Since we can never have an address
377 * greater than 32-bits from a 32-bit process we lop off the top
378 * 32-bits to avoid getting the wrong address
379 */
380 argp = CAST_USER_ADDR_T(uap->arg);
381 }
382
383 pop = &fdp->fd_ofileflags[fd];
384
385 switch (uap->cmd) {
386
387 case F_DUPFD:
388 newmin = CAST_DOWN(int, uap->arg);
389 if ((u_int)newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
390 newmin >= maxfiles) {
391 error = EINVAL;
392 goto out;
393 }
394 if ( (error = fdalloc(p, newmin, &i)) )
395 goto out;
396 error = finishdup(p, fdp, fd, i, retval);
397 goto out;
398
399 case F_GETFD:
400 *retval = (*pop & UF_EXCLOSE)? 1 : 0;
401 error = 0;
402 goto out;
403
404 case F_SETFD:
405 *pop = (*pop &~ UF_EXCLOSE) |
406 (uap->arg & 1)? UF_EXCLOSE : 0;
407 error = 0;
408 goto out;
409
410 case F_GETFL:
411 *retval = OFLAGS(fp->f_flag);
412 error = 0;
413 goto out;
414
415 case F_SETFL:
416 fp->f_flag &= ~FCNTLFLAGS;
417 tmp = CAST_DOWN(int, uap->arg);
418 fp->f_flag |= FFLAGS(tmp) & FCNTLFLAGS;
419 tmp = fp->f_flag & FNONBLOCK;
420 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
421 if (error)
422 goto out;
423 tmp = fp->f_flag & FASYNC;
424 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, p);
425 if (!error)
426 goto out;
427 fp->f_flag &= ~FNONBLOCK;
428 tmp = 0;
429 (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p);
430 goto out;
431
432 case F_GETOWN:
433 if (fp->f_type == DTYPE_SOCKET) {
434 *retval = ((struct socket *)fp->f_data)->so_pgid;
435 error = 0;
436 goto out;
437 }
438 error = fo_ioctl(fp, (int)TIOCGPGRP, (caddr_t)retval, p);
439 *retval = -*retval;
440 goto out;
441
442 case F_SETOWN:
443 tmp = CAST_DOWN(pid_t, uap->arg);
444 if (fp->f_type == DTYPE_SOCKET) {
445 ((struct socket *)fp->f_data)->so_pgid = tmp;
446 error =0;
447 goto out;
448 }
449 if (fp->f_type == DTYPE_PIPE) {
450 error = fo_ioctl(fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
451 goto out;
452 }
453
454 if (tmp <= 0) {
455 tmp = -tmp;
456 } else {
457 struct proc *p1 = pfind(tmp);
458 if (p1 == 0) {
459 error = ESRCH;
460 goto out;
461 }
462 tmp = (int)p1->p_pgrp->pg_id;
463 }
464 error = fo_ioctl(fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
465 goto out;
466
467 case F_SETLKW:
468 flg |= F_WAIT;
469 /* Fall into F_SETLK */
470
471 case F_SETLK:
472 if (fp->f_type != DTYPE_VNODE) {
473 error = EBADF;
474 goto out;
475 }
476 vp = (struct vnode *)fp->f_data;
477
478 fflag = fp->f_flag;
479 offset = fp->f_offset;
480 proc_fdunlock(p);
481
482 /* Copy in the lock structure */
483 error = copyin(argp, (caddr_t)&fl, sizeof (fl));
484 if (error) {
485 goto outdrop;
486 }
487 if ( (error = vnode_getwithref(vp)) ) {
488 goto outdrop;
489 }
490 if (fl.l_whence == SEEK_CUR)
491 fl.l_start += offset;
492
493 switch (fl.l_type) {
494
495 case F_RDLCK:
496 if ((fflag & FREAD) == 0) {
497 (void)vnode_put(vp);
498 error = EBADF;
499 goto outdrop;
500 }
501 OSBitOrAtomic(P_LADVLOCK, &p->p_ladvflag);
502 error = VNOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg, &context);
503 (void)vnode_put(vp);
504 goto outdrop;
505
506 case F_WRLCK:
507 if ((fflag & FWRITE) == 0) {
508 (void)vnode_put(vp);
509 error = EBADF;
510 goto outdrop;
511 }
512 OSBitOrAtomic(P_LADVLOCK, &p->p_ladvflag);
513 error = VNOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg, &context);
514 (void)vnode_put(vp);
515 goto outdrop;
516
517 case F_UNLCK:
518 error = VNOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &fl,
519 F_POSIX, &context);
520 (void)vnode_put(vp);
521 goto outdrop;
522
523 default:
524 (void)vnode_put(vp);
525 error = EINVAL;
526 goto outdrop;
527 }
528
529 case F_GETLK:
530 if (fp->f_type != DTYPE_VNODE) {
531 error = EBADF;
532 goto out;
533 }
534 vp = (struct vnode *)fp->f_data;
535
536 offset = fp->f_offset;
537 proc_fdunlock(p);
538
539 /* Copy in the lock structure */
540 error = copyin(argp, (caddr_t)&fl, sizeof (fl));
541 if (error)
542 goto outdrop;
543
544 if ( (error = vnode_getwithref(vp)) == 0 ) {
545 if (fl.l_whence == SEEK_CUR)
546 fl.l_start += offset;
547
548 error = VNOP_ADVLOCK(vp, (caddr_t)p, F_GETLK, &fl, F_POSIX, &context);
549
550 (void)vnode_put(vp);
551
552 if (error == 0)
553 error = copyout((caddr_t)&fl, argp, sizeof (fl));
554 }
555 goto outdrop;
556
557 case F_PREALLOCATE: {
558 fstore_t alloc_struct; /* structure for allocate command */
559 u_int32_t alloc_flags = 0;
560
561 if (fp->f_type != DTYPE_VNODE) {
562 error = EBADF;
563 goto out;
564 }
565
566 vp = (struct vnode *)fp->f_data;
567 proc_fdunlock(p);
568
569 /* make sure that we have write permission */
570 if ((fp->f_flag & FWRITE) == 0) {
571 error = EBADF;
572 goto outdrop;
573 }
574
575 error = copyin(argp, (caddr_t)&alloc_struct, sizeof (alloc_struct));
576 if (error)
577 goto outdrop;
578
579 /* now set the space allocated to 0 */
580 alloc_struct.fst_bytesalloc = 0;
581
582 /*
583 * Do some simple parameter checking
584 */
585
586 /* set up the flags */
587
588 alloc_flags |= PREALLOCATE;
589
590 if (alloc_struct.fst_flags & F_ALLOCATECONTIG)
591 alloc_flags |= ALLOCATECONTIG;
592
593 if (alloc_struct.fst_flags & F_ALLOCATEALL)
594 alloc_flags |= ALLOCATEALL;
595
596 /*
597 * Do any position mode specific stuff. The only
598 * position mode supported now is PEOFPOSMODE
599 */
600
601 switch (alloc_struct.fst_posmode) {
602
603 case F_PEOFPOSMODE:
604 if (alloc_struct.fst_offset != 0) {
605 error = EINVAL;
606 goto outdrop;
607 }
608
609 alloc_flags |= ALLOCATEFROMPEOF;
610 break;
611
612 case F_VOLPOSMODE:
613 if (alloc_struct.fst_offset <= 0) {
614 error = EINVAL;
615 goto outdrop;
616 }
617
618 alloc_flags |= ALLOCATEFROMVOL;
619 break;
620
621 default: {
622 error = EINVAL;
623 goto outdrop;
624 }
625 }
626 if ( (error = vnode_getwithref(vp)) == 0 ) {
627 /*
628 * call allocate to get the space
629 */
630 error = VNOP_ALLOCATE(vp,alloc_struct.fst_length,alloc_flags,
631 &alloc_struct.fst_bytesalloc, alloc_struct.fst_offset,
632 &context);
633 (void)vnode_put(vp);
634
635 error2 = copyout((caddr_t)&alloc_struct, argp, sizeof (alloc_struct));
636
637 if (error == 0)
638 error = error2;
639 }
640 goto outdrop;
641
642 }
643 case F_SETSIZE:
644 if (fp->f_type != DTYPE_VNODE) {
645 error = EBADF;
646 goto out;
647 }
648 proc_fdunlock(p);
649
650 error = copyin(argp, (caddr_t)&offset, sizeof (off_t));
651 if (error)
652 goto outdrop;
653
654 /*
655 * Make sure that we are root. Growing a file
656 * without zero filling the data is a security hole
657 * root would have access anyway so we'll allow it
658 */
659
660 if (!is_suser()) {
661 error = EACCES;
662 goto outdrop;
663 }
664 vp = (struct vnode *)fp->f_data;
665
666 if ( (error = vnode_getwithref(vp)) == 0 ) {
667 /*
668 * set the file size
669 */
670 error = vnode_setsize(vp, offset, IO_NOZEROFILL, &context);
671
672 (void)vnode_put(vp);
673 }
674 goto outdrop;
675
676 case F_RDAHEAD:
677 if (fp->f_type != DTYPE_VNODE) {
678 error = EBADF;
679 goto out;
680 }
681 vp = (struct vnode *)fp->f_data;
682 proc_fdunlock(p);
683
684 if ( (error = vnode_getwithref(vp)) == 0) {
685 if (uap->arg)
686 vnode_clearnoreadahead(vp);
687 else
688 vnode_setnoreadahead(vp);
689
690 (void)vnode_put(vp);
691 }
692 goto outdrop;
693
694 case F_NOCACHE:
695 if (fp->f_type != DTYPE_VNODE) {
696 error = EBADF;
697 goto out;
698 }
699 vp = (struct vnode *)fp->f_data;
700 proc_fdunlock(p);
701
702 if ( (error = vnode_getwithref(vp)) == 0 ) {
703 if (uap->arg)
704 vnode_setnocache(vp);
705 else
706 vnode_clearnocache(vp);
707
708 (void)vnode_put(vp);
709 }
710 goto outdrop;
711
712 case F_GLOBAL_NOCACHE:
713 if (fp->f_type != DTYPE_VNODE) {
714 error = EBADF;
715 goto out;
716 }
717 vp = (struct vnode *)fp->f_data;
718 proc_fdunlock(p);
719
720 if ( (error = vnode_getwithref(vp)) == 0 ) {
721
722 *retval = vnode_isnocache(vp);
723
724 if (uap->arg)
725 vnode_setnocache(vp);
726 else
727 vnode_clearnocache(vp);
728
729 (void)vnode_put(vp);
730 }
731 goto outdrop;
732
733 case F_RDADVISE: {
734 struct radvisory ra_struct;
735
736 if (fp->f_type != DTYPE_VNODE) {
737 error = EBADF;
738 goto out;
739 }
740 vp = (struct vnode *)fp->f_data;
741 proc_fdunlock(p);
742
743 if ( (error = copyin(argp, (caddr_t)&ra_struct, sizeof (ra_struct))) )
744 goto outdrop;
745 if ( (error = vnode_getwithref(vp)) == 0 ) {
746 error = VNOP_IOCTL(vp, F_RDADVISE, (caddr_t)&ra_struct, 0, &context);
747
748 (void)vnode_put(vp);
749 }
750 goto outdrop;
751 }
752
753 case F_READBOOTSTRAP:
754 case F_WRITEBOOTSTRAP: {
755 fbootstraptransfer_t fbt_struct;
756 user_fbootstraptransfer_t user_fbt_struct;
757 int sizeof_struct;
758 caddr_t boot_structp;
759
760 if (fp->f_type != DTYPE_VNODE) {
761 error = EBADF;
762 goto out;
763 }
764 vp = (struct vnode *)fp->f_data;
765 proc_fdunlock(p);
766
767 if (IS_64BIT_PROCESS(p)) {
768 sizeof_struct = sizeof(user_fbt_struct);
769 boot_structp = (caddr_t) &user_fbt_struct;
770 }
771 else {
772 sizeof_struct = sizeof(fbt_struct);
773 boot_structp = (caddr_t) &fbt_struct;
774 }
775 error = copyin(argp, boot_structp, sizeof_struct);
776 if (error)
777 goto outdrop;
778 if ( (error = vnode_getwithref(vp)) ) {
779 goto outdrop;
780 }
781 if (uap->cmd == F_WRITEBOOTSTRAP) {
782 /*
783 * Make sure that we are root. Updating the
784 * bootstrap on a disk could be a security hole
785 */
786 if (!is_suser()) {
787 (void)vnode_put(vp);
788 error = EACCES;
789 goto outdrop;
790 }
791 }
792 if (strcmp(vnode_mount(vp)->mnt_vfsstat.f_fstypename, "hfs") != 0) {
793 error = EINVAL;
794 } else {
795 /*
796 * call vnop_ioctl to handle the I/O
797 */
798 error = VNOP_IOCTL(vp, uap->cmd, boot_structp, 0, &context);
799 }
800 (void)vnode_put(vp);
801 goto outdrop;
802 }
803 case F_LOG2PHYS: {
804 struct log2phys l2p_struct; /* structure for allocate command */
805
806 if (fp->f_type != DTYPE_VNODE) {
807 error = EBADF;
808 goto out;
809 }
810 vp = (struct vnode *)fp->f_data;
811 proc_fdunlock(p);
812 if ( (error = vnode_getwithref(vp)) ) {
813 goto outdrop;
814 }
815 error = VNOP_OFFTOBLK(vp, fp->f_offset, &lbn);
816 if (error) {
817 (void)vnode_put(vp);
818 goto outdrop;
819 }
820 error = VNOP_BLKTOOFF(vp, lbn, &offset);
821 if (error) {
822 (void)vnode_put(vp);
823 goto outdrop;
824 }
825 devBlockSize = vfs_devblocksize(vnode_mount(vp));
826
827 error = VNOP_BLOCKMAP(vp, offset, devBlockSize, &bn, NULL, NULL, 0, &context);
828
829 (void)vnode_put(vp);
830
831 if (!error) {
832 l2p_struct.l2p_flags = 0; /* for now */
833 l2p_struct.l2p_contigbytes = 0; /* for now */
834 l2p_struct.l2p_devoffset = bn * devBlockSize;
835 l2p_struct.l2p_devoffset += fp->f_offset - offset;
836 error = copyout((caddr_t)&l2p_struct, argp, sizeof (l2p_struct));
837 }
838 goto outdrop;
839 }
840 case F_GETPATH: {
841 char *pathbufp;
842 int pathlen;
843
844 if (fp->f_type != DTYPE_VNODE) {
845 error = EBADF;
846 goto out;
847 }
848 vp = (struct vnode *)fp->f_data;
849 proc_fdunlock(p);
850
851 pathlen = MAXPATHLEN;
852 MALLOC(pathbufp, char *, pathlen, M_TEMP, M_WAITOK);
853 if (pathbufp == NULL) {
854 error = ENOMEM;
855 goto outdrop;
856 }
857 if ( (error = vnode_getwithref(vp)) == 0 ) {
858 error = vn_getpath(vp, pathbufp, &pathlen);
859 (void)vnode_put(vp);
860
861 if (error == 0)
862 error = copyout((caddr_t)pathbufp, argp, pathlen);
863 }
864 FREE(pathbufp, M_TEMP);
865 goto outdrop;
866 }
867
868 case F_PATHPKG_CHECK: {
869 char *pathbufp;
870 size_t pathlen;
871
872 if (fp->f_type != DTYPE_VNODE) {
873 error = EBADF;
874 goto out;
875 }
876 vp = (struct vnode *)fp->f_data;
877 proc_fdunlock(p);
878
879 pathlen = MAXPATHLEN;
880 pathbufp = kalloc(MAXPATHLEN);
881
882 if ( (error = copyinstr(argp, pathbufp, MAXPATHLEN, &pathlen)) == 0 ) {
883 if ( (error = vnode_getwithref(vp)) == 0 ) {
884 error = vn_path_package_check(vp, pathbufp, pathlen, retval);
885
886 (void)vnode_put(vp);
887 }
888 }
889 kfree(pathbufp, MAXPATHLEN);
890 goto outdrop;
891 }
892
893 case F_CHKCLEAN: // used by regression tests to see if all dirty pages got cleaned by fsync()
894 case F_FULLFSYNC: // fsync + flush the journal + DKIOCSYNCHRONIZECACHE
895 case F_FREEZE_FS: // freeze all other fs operations for the fs of this fd
896 case F_THAW_FS: { // thaw all frozen fs operations for the fs of this fd
897 if (fp->f_type != DTYPE_VNODE) {
898 error = EBADF;
899 goto out;
900 }
901 vp = (struct vnode *)fp->f_data;
902 proc_fdunlock(p);
903
904 if ( (error = vnode_getwithref(vp)) == 0 ) {
905 error = VNOP_IOCTL(vp, uap->cmd, (caddr_t)NULL, 0, &context);
906
907 (void)vnode_put(vp);
908 }
909 break;
910 }
911
912 default:
913 if (uap->cmd < FCNTL_FS_SPECIFIC_BASE) {
914 error = EINVAL;
915 goto out;
916 }
917
918 // if it's a fs-specific fcntl() then just pass it through
919
920 if (fp->f_type != DTYPE_VNODE) {
921 error = EBADF;
922 goto out;
923 }
924 vp = (struct vnode *)fp->f_data;
925 proc_fdunlock(p);
926
927 if ( (error = vnode_getwithref(vp)) == 0 ) {
928 error = VNOP_IOCTL(vp, uap->cmd, CAST_DOWN(caddr_t, argp), 0, &context);
929
930 (void)vnode_put(vp);
931 }
932 break;
933
934 }
935
936 outdrop:
937 AUDIT_ARG(vnpath_withref, vp, ARG_VNODE1);
938 fp_drop(p, fd, fp, 0);
939 return(error);
940 out:
941 fp_drop(p, fd, fp, 1);
942 proc_fdunlock(p);
943 return(error);
944 }
945
946 /*
947 * Common code for dup, dup2, and fcntl(F_DUPFD).
948 */
949 int
950 finishdup(struct proc * p, struct filedesc *fdp, int old, int new, register_t *retval)
951 {
952 struct fileproc *nfp;
953 struct fileproc *ofp;
954
955 if ((ofp = fdp->fd_ofiles[old]) == NULL ||
956 (fdp->fd_ofileflags[old] & UF_RESERVED)) {
957 _fdrelse(fdp, new);
958 return (EBADF);
959 }
960 fg_ref(ofp);
961 proc_fdunlock(p);
962
963 MALLOC_ZONE(nfp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
964 bzero(nfp, sizeof(struct fileproc));
965
966 proc_fdlock(p);
967 nfp->f_flags = ofp->f_flags;
968 nfp->f_fglob = ofp->f_fglob;
969 nfp->f_iocount = 0;
970
971 fdp->fd_ofiles[new] = nfp;
972 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
973 if (new > fdp->fd_lastfile)
974 fdp->fd_lastfile = new;
975 *retval = new;
976 return (0);
977 }
978
979
980 int
981 close(struct proc *p, struct close_args *uap, __unused register_t *retval)
982 {
983 struct fileproc *fp;
984 int fd = uap->fd;
985 int error =0;
986
987 AUDIT_SYSCLOSE(p, fd);
988
989 proc_fdlock(p);
990
991 if ( (error = fp_lookup(p,fd,&fp, 1)) ) {
992 proc_fdunlock(p);
993 return(error);
994 }
995
996 error = close_internal(p, fd, fp, CLOSEINT_LOCKED | CLOSEINT_WAITONCLOSE);
997
998 proc_fdunlock(p);
999
1000 return(error);
1001 }
1002
1003
1004 /*
1005 * Close a file descriptor.
1006 */
1007 int
1008 close_internal(struct proc *p, int fd, struct fileproc *fp, int flags)
1009 {
1010 struct filedesc *fdp = p->p_fd;
1011 int error =0;
1012 int locked = flags & CLOSEINT_LOCKED;
1013 int waitonclose = flags & CLOSEINT_WAITONCLOSE;
1014 int norelse = flags & CLOSEINT_NOFDRELSE;
1015 int nofdref = flags & CLOSEINT_NOFDNOREF;
1016 int slpstate = PRIBIO;
1017
1018 if (!locked)
1019 proc_fdlock(p);
1020
1021 /* Keep people from using the filedesc while we are closing it */
1022 fdp->fd_ofileflags[fd] |= UF_RESERVED;
1023
1024 fdp->fd_ofileflags[fd] |= UF_CLOSING;
1025
1026
1027 if ((waitonclose && ((fp->f_flags & FP_CLOSING) == FP_CLOSING))) {
1028 if (nofdref == 0)
1029 fp_drop(p, fd, fp, 1);
1030 fp->f_flags |= FP_WAITCLOSE;
1031 if (!locked)
1032 slpstate |= PDROP;
1033 msleep(&fp->f_flags, &p->p_fdmlock, slpstate, "close wait",0) ;
1034 return(EBADF);
1035 }
1036
1037 fp->f_flags |= FP_CLOSING;
1038 if (nofdref)
1039 fp->f_iocount++;
1040
1041 if ( (fp->f_flags & FP_AIOISSUED) || kauth_authorize_fileop_has_listeners() ) {
1042
1043 proc_fdunlock(p);
1044
1045 if ( (fp->f_type == DTYPE_VNODE) && kauth_authorize_fileop_has_listeners() ) {
1046 /*
1047 * call out to allow 3rd party notification of close.
1048 * Ignore result of kauth_authorize_fileop call.
1049 */
1050 if (vnode_getwithref((vnode_t)fp->f_data) == 0) {
1051 u_int fileop_flags = 0;
1052 if ((fp->f_flags & FP_WRITTEN) != 0)
1053 fileop_flags |= KAUTH_FILEOP_CLOSE_MODIFIED;
1054 kauth_authorize_fileop(fp->f_fglob->fg_cred, KAUTH_FILEOP_CLOSE,
1055 (uintptr_t)fp->f_data, (uintptr_t)fileop_flags);
1056 vnode_put((vnode_t)fp->f_data);
1057 }
1058 }
1059 if (fp->f_flags & FP_AIOISSUED)
1060 /*
1061 * cancel all async IO requests that can be cancelled.
1062 */
1063 _aio_close( p, fd );
1064
1065 proc_fdlock(p);
1066 }
1067
1068 if (fd < fdp->fd_knlistsize)
1069 knote_fdclose(p, fd);
1070
1071 if (fp->f_flags & FP_WAITEVENT)
1072 (void)waitevent_close(p, fp);
1073
1074 if ((fp->f_flags & FP_INCHRREAD) == 0)
1075 fileproc_drain(p, fp);
1076 if (norelse == 0)
1077 _fdrelse(fdp, fd);
1078 error = closef_locked(fp, fp->f_fglob, p);
1079 if ((fp->f_flags & FP_WAITCLOSE) == FP_WAITCLOSE)
1080 wakeup(&fp->f_flags);
1081 fp->f_flags &= ~(FP_WAITCLOSE | FP_CLOSING);
1082
1083 if (!locked)
1084 proc_fdunlock(p);
1085
1086 FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
1087 return(error);
1088 }
1089
1090 /*
1091 * Return status information about a file descriptor.
1092 *
1093 * XXX switch on node type is bogus; need a stat in struct fileops instead.
1094 */
1095 static int
1096 fstat1(struct proc *p, int fd, user_addr_t ub, user_addr_t xsecurity, user_addr_t xsecurity_size)
1097 {
1098 struct fileproc *fp;
1099 struct stat sb;
1100 struct user_stat user_sb;
1101 int error, my_size;
1102 int funnel_state;
1103 short type;
1104 caddr_t data;
1105 kauth_filesec_t fsec;
1106 ssize_t xsecurity_bufsize;
1107 int entrycount;
1108 struct vfs_context context;
1109
1110
1111 AUDIT_ARG(fd, fd);
1112
1113 if ((error = fp_lookup(p, fd, &fp, 0)) != 0)
1114 return(error);
1115 type = fp->f_type;
1116 data = fp->f_data;
1117 fsec = KAUTH_FILESEC_NONE;
1118
1119 switch (type) {
1120
1121 case DTYPE_VNODE:
1122 context.vc_proc = current_proc();
1123 context.vc_ucred = kauth_cred_get();
1124 if ((error = vnode_getwithref((vnode_t)data)) == 0) {
1125 /*
1126 * If the caller has the file open, and is not requesting extended security,
1127 * we are going to let them get the basic stat information.
1128 */
1129 if (xsecurity == USER_ADDR_NULL) {
1130 error = vn_stat_noauth((vnode_t)data, &sb, NULL, &context);
1131 } else {
1132 error = vn_stat((vnode_t)data, &sb, &fsec, &context);
1133 }
1134
1135 AUDIT_ARG(vnpath, (struct vnode *)data, ARG_VNODE1);
1136 (void)vnode_put((vnode_t)data);
1137 }
1138 break;
1139
1140 case DTYPE_SOCKET:
1141 error = soo_stat((struct socket *)data, &sb);
1142 break;
1143
1144 case DTYPE_PIPE:
1145 error = pipe_stat((void *)data, &sb);
1146 break;
1147
1148 case DTYPE_PSXSHM:
1149 error = pshm_stat((void *)data, &sb);
1150 break;
1151
1152 case DTYPE_KQUEUE:
1153 funnel_state = thread_funnel_set(kernel_flock, TRUE);
1154 error = kqueue_stat(fp, &sb, p);
1155 thread_funnel_set(kernel_flock, funnel_state);
1156 break;
1157
1158 default:
1159 error = EBADF;
1160 goto out;
1161 }
1162 /* Zap spare fields */
1163 sb.st_lspare = 0;
1164 sb.st_qspare[0] = 0LL;
1165 sb.st_qspare[1] = 0LL;
1166 if (error == 0) {
1167 caddr_t sbp;
1168 if (IS_64BIT_PROCESS(current_proc())) {
1169 munge_stat(&sb, &user_sb);
1170 my_size = sizeof(user_sb);
1171 sbp = (caddr_t)&user_sb;
1172 }
1173 else {
1174 my_size = sizeof(sb);
1175 sbp = (caddr_t)&sb;
1176 }
1177 error = copyout(sbp, ub, my_size);
1178 }
1179
1180 /* caller wants extended security information? */
1181 if (xsecurity != USER_ADDR_NULL) {
1182
1183 /* did we get any? */
1184 if (fsec == KAUTH_FILESEC_NONE) {
1185 if (susize(xsecurity_size, 0) != 0) {
1186 error = EFAULT;
1187 goto out;
1188 }
1189 } else {
1190 /* find the user buffer size */
1191 xsecurity_bufsize = fusize(xsecurity_size);
1192
1193 /* copy out the actual data size */
1194 if (susize(xsecurity_size, KAUTH_FILESEC_COPYSIZE(fsec)) != 0) {
1195 error = EFAULT;
1196 goto out;
1197 }
1198
1199 /* if the caller supplied enough room, copy out to it */
1200 if (xsecurity_bufsize >= KAUTH_FILESEC_COPYSIZE(fsec))
1201 error = copyout(fsec, xsecurity, KAUTH_FILESEC_COPYSIZE(fsec));
1202 }
1203 }
1204 out:
1205 fp_drop(p, fd, fp, 0);
1206 if (fsec != NULL)
1207 kauth_filesec_free(fsec);
1208 return (error);
1209 }
1210
1211 int
1212 fstat_extended(struct proc *p, struct fstat_extended_args *uap, __unused register_t *retval)
1213 {
1214 return(fstat1(p, uap->fd, uap->ub, uap->xsecurity, uap->xsecurity_size));
1215 }
1216
1217 int
1218 fstat(struct proc *p, register struct fstat_args *uap, __unused register_t *retval)
1219 {
1220 return(fstat1(p, uap->fd, uap->ub, 0, 0));
1221 }
1222
1223 /*
1224 * Return pathconf information about a file descriptor.
1225 */
1226 int
1227 fpathconf(p, uap, retval)
1228 struct proc *p;
1229 register struct fpathconf_args *uap;
1230 register_t *retval;
1231 {
1232 int fd = uap->fd;
1233 struct fileproc *fp;
1234 struct vnode *vp;
1235 struct vfs_context context;
1236 int error = 0;
1237 short type;
1238 caddr_t data;
1239
1240
1241 AUDIT_ARG(fd, uap->fd);
1242 if ( (error = fp_lookup(p, fd, &fp, 0)) )
1243 return(error);
1244 type = fp->f_type;
1245 data = fp->f_data;
1246
1247 switch (type) {
1248
1249 case DTYPE_SOCKET:
1250 if (uap->name != _PC_PIPE_BUF) {
1251 error = EINVAL;
1252 goto out;
1253 }
1254 *retval = PIPE_BUF;
1255 error = 0;
1256 goto out;
1257
1258 case DTYPE_PIPE:
1259 *retval = PIPE_BUF;
1260 error = 0;
1261 goto out;
1262
1263 case DTYPE_VNODE:
1264 vp = (struct vnode *)data;
1265
1266 if ( (error = vnode_getwithref(vp)) == 0) {
1267 AUDIT_ARG(vnpath, vp, ARG_VNODE1);
1268
1269 context.vc_proc = p;
1270 context.vc_ucred = kauth_cred_get();
1271
1272 error = vn_pathconf(vp, uap->name, retval, &context);
1273
1274 (void)vnode_put(vp);
1275 }
1276 goto out;
1277
1278 case DTYPE_PSXSHM:
1279 case DTYPE_KQUEUE:
1280 error = EINVAL;
1281 goto out;
1282
1283 default:
1284 panic("fpathconf (unrecognized - %d)", type);
1285 }
1286 /*NOTREACHED*/
1287 out:
1288 fp_drop(p, fd, fp, 0);
1289 return(error);
1290 }
1291
1292 /*
1293 * Allocate a file descriptor for the process.
1294 */
1295 int fdexpand;
1296
1297 int
1298 fdalloc(p, want, result)
1299 struct proc *p;
1300 int want;
1301 int *result;
1302 {
1303 register struct filedesc *fdp = p->p_fd;
1304 register int i;
1305 int lim, last, numfiles, oldnfiles;
1306 struct fileproc **newofiles, **ofiles;
1307 char *newofileflags, *ofileflags;
1308
1309 /*
1310 * Search for a free descriptor starting at the higher
1311 * of want or fd_freefile. If that fails, consider
1312 * expanding the ofile array.
1313 */
1314 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
1315 for (;;) {
1316 last = min(fdp->fd_nfiles, lim);
1317 if ((i = want) < fdp->fd_freefile)
1318 i = fdp->fd_freefile;
1319 ofiles = &fdp->fd_ofiles[i];
1320 ofileflags = &fdp->fd_ofileflags[i];
1321 for (; i < last; i++) {
1322 if (*ofiles == NULL && !(*ofileflags & UF_RESERVED)) {
1323 *ofileflags = UF_RESERVED;
1324 if (i > fdp->fd_lastfile)
1325 fdp->fd_lastfile = i;
1326 if (want <= fdp->fd_freefile)
1327 fdp->fd_freefile = i;
1328 *result = i;
1329 return (0);
1330 }
1331 ofiles++; ofileflags++;
1332 }
1333
1334 /*
1335 * No space in current array. Expand?
1336 */
1337 if (fdp->fd_nfiles >= lim)
1338 return (EMFILE);
1339 if (fdp->fd_nfiles < NDEXTENT)
1340 numfiles = NDEXTENT;
1341 else
1342 numfiles = 2 * fdp->fd_nfiles;
1343 /* Enforce lim */
1344 if (numfiles > lim)
1345 numfiles = lim;
1346 proc_fdunlock(p);
1347 MALLOC_ZONE(newofiles, struct fileproc **,
1348 numfiles * OFILESIZE, M_OFILETABL, M_WAITOK);
1349 proc_fdlock(p);
1350 if (newofiles == NULL) {
1351 return (ENOMEM);
1352 }
1353 if (fdp->fd_nfiles >= numfiles) {
1354 FREE_ZONE(newofiles, numfiles * OFILESIZE, M_OFILETABL);
1355 continue;
1356 }
1357 newofileflags = (char *) &newofiles[numfiles];
1358 /*
1359 * Copy the existing ofile and ofileflags arrays
1360 * and zero the new portion of each array.
1361 */
1362 oldnfiles = fdp->fd_nfiles;
1363 (void) memcpy(newofiles, fdp->fd_ofiles,
1364 oldnfiles * sizeof *fdp->fd_ofiles);
1365 (void) memset(&newofiles[oldnfiles], 0,
1366 (numfiles - oldnfiles) * sizeof *fdp->fd_ofiles);
1367
1368 (void) memcpy(newofileflags, fdp->fd_ofileflags,
1369 oldnfiles * sizeof *fdp->fd_ofileflags);
1370 (void) memset(&newofileflags[oldnfiles], 0,
1371 (numfiles - oldnfiles) *
1372 sizeof *fdp->fd_ofileflags);
1373 ofiles = fdp->fd_ofiles;
1374 fdp->fd_ofiles = newofiles;
1375 fdp->fd_ofileflags = newofileflags;
1376 fdp->fd_nfiles = numfiles;
1377 FREE_ZONE(ofiles, oldnfiles * OFILESIZE, M_OFILETABL);
1378 fdexpand++;
1379 }
1380 }
1381
1382 /*
1383 * Check to see whether n user file descriptors
1384 * are available to the process p.
1385 */
1386 int
1387 fdavail(p, n)
1388 struct proc *p;
1389 int n;
1390 {
1391 struct filedesc *fdp = p->p_fd;
1392 struct fileproc **fpp;
1393 char *flags;
1394 int i, lim;
1395
1396 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
1397 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
1398 return (1);
1399 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
1400 flags = &fdp->fd_ofileflags[fdp->fd_freefile];
1401 for (i = fdp->fd_nfiles - fdp->fd_freefile; --i >= 0; fpp++, flags++)
1402 if (*fpp == NULL && !(*flags & UF_RESERVED) && --n <= 0)
1403 return (1);
1404 return (0);
1405 }
1406
1407 void
1408 fdrelse(p, fd)
1409 struct proc *p;
1410 int fd;
1411 {
1412 _fdrelse(p->p_fd, fd);
1413 }
1414
1415 void
1416 fddrop(p, fd)
1417 struct proc *p;
1418 int fd;
1419 {
1420 struct filedesc *fdp = p->p_fd;
1421 struct fileproc *fp;
1422
1423 if (fd < fdp->fd_freefile)
1424 fdp->fd_freefile = fd;
1425 #if DIAGNOSTIC
1426 if (fd > fdp->fd_lastfile)
1427 panic("fdrelse: fd_lastfile inconsistent");
1428 #endif
1429 fp = fdp->fd_ofiles[fd];
1430 fdp->fd_ofiles[fd] = NULL;
1431 fdp->fd_ofileflags[fd] = 0;
1432
1433 while ((fd = fdp->fd_lastfile) > 0 &&
1434 fdp->fd_ofiles[fd] == NULL &&
1435 !(fdp->fd_ofileflags[fd] & UF_RESERVED))
1436 fdp->fd_lastfile--;
1437 FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
1438 }
1439
1440
1441 int
1442 fdgetf_noref(p, fd, resultfp)
1443 struct proc *p;
1444 int fd;
1445 struct fileproc **resultfp;
1446 {
1447 struct filedesc *fdp = p->p_fd;
1448 struct fileproc *fp;
1449
1450 if (fd < 0 || fd >= fdp->fd_nfiles ||
1451 (fp = fdp->fd_ofiles[fd]) == NULL ||
1452 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1453 return (EBADF);
1454 }
1455 if (resultfp)
1456 *resultfp = fp;
1457 return (0);
1458 }
1459
1460
1461 /* should be called only when proc_fdlock is held */
1462 void
1463 fp_setflags(proc_t p, struct fileproc * fp, int flags)
1464 {
1465 proc_fdlock(p);
1466 fp->f_flags |= flags;
1467 proc_fdunlock(p);
1468 }
1469
1470 void
1471 fp_clearflags(proc_t p, struct fileproc * fp, int flags)
1472 {
1473
1474 proc_fdlock(p);
1475 if (fp)
1476 fp->f_flags &= ~flags;
1477 proc_fdunlock(p);
1478 }
1479
1480 int
1481 fp_getfvp(p, fd, resultfp, resultvp)
1482 struct proc *p;
1483 int fd;
1484 struct fileproc **resultfp;
1485 struct vnode **resultvp;
1486 {
1487 struct filedesc *fdp = p->p_fd;
1488 struct fileproc *fp;
1489
1490 proc_fdlock(p);
1491 if (fd < 0 || fd >= fdp->fd_nfiles ||
1492 (fp = fdp->fd_ofiles[fd]) == NULL ||
1493 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1494 proc_fdunlock(p);
1495 return (EBADF);
1496 }
1497 if (fp->f_type != DTYPE_VNODE) {
1498 proc_fdunlock(p);
1499 return(ENOTSUP);
1500 }
1501 fp->f_iocount++;
1502
1503 if (resultfp)
1504 *resultfp = fp;
1505 if (resultvp)
1506 *resultvp = (struct vnode *)fp->f_data;
1507 proc_fdunlock(p);
1508
1509 return (0);
1510 }
1511
1512
1513 /*
1514 * Returns: EBADF The file descriptor is invalid
1515 * EOPNOTSUPP The file descriptor is not a socket
1516 * 0 Success
1517 *
1518 * Notes: EOPNOTSUPP should probably be ENOTSOCK; this function is only
1519 * ever called from accept1().
1520 */
1521 int
1522 fp_getfsock(p, fd, resultfp, results)
1523 struct proc *p;
1524 int fd;
1525 struct fileproc **resultfp;
1526 struct socket **results;
1527 {
1528 struct filedesc *fdp = p->p_fd;
1529 struct fileproc *fp;
1530
1531 proc_fdlock(p);
1532 if (fd < 0 || fd >= fdp->fd_nfiles ||
1533 (fp = fdp->fd_ofiles[fd]) == NULL ||
1534 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1535 proc_fdunlock(p);
1536 return (EBADF);
1537 }
1538 if (fp->f_type != DTYPE_SOCKET) {
1539 proc_fdunlock(p);
1540 return(EOPNOTSUPP);
1541 }
1542 fp->f_iocount++;
1543
1544 if (resultfp)
1545 *resultfp = fp;
1546 if (results)
1547 *results = (struct socket *)fp->f_data;
1548 proc_fdunlock(p);
1549
1550 return (0);
1551 }
1552
1553
1554 int
1555 fp_getfkq(p, fd, resultfp, resultkq)
1556 struct proc *p;
1557 int fd;
1558 struct fileproc **resultfp;
1559 struct kqueue **resultkq;
1560 {
1561 struct filedesc *fdp = p->p_fd;
1562 struct fileproc *fp;
1563
1564 proc_fdlock(p);
1565 if ( fd < 0 || fd >= fdp->fd_nfiles ||
1566 (fp = fdp->fd_ofiles[fd]) == NULL ||
1567 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1568 proc_fdunlock(p);
1569 return (EBADF);
1570 }
1571 if (fp->f_type != DTYPE_KQUEUE) {
1572 proc_fdunlock(p);
1573 return(EBADF);
1574 }
1575 fp->f_iocount++;
1576
1577 if (resultfp)
1578 *resultfp = fp;
1579 if (resultkq)
1580 *resultkq = (struct kqueue *)fp->f_data;
1581 proc_fdunlock(p);
1582
1583 return (0);
1584 }
1585
1586 int
1587 fp_getfpshm(p, fd, resultfp, resultpshm)
1588 struct proc *p;
1589 int fd;
1590 struct fileproc **resultfp;
1591 struct pshmnode **resultpshm;
1592 {
1593 struct filedesc *fdp = p->p_fd;
1594 struct fileproc *fp;
1595
1596 proc_fdlock(p);
1597 if (fd < 0 || fd >= fdp->fd_nfiles ||
1598 (fp = fdp->fd_ofiles[fd]) == NULL ||
1599 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1600 proc_fdunlock(p);
1601 return (EBADF);
1602 }
1603 if (fp->f_type != DTYPE_PSXSHM) {
1604
1605 proc_fdunlock(p);
1606 return(EBADF);
1607 }
1608 fp->f_iocount++;
1609
1610 if (resultfp)
1611 *resultfp = fp;
1612 if (resultpshm)
1613 *resultpshm = (struct pshmnode *)fp->f_data;
1614 proc_fdunlock(p);
1615
1616 return (0);
1617 }
1618
1619
1620 int
1621 fp_getfpsem(p, fd, resultfp, resultpsem)
1622 struct proc *p;
1623 int fd;
1624 struct fileproc **resultfp;
1625 struct psemnode **resultpsem;
1626 {
1627 struct filedesc *fdp = p->p_fd;
1628 struct fileproc *fp;
1629
1630 proc_fdlock(p);
1631 if (fd < 0 || fd >= fdp->fd_nfiles ||
1632 (fp = fdp->fd_ofiles[fd]) == NULL ||
1633 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1634 proc_fdunlock(p);
1635 return (EBADF);
1636 }
1637 if (fp->f_type != DTYPE_PSXSEM) {
1638 proc_fdunlock(p);
1639 return(EBADF);
1640 }
1641 fp->f_iocount++;
1642
1643 if (resultfp)
1644 *resultfp = fp;
1645 if (resultpsem)
1646 *resultpsem = (struct psemnode *)fp->f_data;
1647 proc_fdunlock(p);
1648
1649 return (0);
1650 }
1651 int
1652 fp_lookup(p, fd, resultfp, locked)
1653 struct proc *p;
1654 int fd;
1655 struct fileproc **resultfp;
1656 int locked;
1657 {
1658 struct filedesc *fdp = p->p_fd;
1659 struct fileproc *fp;
1660
1661 if (!locked)
1662 proc_fdlock(p);
1663 if (fd < 0 || fd >= fdp->fd_nfiles ||
1664 (fp = fdp->fd_ofiles[fd]) == NULL ||
1665 (fdp->fd_ofileflags[fd] & UF_RESERVED)) {
1666 if (!locked)
1667 proc_fdunlock(p);
1668 return (EBADF);
1669 }
1670 fp->f_iocount++;
1671
1672 if (resultfp)
1673 *resultfp = fp;
1674 if (!locked)
1675 proc_fdunlock(p);
1676
1677 return (0);
1678 }
1679
1680 int
1681 fp_drop_written(proc_t p, int fd, struct fileproc *fp)
1682 {
1683 int error;
1684
1685 proc_fdlock(p);
1686
1687 fp->f_flags |= FP_WRITTEN;
1688
1689 error = fp_drop(p, fd, fp, 1);
1690
1691 proc_fdunlock(p);
1692
1693 return (error);
1694 }
1695
1696
1697 int
1698 fp_drop_event(proc_t p, int fd, struct fileproc *fp)
1699 {
1700 int error;
1701
1702 proc_fdlock(p);
1703
1704 fp->f_flags |= FP_WAITEVENT;
1705
1706 error = fp_drop(p, fd, fp, 1);
1707
1708 proc_fdunlock(p);
1709
1710 return (error);
1711 }
1712
1713 int
1714 fp_drop(p, fd, fp, locked)
1715 struct proc *p;
1716 int fd;
1717 struct fileproc *fp;
1718 int locked;
1719 {
1720 struct filedesc *fdp = p->p_fd;
1721
1722 if (!locked)
1723 proc_fdlock(p);
1724 if ((fp == FILEPROC_NULL) && (fd < 0 || fd >= fdp->fd_nfiles ||
1725 (fp = fdp->fd_ofiles[fd]) == NULL ||
1726 ((fdp->fd_ofileflags[fd] & UF_RESERVED) &&
1727 !(fdp->fd_ofileflags[fd] & UF_CLOSING)))) {
1728 if (!locked)
1729 proc_fdunlock(p);
1730 return (EBADF);
1731 }
1732 fp->f_iocount--;
1733
1734 if (p->p_fpdrainwait && fp->f_iocount == 0) {
1735 p->p_fpdrainwait = 0;
1736 wakeup(&p->p_fpdrainwait);
1737 }
1738 if (!locked)
1739 proc_fdunlock(p);
1740
1741 return (0);
1742 }
1743
1744 int
1745 file_vnode(int fd, struct vnode **vpp)
1746 {
1747 struct proc * p = current_proc();
1748 struct fileproc *fp;
1749 int error;
1750
1751 proc_fdlock(p);
1752 if ( (error = fp_lookup(p, fd, &fp, 1)) ) {
1753 proc_fdunlock(p);
1754 return(error);
1755 }
1756 if (fp->f_type != DTYPE_VNODE) {
1757 fp_drop(p, fd, fp,1);
1758 proc_fdunlock(p);
1759 return(EINVAL);
1760 }
1761 *vpp = (struct vnode *)fp->f_data;
1762 proc_fdunlock(p);
1763
1764 return(0);
1765 }
1766
1767
1768 int
1769 file_socket(int fd, struct socket **sp)
1770 {
1771 struct proc * p = current_proc();
1772 struct fileproc *fp;
1773 int error;
1774
1775 proc_fdlock(p);
1776 if ( (error = fp_lookup(p, fd, &fp, 1)) ) {
1777 proc_fdunlock(p);
1778 return(error);
1779 }
1780 if (fp->f_type != DTYPE_SOCKET) {
1781 fp_drop(p, fd, fp,1);
1782 proc_fdunlock(p);
1783 return(ENOTSOCK);
1784 }
1785 *sp = (struct socket *)fp->f_data;
1786 proc_fdunlock(p);
1787
1788 return(0);
1789 }
1790
1791 int
1792 file_flags(int fd, int * flags)
1793 {
1794
1795 struct proc * p = current_proc();
1796 struct fileproc *fp;
1797 int error;
1798
1799 proc_fdlock(p);
1800 if ( (error = fp_lookup(p, fd, &fp, 1)) ) {
1801 proc_fdunlock(p);
1802 return(error);
1803 }
1804 *flags = (int)fp->f_flag;
1805 fp_drop(p, fd, fp,1);
1806 proc_fdunlock(p);
1807
1808 return(0);
1809 }
1810
1811
1812 int
1813 file_drop(int fd)
1814 {
1815 struct fileproc *fp;
1816 struct proc *p = current_proc();
1817
1818 proc_fdlock(p);
1819 if (fd < 0 || fd >= p->p_fd->fd_nfiles ||
1820 (fp = p->p_fd->fd_ofiles[fd]) == NULL ||
1821 ((p->p_fd->fd_ofileflags[fd] & UF_RESERVED) &&
1822 !(p->p_fd->fd_ofileflags[fd] & UF_CLOSING))) {
1823 proc_fdunlock(p);
1824 return (EBADF);
1825 }
1826 fp->f_iocount --;
1827
1828 if (p->p_fpdrainwait && fp->f_iocount == 0) {
1829 p->p_fpdrainwait = 0;
1830 wakeup(&p->p_fpdrainwait);
1831 }
1832 proc_fdunlock(p);
1833 return(0);
1834
1835
1836 }
1837
1838 int
1839 falloc(p, resultfp, resultfd )
1840 struct proc *p;
1841 struct fileproc **resultfp;
1842 int *resultfd;
1843 {
1844 int error;
1845
1846 proc_fdlock(p);
1847 error = falloc_locked(p, resultfp, resultfd, 1);
1848 proc_fdunlock(p);
1849
1850 return(error);
1851 }
1852 /*
1853 * Create a new open file structure and allocate
1854 * a file decriptor for the process that refers to it.
1855 */
1856 int
1857 falloc_locked(p, resultfp, resultfd, locked)
1858 struct proc *p;
1859 struct fileproc **resultfp;
1860 int *resultfd;
1861 int locked;
1862 {
1863 struct fileproc *fp, *fq;
1864 struct fileglob *fg;
1865 int error, nfd;
1866
1867 if (!locked)
1868 proc_fdlock(p);
1869 if ( (error = fdalloc(p, 0, &nfd)) ) {
1870 if (!locked)
1871 proc_fdunlock(p);
1872 return (error);
1873 }
1874 if (nfiles >= maxfiles) {
1875 if (!locked)
1876 proc_fdunlock(p);
1877 tablefull("file");
1878 return (ENFILE);
1879 }
1880 /*
1881 * Allocate a new file descriptor.
1882 * If the process has file descriptor zero open, add to the list
1883 * of open files at that point, otherwise put it at the front of
1884 * the list of open files.
1885 */
1886 proc_fdunlock(p);
1887
1888 MALLOC_ZONE(fp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
1889 MALLOC_ZONE(fg, struct fileglob *, sizeof(struct fileglob), M_FILEGLOB, M_WAITOK);
1890 bzero(fp, sizeof(struct fileproc));
1891 bzero(fg, sizeof(struct fileglob));
1892 lck_mtx_init(&fg->fg_lock, file_lck_grp, file_lck_attr);
1893
1894 fp->f_iocount = 1;
1895 fg->fg_count = 1;
1896 fp->f_fglob = fg;
1897
1898 proc_fdlock(p);
1899
1900 fp->f_cred = kauth_cred_proc_ref(p);
1901
1902 lck_mtx_lock(file_flist_lock);
1903
1904 nfiles++;
1905
1906 if ( (fq = p->p_fd->fd_ofiles[0]) ) {
1907 LIST_INSERT_AFTER(fq->f_fglob, fg, f_list);
1908 } else {
1909 LIST_INSERT_HEAD(&filehead, fg, f_list);
1910 }
1911 lck_mtx_unlock(file_flist_lock);
1912
1913 p->p_fd->fd_ofiles[nfd] = fp;
1914
1915 if (!locked)
1916 proc_fdunlock(p);
1917
1918 if (resultfp)
1919 *resultfp = fp;
1920 if (resultfd)
1921 *resultfd = nfd;
1922
1923 return (0);
1924 }
1925
1926 /*
1927 * Free a file structure.
1928 */
1929 void
1930 fg_free(fg)
1931 struct fileglob *fg;
1932 {
1933 kauth_cred_t cred;
1934
1935 lck_mtx_lock(file_flist_lock);
1936 LIST_REMOVE(fg, f_list);
1937 nfiles--;
1938 lck_mtx_unlock(file_flist_lock);
1939
1940 cred = fg->fg_cred;
1941 if (cred != NOCRED) {
1942 fg->fg_cred = NOCRED;
1943 kauth_cred_rele(cred);
1944 }
1945 lck_mtx_destroy(&fg->fg_lock, file_lck_grp);
1946
1947 FREE_ZONE(fg, sizeof *fg, M_FILEGLOB);
1948 }
1949
1950 void
1951 fdexec(p)
1952 struct proc *p;
1953 {
1954 struct filedesc *fdp = p->p_fd;
1955 int i = fdp->fd_lastfile;
1956 struct fileproc **fpp = &fdp->fd_ofiles[i];
1957 char *flags = &fdp->fd_ofileflags[i];
1958 int funnel_state;
1959
1960 funnel_state = thread_funnel_set(kernel_flock, FALSE);
1961 proc_fdlock(p);
1962
1963 while (i >= 0) {
1964 if ((*flags & (UF_RESERVED|UF_EXCLOSE)) == UF_EXCLOSE) {
1965 struct fileproc *fp = *fpp;
1966
1967 if (i < fdp->fd_knlistsize)
1968 knote_fdclose(p, i);
1969
1970 *fpp = NULL; *flags = 0;
1971 if (i == fdp->fd_lastfile && i > 0)
1972 fdp->fd_lastfile--;
1973 closef_locked(fp, fp->f_fglob, p);
1974 FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
1975 }
1976
1977 i--; fpp--; flags--;
1978 }
1979 proc_fdunlock(p);
1980 thread_funnel_set(kernel_flock, funnel_state);
1981 }
1982
1983 /*
1984 * Copy a filedesc structure.
1985 */
1986 struct filedesc *
1987 fdcopy(p)
1988 struct proc *p;
1989 {
1990 struct filedesc *newfdp, *fdp = p->p_fd;
1991 int i;
1992 struct fileproc *ofp, *fp;
1993 vnode_t v_dir;
1994
1995 MALLOC_ZONE(newfdp, struct filedesc *,
1996 sizeof *newfdp, M_FILEDESC, M_WAITOK);
1997 if (newfdp == NULL)
1998 return(NULL);
1999
2000 proc_fdlock(p);
2001
2002 /*
2003 * the FD_CHROOT flag will be inherited via this copy
2004 */
2005 (void) memcpy(newfdp, fdp, sizeof *newfdp);
2006
2007 /*
2008 * for both fd_cdir and fd_rdir make sure we get
2009 * a valid reference... if we can't, than set
2010 * set the pointer(s) to NULL in the child... this
2011 * will keep us from using a non-referenced vp
2012 * and allows us to do the vnode_rele only on
2013 * a properly referenced vp
2014 */
2015 if ( (v_dir = newfdp->fd_cdir) ) {
2016 if (vnode_getwithref(v_dir) == 0) {
2017 if ( (vnode_ref(v_dir)) )
2018 newfdp->fd_cdir = NULL;
2019 vnode_put(v_dir);
2020 } else
2021 newfdp->fd_cdir = NULL;
2022 }
2023 if (newfdp->fd_cdir == NULL && fdp->fd_cdir) {
2024 /*
2025 * we couldn't get a new reference on
2026 * the current working directory being
2027 * inherited... we might as well drop
2028 * our reference from the parent also
2029 * since the vnode has gone DEAD making
2030 * it useless... by dropping it we'll
2031 * be that much closer to recyling it
2032 */
2033 vnode_rele(fdp->fd_cdir);
2034 fdp->fd_cdir = NULL;
2035 }
2036
2037 if ( (v_dir = newfdp->fd_rdir) ) {
2038 if (vnode_getwithref(v_dir) == 0) {
2039 if ( (vnode_ref(v_dir)) )
2040 newfdp->fd_rdir = NULL;
2041 vnode_put(v_dir);
2042 } else
2043 newfdp->fd_rdir = NULL;
2044 }
2045 if (newfdp->fd_rdir == NULL && fdp->fd_rdir) {
2046 /*
2047 * we couldn't get a new reference on
2048 * the root directory being
2049 * inherited... we might as well drop
2050 * our reference from the parent also
2051 * since the vnode has gone DEAD making
2052 * it useless... by dropping it we'll
2053 * be that much closer to recyling it
2054 */
2055 vnode_rele(fdp->fd_rdir);
2056 fdp->fd_rdir = NULL;
2057 }
2058 newfdp->fd_refcnt = 1;
2059
2060 /*
2061 * If the number of open files fits in the internal arrays
2062 * of the open file structure, use them, otherwise allocate
2063 * additional memory for the number of descriptors currently
2064 * in use.
2065 */
2066 if (newfdp->fd_lastfile < NDFILE)
2067 i = NDFILE;
2068 else {
2069 /*
2070 * Compute the smallest multiple of NDEXTENT needed
2071 * for the file descriptors currently in use,
2072 * allowing the table to shrink.
2073 */
2074 i = newfdp->fd_nfiles;
2075 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
2076 i /= 2;
2077 }
2078 proc_fdunlock(p);
2079
2080 MALLOC_ZONE(newfdp->fd_ofiles, struct fileproc **,
2081 i * OFILESIZE, M_OFILETABL, M_WAITOK);
2082 if (newfdp->fd_ofiles == NULL) {
2083 if (newfdp->fd_cdir)
2084 vnode_rele(newfdp->fd_cdir);
2085 if (newfdp->fd_rdir)
2086 vnode_rele(newfdp->fd_rdir);
2087
2088 FREE_ZONE(newfdp, sizeof *newfdp, M_FILEDESC);
2089 return(NULL);
2090 }
2091 proc_fdlock(p);
2092
2093 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
2094 newfdp->fd_nfiles = i;
2095
2096 if (fdp->fd_nfiles > 0) {
2097 struct fileproc **fpp;
2098 char *flags;
2099
2100 (void) memcpy(newfdp->fd_ofiles, fdp->fd_ofiles,
2101 i * sizeof *fdp->fd_ofiles);
2102 (void) memcpy(newfdp->fd_ofileflags, fdp->fd_ofileflags,
2103 i * sizeof *fdp->fd_ofileflags);
2104
2105 /*
2106 * kq descriptors cannot be copied.
2107 */
2108 if (newfdp->fd_knlistsize != -1) {
2109 fpp = &newfdp->fd_ofiles[newfdp->fd_lastfile];
2110 for (i = newfdp->fd_lastfile; i >= 0; i--, fpp--) {
2111 if (*fpp != NULL && (*fpp)->f_type == DTYPE_KQUEUE) {
2112 *fpp = NULL;
2113 if (i < newfdp->fd_freefile)
2114 newfdp->fd_freefile = i;
2115 }
2116 if (*fpp == NULL && i == newfdp->fd_lastfile && i > 0)
2117 newfdp->fd_lastfile--;
2118 }
2119 newfdp->fd_knlist = NULL;
2120 newfdp->fd_knlistsize = -1;
2121 newfdp->fd_knhash = NULL;
2122 newfdp->fd_knhashmask = 0;
2123 }
2124 fpp = newfdp->fd_ofiles;
2125 flags = newfdp->fd_ofileflags;
2126
2127 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++, flags++)
2128 if ((ofp = *fpp) != NULL && !(*flags & UF_RESERVED)) {
2129 MALLOC_ZONE(fp, struct fileproc *, sizeof(struct fileproc), M_FILEPROC, M_WAITOK);
2130 bzero(fp, sizeof(struct fileproc));
2131 fp->f_flags = ofp->f_flags;
2132 //fp->f_iocount = ofp->f_iocount;
2133 fp->f_iocount = 0;
2134 fp->f_fglob = ofp->f_fglob;
2135 (void)fg_ref(fp);
2136 *fpp = fp;
2137 } else {
2138 *fpp = NULL;
2139 *flags = 0;
2140 }
2141 } else
2142 (void) memset(newfdp->fd_ofiles, 0, i * OFILESIZE);
2143
2144 proc_fdunlock(p);
2145 return (newfdp);
2146 }
2147
2148 /*
2149 * Release a filedesc structure.
2150 */
2151 void
2152 fdfree(p)
2153 struct proc *p;
2154 {
2155 struct filedesc *fdp;
2156 struct fileproc *fp;
2157 int i;
2158
2159 proc_fdlock(p);
2160
2161 /* Certain daemons might not have file descriptors */
2162 fdp = p->p_fd;
2163
2164 if ((fdp == NULL) || (--fdp->fd_refcnt > 0)) {
2165 proc_fdunlock(p);
2166 return;
2167 }
2168 if (fdp->fd_refcnt == 0xffff)
2169 panic("fdfree: bad fd_refcnt");
2170
2171 /* Last reference: the structure can't change out from under us */
2172
2173 if (fdp->fd_nfiles > 0 && fdp->fd_ofiles) {
2174 for (i = fdp->fd_lastfile; i >= 0; i--) {
2175 if ((fp = fdp->fd_ofiles[i]) != NULL) {
2176
2177 if (fdp->fd_ofileflags[i] & UF_RESERVED)
2178 panic("fdfree: found fp with UF_RESERVED\n");
2179
2180 /* closef drops the iocount ... */
2181 if ((fp->f_flags & FP_INCHRREAD) != 0)
2182 fp->f_iocount++;
2183 fdp->fd_ofiles[i] = NULL;
2184 fdp->fd_ofileflags[i] |= UF_RESERVED;
2185
2186 if (i < fdp->fd_knlistsize)
2187 knote_fdclose(p, i);
2188 if (fp->f_flags & FP_WAITEVENT)
2189 (void)waitevent_close(p, fp);
2190 (void) closef_locked(fp, fp->f_fglob, p);
2191 FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
2192 }
2193 }
2194 FREE_ZONE(fdp->fd_ofiles, fdp->fd_nfiles * OFILESIZE, M_OFILETABL);
2195 fdp->fd_ofiles = NULL;
2196 fdp->fd_nfiles = 0;
2197 }
2198
2199 proc_fdunlock(p);
2200
2201 if (fdp->fd_cdir)
2202 vnode_rele(fdp->fd_cdir);
2203 if (fdp->fd_rdir)
2204 vnode_rele(fdp->fd_rdir);
2205
2206 proc_fdlock(p);
2207 p->p_fd = NULL;
2208 proc_fdunlock(p);
2209
2210 if (fdp->fd_knlist)
2211 FREE(fdp->fd_knlist, M_KQUEUE);
2212 if (fdp->fd_knhash)
2213 FREE(fdp->fd_knhash, M_KQUEUE);
2214
2215 FREE_ZONE(fdp, sizeof *fdp, M_FILEDESC);
2216 }
2217
2218 static int
2219 closef_finish(fp, fg, p)
2220 struct fileproc *fp;
2221 struct fileglob *fg;
2222 struct proc *p;
2223 {
2224 struct vnode *vp;
2225 struct flock lf;
2226 int error;
2227 struct vfs_context context;
2228
2229 if ((fg->fg_flag & FHASLOCK) && fg->fg_type == DTYPE_VNODE) {
2230 lf.l_whence = SEEK_SET;
2231 lf.l_start = 0;
2232 lf.l_len = 0;
2233 lf.l_type = F_UNLCK;
2234 vp = (struct vnode *)fg->fg_data;
2235 context.vc_proc = p;
2236 context.vc_ucred = fg->fg_cred;
2237
2238 (void) VNOP_ADVLOCK(vp, (caddr_t)fg, F_UNLCK, &lf, F_FLOCK, &context);
2239 }
2240 if (fg->fg_ops)
2241 error = fo_close(fg, p);
2242 else
2243 error = 0;
2244
2245 if (((fp != (struct fileproc *)0) && ((fp->f_flags & FP_INCHRREAD) != 0))) {
2246 proc_fdlock(p);
2247 if ( ((fp->f_flags & FP_INCHRREAD) != 0) ) {
2248 fileproc_drain(p, fp);
2249 }
2250 proc_fdunlock(p);
2251 }
2252 fg_free(fg);
2253
2254 return (error);
2255 }
2256
2257 int
2258 closef(fg, p)
2259 struct fileglob *fg;
2260 struct proc *p;
2261 {
2262 int error;
2263
2264 proc_fdlock(p);
2265 error = closef_locked((struct fileproc *)0, fg, p);
2266 proc_fdunlock(p);
2267
2268 return(error);
2269 }
2270 /*
2271 * Internal form of close.
2272 * Decrement reference count on file structure.
2273 * Note: p may be NULL when closing a file
2274 * that was being passed in a message.
2275 */
2276 int
2277 closef_locked(fp, fg, p)
2278 struct fileproc *fp;
2279 struct fileglob *fg;
2280 struct proc *p;
2281 {
2282 struct vnode *vp;
2283 struct flock lf;
2284 struct vfs_context context;
2285 int error;
2286
2287 if (fg == NULL) {
2288 return (0);
2289 }
2290 /*
2291 * POSIX record locking dictates that any close releases ALL
2292 * locks owned by this process. This is handled by setting
2293 * a flag in the unlock to free ONLY locks obeying POSIX
2294 * semantics, and not to free BSD-style file locks.
2295 * If the descriptor was in a message, POSIX-style locks
2296 * aren't passed with the descriptor.
2297 */
2298 if (p && (p->p_ladvflag & P_LADVLOCK) && fg->fg_type == DTYPE_VNODE) {
2299 proc_fdunlock(p);
2300
2301 lf.l_whence = SEEK_SET;
2302 lf.l_start = 0;
2303 lf.l_len = 0;
2304 lf.l_type = F_UNLCK;
2305 vp = (struct vnode *)fg->fg_data;
2306
2307 if ( (error = vnode_getwithref(vp)) == 0 ) {
2308 context.vc_proc = p;
2309 context.vc_ucred = fg->fg_cred;
2310 (void) VNOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX, &context);
2311
2312 (void)vnode_put(vp);
2313 }
2314 proc_fdlock(p);
2315 }
2316 lck_mtx_lock(&fg->fg_lock);
2317 fg->fg_count--;
2318
2319 if (fg->fg_count > 0) {
2320 lck_mtx_unlock(&fg->fg_lock);
2321 return (0);
2322 }
2323 if (fg->fg_count != 0)
2324 panic("fg: being freed with bad fg_count (%d)", fg, fg->fg_count);
2325
2326 if (fp && (fp->f_flags & FP_WRITTEN))
2327 fg->fg_flag |= FWASWRITTEN;
2328
2329 fg->fg_lflags |= FG_TERM;
2330 lck_mtx_unlock(&fg->fg_lock);
2331
2332 proc_fdunlock(p);
2333 error = closef_finish(fp, fg, p);
2334 proc_fdlock(p);
2335
2336 return(error);
2337 }
2338
2339
2340 extern int selwait;
2341 void
2342 fileproc_drain(struct proc *p, struct fileproc * fp)
2343 {
2344 fp->f_iocount-- ; /* (the one the close holds) */
2345
2346 while (fp->f_iocount) {
2347 if (((fp->f_flags & FP_INSELECT)== FP_INSELECT)) {
2348 wait_queue_wakeup_all((wait_queue_t)fp->f_waddr, &selwait, THREAD_INTERRUPTED);
2349 } else {
2350 if (fp->f_fglob->fg_ops->fo_drain) {
2351 (*fp->f_fglob->fg_ops->fo_drain)(fp, p);
2352 }
2353 }
2354 p->p_fpdrainwait = 1;
2355
2356 msleep(&p->p_fpdrainwait, &p->p_fdmlock, PRIBIO, "fpdrain",0);
2357
2358 //panic("successful wait after drain\n");
2359 }
2360 }
2361
2362 int
2363 fp_free(struct proc * p, int fd, struct fileproc * fp)
2364 {
2365 proc_fdlock(p);
2366 fdrelse(p, fd);
2367 proc_fdunlock(p);
2368
2369 fg_free(fp->f_fglob);
2370 FREE_ZONE(fp, sizeof *fp, M_FILEPROC);
2371 }
2372
2373
2374 /*
2375 * Apply an advisory lock on a file descriptor.
2376 *
2377 * Just attempt to get a record lock of the requested type on
2378 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
2379 */
2380 int
2381 flock(struct proc *p, register struct flock_args *uap, __unused register_t *retval)
2382 {
2383 int fd = uap->fd;
2384 int how = uap->how;
2385 struct fileproc *fp;
2386 struct vnode *vp;
2387 struct flock lf;
2388 struct vfs_context context;
2389 int error=0;
2390
2391 AUDIT_ARG(fd, uap->fd);
2392 if ( (error = fp_getfvp(p, fd, &fp, &vp)) ) {
2393 return(error);
2394 }
2395 if ( (error = vnode_getwithref(vp)) ) {
2396 goto out1;
2397 }
2398 AUDIT_ARG(vnpath, vp, ARG_VNODE1);
2399
2400 context.vc_proc = p;
2401 context.vc_ucred = fp->f_cred;
2402
2403 lf.l_whence = SEEK_SET;
2404 lf.l_start = 0;
2405 lf.l_len = 0;
2406 if (how & LOCK_UN) {
2407 lf.l_type = F_UNLCK;
2408 fp->f_flag &= ~FHASLOCK;
2409 error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_UNLCK, &lf, F_FLOCK, &context);
2410 goto out;
2411 }
2412 if (how & LOCK_EX)
2413 lf.l_type = F_WRLCK;
2414 else if (how & LOCK_SH)
2415 lf.l_type = F_RDLCK;
2416 else {
2417 error = EBADF;
2418 goto out;
2419 }
2420 fp->f_flag |= FHASLOCK;
2421 if (how & LOCK_NB) {
2422 error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_SETLK, &lf, F_FLOCK, &context);
2423 goto out;
2424 }
2425 error = VNOP_ADVLOCK(vp, (caddr_t)fp->f_fglob, F_SETLK, &lf, F_FLOCK|F_WAIT, &context);
2426 out:
2427 (void)vnode_put(vp);
2428 out1:
2429 fp_drop(p, fd, fp, 0);
2430 return(error);
2431
2432 }
2433
2434 /*
2435 * File Descriptor pseudo-device driver (/dev/fd/).
2436 *
2437 * Opening minor device N dup()s the file (if any) connected to file
2438 * descriptor N belonging to the calling process. Note that this driver
2439 * consists of only the ``open()'' routine, because all subsequent
2440 * references to this file will be direct to the other driver.
2441 */
2442 int
2443 fdopen(dev_t dev, __unused int mode, __unused int type, struct proc *p)
2444 {
2445
2446 /*
2447 * XXX Kludge: set curproc->p_dupfd to contain the value of the
2448 * the file descriptor being sought for duplication. The error
2449 * return ensures that the vnode for this device will be released
2450 * by vn_open. Open will detect this special error and take the
2451 * actions in dupfdopen below. Other callers of vn_open or vnop_open
2452 * will simply report the error.
2453 */
2454 p->p_dupfd = minor(dev);
2455 return (ENODEV);
2456 }
2457
2458 /*
2459 * Duplicate the specified descriptor to a free descriptor.
2460 */
2461 int
2462 dupfdopen(fdp, indx, dfd, mode, error)
2463 register struct filedesc *fdp;
2464 register int indx, dfd;
2465 int mode;
2466 int error;
2467 {
2468 struct fileproc *wfp;
2469 struct fileproc *fp;
2470 struct proc * p = current_proc();
2471
2472 /*
2473 * If the to-be-dup'd fd number is greater than the allowed number
2474 * of file descriptors, or the fd to be dup'd has already been
2475 * closed, reject. Note, check for new == old is necessary as
2476 * falloc could allocate an already closed to-be-dup'd descriptor
2477 * as the new descriptor.
2478 */
2479 proc_fdlock(p);
2480
2481 fp = fdp->fd_ofiles[indx];
2482 if (dfd < 0 || dfd >= fdp->fd_nfiles ||
2483 (wfp = fdp->fd_ofiles[dfd]) == NULL || wfp == fp ||
2484 (fdp->fd_ofileflags[dfd] & UF_RESERVED)) {
2485
2486 proc_fdunlock(p);
2487 return (EBADF);
2488 }
2489 /*
2490 * There are two cases of interest here.
2491 *
2492 * For ENODEV simply dup (dfd) to file descriptor
2493 * (indx) and return.
2494 *
2495 * For ENXIO steal away the file structure from (dfd) and
2496 * store it in (indx). (dfd) is effectively closed by
2497 * this operation.
2498 *
2499 * Any other error code is just returned.
2500 */
2501 switch (error) {
2502 case ENODEV:
2503 /*
2504 * Check that the mode the file is being opened for is a
2505 * subset of the mode of the existing descriptor.
2506 */
2507 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) {
2508 proc_fdunlock(p);
2509 return (EACCES);
2510 }
2511 if (indx > fdp->fd_lastfile)
2512 fdp->fd_lastfile = indx;
2513 (void)fg_ref(wfp);
2514
2515 if (fp->f_fglob)
2516 fg_free(fp->f_fglob);
2517 fp->f_fglob = wfp->f_fglob;
2518
2519 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
2520
2521 proc_fdunlock(p);
2522 return (0);
2523
2524 case ENXIO:
2525 /*
2526 * Steal away the file pointer from dfd, and stuff it into indx.
2527 */
2528 if (indx > fdp->fd_lastfile)
2529 fdp->fd_lastfile = indx;
2530
2531 if (fp->f_fglob)
2532 fg_free(fp->f_fglob);
2533 fp->f_fglob = wfp->f_fglob;
2534
2535 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
2536 _fdrelse(fdp, dfd);
2537
2538 proc_fdunlock(p);
2539
2540 FREE_ZONE(wfp, sizeof *fp, M_FILEPROC);
2541
2542 return (0);
2543
2544 default:
2545 proc_fdunlock(p);
2546 return (error);
2547 }
2548 /* NOTREACHED */
2549 }
2550
2551 void
2552 fg_ref(struct fileproc * fp)
2553 {
2554 struct fileglob *fg;
2555
2556 fg = fp->f_fglob;
2557
2558 lck_mtx_lock(&fg->fg_lock);
2559 fg->fg_count++;
2560 lck_mtx_unlock(&fg->fg_lock);
2561 }
2562
2563 void
2564 fg_drop(struct fileproc * fp)
2565 {
2566 struct fileglob *fg;
2567
2568 fg = fp->f_fglob;
2569 lck_mtx_lock(&fg->fg_lock);
2570 fg->fg_count--;
2571 lck_mtx_unlock(&fg->fg_lock);
2572 }
2573
2574
2575 void
2576 fg_insertuipc(struct fileglob * fg)
2577 {
2578 int insertque = 0;
2579
2580 lck_mtx_lock(&fg->fg_lock);
2581
2582 while (fg->fg_lflags & FG_RMMSGQ) {
2583 fg->fg_lflags |= FG_WRMMSGQ;
2584 msleep(&fg->fg_lflags, &fg->fg_lock, 0, "fg_insertuipc", 0);
2585 }
2586
2587 fg->fg_count++;
2588 fg->fg_msgcount++;
2589 if (fg->fg_msgcount == 1) {
2590 fg->fg_lflags |= FG_INSMSGQ;
2591 insertque=1;
2592 }
2593 lck_mtx_unlock(&fg->fg_lock);
2594
2595 if (insertque) {
2596 lck_mtx_lock(uipc_lock);
2597 LIST_INSERT_HEAD(&fmsghead, fg, f_msglist);
2598 lck_mtx_unlock(uipc_lock);
2599 lck_mtx_lock(&fg->fg_lock);
2600 fg->fg_lflags &= ~FG_INSMSGQ;
2601 if (fg->fg_lflags & FG_WINSMSGQ) {
2602 fg->fg_lflags &= ~FG_WINSMSGQ;
2603 wakeup(&fg->fg_lflags);
2604 }
2605 lck_mtx_unlock(&fg->fg_lock);
2606 }
2607
2608 }
2609
2610 void
2611 fg_removeuipc(struct fileglob * fg)
2612 {
2613 int removeque = 0;
2614
2615 lck_mtx_lock(&fg->fg_lock);
2616 while (fg->fg_lflags & FG_INSMSGQ) {
2617 fg->fg_lflags |= FG_WINSMSGQ;
2618 msleep(&fg->fg_lflags, &fg->fg_lock, 0, "fg_removeuipc", 0);
2619 }
2620 fg->fg_msgcount--;
2621 if (fg->fg_msgcount == 0) {
2622 fg->fg_lflags |= FG_RMMSGQ;
2623 removeque=1;
2624 }
2625 lck_mtx_unlock(&fg->fg_lock);
2626
2627 if (removeque) {
2628 lck_mtx_lock(uipc_lock);
2629 LIST_REMOVE(fg, f_msglist);
2630 lck_mtx_unlock(uipc_lock);
2631 lck_mtx_lock(&fg->fg_lock);
2632 fg->fg_lflags &= ~FG_RMMSGQ;
2633 if (fg->fg_lflags & FG_WRMMSGQ) {
2634 fg->fg_lflags &= ~FG_WRMMSGQ;
2635 wakeup(&fg->fg_lflags);
2636 }
2637 lck_mtx_unlock(&fg->fg_lock);
2638 }
2639 }
2640
2641
2642 int
2643 fo_read(struct fileproc *fp, struct uio *uio, kauth_cred_t cred, int flags, struct proc *p)
2644 {
2645 return ((*fp->f_ops->fo_read)(fp, uio, cred, flags, p));
2646 }
2647
2648 int
2649 fo_write(struct fileproc *fp, struct uio *uio, kauth_cred_t cred, int flags, struct proc *p)
2650 {
2651 return((*fp->f_ops->fo_write)(fp, uio, cred, flags, p));
2652 }
2653
2654 int
2655 fo_ioctl(struct fileproc *fp, u_long com, caddr_t data, struct proc *p)
2656 {
2657 int error;
2658
2659 proc_fdunlock(p);
2660 error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
2661 proc_fdlock(p);
2662 return(error);
2663 }
2664
2665 int
2666 fo_select(struct fileproc *fp, int which, void *wql, struct proc *p)
2667 {
2668 return((*fp->f_ops->fo_select)(fp, which, wql, p));
2669 }
2670
2671 int
2672 fo_close(struct fileglob *fg, struct proc *p)
2673 {
2674 return((*fg->fg_ops->fo_close)(fg, p));
2675 }
2676
2677 int
2678 fo_kqfilter(struct fileproc *fp, struct knote *kn, struct proc *p)
2679 {
2680 return ((*fp->f_ops->fo_kqfilter)(fp, kn, p));
2681 }
2682