1 /*
2 * Copyright (c) 1982, 1986, 1989, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94
39 * $FreeBSD$
40 */
41
42 #include "opt_compat.h"
43 #include "opt_devfs.h"
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/sysproto.h>
48 #include <sys/conf.h>
49 #include <sys/filedesc.h>
50 #include <sys/kernel.h>
51 #include <sys/sysctl.h>
52 #include <sys/vnode.h>
53 #include <sys/proc.h>
54 #include <sys/file.h>
55 #include <sys/socketvar.h>
56 #include <sys/stat.h>
57 #include <sys/filio.h>
58 #include <sys/ttycom.h>
59 #include <sys/fcntl.h>
60 #include <sys/malloc.h>
61 #include <sys/unistd.h>
62 #include <sys/resourcevar.h>
63 #include <sys/pipe.h>
64
65 #include <vm/vm.h>
66 #include <vm/vm_extern.h>
67
68 #ifdef DEVFS
69 #include <sys/devfsext.h>
70 #endif /*DEVFS*/
71
72 static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
73 MALLOC_DEFINE(M_FILE, "file", "Open file structure");
74 static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
75
76
77 static d_open_t fdopen;
78 #define NUMFDESC 64
79
80 #define CDEV_MAJOR 22
81 static struct cdevsw fildesc_cdevsw =
82 { fdopen, noclose, noread, nowrite,
83 noioc, nostop, nullreset, nodevtotty,
84 seltrue, nommap, nostrat };
85
86 static int finishdup __P((struct filedesc *fdp, int old, int new, register_t *retval));
87 /*
88 * Descriptor management.
89 */
90 struct filelist filehead; /* head of list of open files */
91 int nfiles; /* actual number of open files */
92 extern int cmask;
93
94 /*
95 * System calls on descriptors.
96 */
97 #ifndef _SYS_SYSPROTO_H_
98 struct getdtablesize_args {
99 int dummy;
100 };
101 #endif
102 /* ARGSUSED */
103 int
104 getdtablesize(p, uap)
105 struct proc *p;
106 struct getdtablesize_args *uap;
107 {
108
109 p->p_retval[0] =
110 min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
111 return (0);
112 }
113
114 /*
115 * Duplicate a file descriptor to a particular value.
116 */
117 #ifndef _SYS_SYSPROTO_H_
118 struct dup2_args {
119 u_int from;
120 u_int to;
121 };
122 #endif
123 /* ARGSUSED */
124 int
125 dup2(p, uap)
126 struct proc *p;
127 struct dup2_args *uap;
128 {
129 register struct filedesc *fdp = p->p_fd;
130 register u_int old = uap->from, new = uap->to;
131 int i, error;
132
133 if (old >= fdp->fd_nfiles ||
134 fdp->fd_ofiles[old] == NULL ||
135 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
136 new >= maxfilesperproc)
137 return (EBADF);
138 if (old == new) {
139 p->p_retval[0] = new;
140 return (0);
141 }
142 if (new >= fdp->fd_nfiles) {
143 if ((error = fdalloc(p, new, &i)))
144 return (error);
145 if (new != i)
146 panic("dup2: fdalloc");
147 } else if (fdp->fd_ofiles[new]) {
148 if (fdp->fd_ofileflags[new] & UF_MAPPED)
149 (void) munmapfd(p, new);
150 /*
151 * dup2() must succeed even if the close has an error.
152 */
153 (void) closef(fdp->fd_ofiles[new], p);
154 }
155 return (finishdup(fdp, (int)old, (int)new, p->p_retval));
156 }
157
158 /*
159 * Duplicate a file descriptor.
160 */
161 #ifndef _SYS_SYSPROTO_H_
162 struct dup_args {
163 u_int fd;
164 };
165 #endif
166 /* ARGSUSED */
167 int
168 dup(p, uap)
169 struct proc *p;
170 struct dup_args *uap;
171 {
172 register struct filedesc *fdp;
173 u_int old;
174 int new, error;
175
176 old = uap->fd;
177
178 #if 0
179 /*
180 * XXX Compatibility
181 */
182 if (old &~ 077) { uap->fd &= 077; return (dup2(p, uap, p->p_retval)); }
183 #endif
184
185 fdp = p->p_fd;
186 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL)
187 return (EBADF);
188 if ((error = fdalloc(p, 0, &new)))
189 return (error);
190 return (finishdup(fdp, (int)old, new, p->p_retval));
191 }
192
193 /*
194 * The file control system call.
195 */
196 #ifndef _SYS_SYSPROTO_H_
197 struct fcntl_args {
198 int fd;
199 int cmd;
200 long arg;
201 };
202 #endif
203 /* ARGSUSED */
204 int
205 fcntl(p, uap)
206 struct proc *p;
207 register struct fcntl_args *uap;
208 {
209 register struct filedesc *fdp = p->p_fd;
210 register struct file *fp;
211 register char *pop;
212 struct vnode *vp;
213 int i, tmp, error, flg = F_POSIX;
214 struct flock fl;
215 u_int newmin;
216
217 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
218 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
219 return (EBADF);
220 pop = &fdp->fd_ofileflags[uap->fd];
221 switch (uap->cmd) {
222
223 case F_DUPFD:
224 newmin = uap->arg;
225 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
226 newmin >= maxfilesperproc)
227 return (EINVAL);
228 if ((error = fdalloc(p, newmin, &i)))
229 return (error);
230 return (finishdup(fdp, uap->fd, i, p->p_retval));
231
232 case F_GETFD:
233 p->p_retval[0] = *pop & 1;
234 return (0);
235
236 case F_SETFD:
237 *pop = (*pop &~ 1) | (uap->arg & 1);
238 return (0);
239
240 case F_GETFL:
241 p->p_retval[0] = OFLAGS(fp->f_flag);
242 return (0);
243
244 case F_SETFL:
245 fp->f_flag &= ~FCNTLFLAGS;
246 fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS;
247 tmp = fp->f_flag & FNONBLOCK;
248 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
249 if (error)
250 return (error);
251 tmp = fp->f_flag & FASYNC;
252 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
253 if (!error)
254 return (0);
255 fp->f_flag &= ~FNONBLOCK;
256 tmp = 0;
257 (void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
258 return (error);
259
260 case F_GETOWN:
261 error = (*fp->f_ops->fo_ioctl)
262 (fp, FIOGETOWN, (caddr_t)p->p_retval, p);
263 return (error);
264
265 case F_SETOWN:
266 return ((*fp->f_ops->fo_ioctl)
267 (fp, FIOSETOWN, (caddr_t)&uap->arg, p));
268
269 case F_SETLKW:
270 flg |= F_WAIT;
271 /* Fall into F_SETLK */
272
273 case F_SETLK:
274 if (fp->f_type != DTYPE_VNODE)
275 return (EBADF);
276 vp = (struct vnode *)fp->f_data;
277 /* Copy in the lock structure */
278 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
279 sizeof(fl));
280 if (error)
281 return (error);
282 if (fl.l_whence == SEEK_CUR)
283 fl.l_start += fp->f_offset;
284 switch (fl.l_type) {
285
286 case F_RDLCK:
287 if ((fp->f_flag & FREAD) == 0)
288 return (EBADF);
289 p->p_flag |= P_ADVLOCK;
290 return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg));
291
292 case F_WRLCK:
293 if ((fp->f_flag & FWRITE) == 0)
294 return (EBADF);
295 p->p_flag |= P_ADVLOCK;
296 return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg));
297
298 case F_UNLCK:
299 return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &fl,
300 F_POSIX));
301
302 default:
303 return (EINVAL);
304 }
305
306 case F_GETLK:
307 if (fp->f_type != DTYPE_VNODE)
308 return (EBADF);
309 vp = (struct vnode *)fp->f_data;
310 /* Copy in the lock structure */
311 error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl,
312 sizeof(fl));
313 if (error)
314 return (error);
315 if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK &&
316 fl.l_type != F_UNLCK)
317 return (EINVAL);
318 if (fl.l_whence == SEEK_CUR)
319 fl.l_start += fp->f_offset;
320 if ((error = VOP_ADVLOCK(vp,(caddr_t)p->p_leader,F_GETLK,&fl,F_POSIX)))
321 return (error);
322 return (copyout((caddr_t)&fl, (caddr_t)(intptr_t)uap->arg,
323 sizeof(fl)));
324
325 default:
326 return (EINVAL);
327 }
328 /* NOTREACHED */
329 }
330
331 /*
332 * Common code for dup, dup2, and fcntl(F_DUPFD).
333 */
334 static int
335 finishdup(fdp, old, new, retval)
336 register struct filedesc *fdp;
337 register int old, new;
338 register_t *retval;
339 {
340 register struct file *fp;
341
342 fp = fdp->fd_ofiles[old];
343 fdp->fd_ofiles[new] = fp;
344 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE;
345 fp->f_count++;
346 if (new > fdp->fd_lastfile)
347 fdp->fd_lastfile = new;
348 *retval = new;
349 return (0);
350 }
351
352 /*
353 * If sigio is on the list associated with a process or process group,
354 * disable signalling from the device, remove sigio from the list and
355 * free sigio.
356 */
357 void
358 funsetown(sigio)
359 struct sigio *sigio;
360 {
361 int s;
362
363 if (sigio == NULL)
364 return;
365 s = splhigh();
366 *(sigio->sio_myref) = NULL;
367 splx(s);
368 if (sigio->sio_pgid < 0) {
369 SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio,
370 sigio, sio_pgsigio);
371 } else /* if ((*sigiop)->sio_pgid > 0) */ {
372 SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio,
373 sigio, sio_pgsigio);
374 }
375 crfree(sigio->sio_ucred);
376 FREE(sigio, M_SIGIO);
377 }
378
379 /* Free a list of sigio structures. */
380 void
381 funsetownlst(sigiolst)
382 struct sigiolst *sigiolst;
383 {
384 struct sigio *sigio;
385
386 while ((sigio = sigiolst->slh_first) != NULL)
387 funsetown(sigio);
388 }
389
390 /*
391 * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg).
392 *
393 * After permission checking, add a sigio structure to the sigio list for
394 * the process or process group.
395 */
396 int
397 fsetown(pgid, sigiop)
398 pid_t pgid;
399 struct sigio **sigiop;
400 {
401 struct proc *proc;
402 struct pgrp *pgrp;
403 struct sigio *sigio;
404 int s;
405
406 if (pgid == 0) {
407 funsetown(*sigiop);
408 return (0);
409 }
410 if (pgid > 0) {
411 proc = pfind(pgid);
412 if (proc == NULL)
413 return (ESRCH);
414 /*
415 * Policy - Don't allow a process to FSETOWN a process
416 * in another session.
417 *
418 * Remove this test to allow maximum flexibility or
419 * restrict FSETOWN to the current process or process
420 * group for maximum safety.
421 */
422 else if (proc->p_session != curproc->p_session)
423 return (EPERM);
424 pgrp = NULL;
425 } else /* if (pgid < 0) */ {
426 pgrp = pgfind(-pgid);
427 if (pgrp == NULL)
428 return (ESRCH);
429 /*
430 * Policy - Don't allow a process to FSETOWN a process
431 * in another session.
432 *
433 * Remove this test to allow maximum flexibility or
434 * restrict FSETOWN to the current process or process
435 * group for maximum safety.
436 */
437 else if (pgrp->pg_session != curproc->p_session)
438 return (EPERM);
439 proc = NULL;
440 }
441 funsetown(*sigiop);
442 MALLOC(sigio, struct sigio *, sizeof(struct sigio), M_SIGIO,
443 M_WAITOK);
444 if (pgid > 0) {
445 SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio);
446 sigio->sio_proc = proc;
447 } else {
448 SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio);
449 sigio->sio_pgrp = pgrp;
450 }
451 sigio->sio_pgid = pgid;
452 crhold(curproc->p_ucred);
453 sigio->sio_ucred = curproc->p_ucred;
454 /* It would be convenient if p_ruid was in ucred. */
455 sigio->sio_ruid = curproc->p_cred->p_ruid;
456 sigio->sio_myref = sigiop;
457 s = splhigh();
458 *sigiop = sigio;
459 splx(s);
460 return (0);
461 }
462
463 /*
464 * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg).
465 */
466 pid_t
467 fgetown(sigio)
468 struct sigio *sigio;
469 {
470 return (sigio != NULL ? sigio->sio_pgid : 0);
471 }
472
473 /*
474 * Close a file descriptor.
475 */
476 #ifndef _SYS_SYSPROTO_H_
477 struct close_args {
478 int fd;
479 };
480 #endif
481 /* ARGSUSED */
482 int
483 close(p, uap)
484 struct proc *p;
485 struct close_args *uap;
486 {
487 register struct filedesc *fdp = p->p_fd;
488 register struct file *fp;
489 register int fd = uap->fd;
490 register u_char *pf;
491
492 if ((unsigned)fd >= fdp->fd_nfiles ||
493 (fp = fdp->fd_ofiles[fd]) == NULL)
494 return (EBADF);
495 pf = (u_char *)&fdp->fd_ofileflags[fd];
496 if (*pf & UF_MAPPED)
497 (void) munmapfd(p, fd);
498 fdp->fd_ofiles[fd] = NULL;
499 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
500 fdp->fd_lastfile--;
501 if (fd < fdp->fd_freefile)
502 fdp->fd_freefile = fd;
503 *pf = 0;
504 return (closef(fp, p));
505 }
506
507 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
508 /*
509 * Return status information about a file descriptor.
510 */
511 #ifndef _SYS_SYSPROTO_H_
512 struct ofstat_args {
513 int fd;
514 struct ostat *sb;
515 };
516 #endif
517 /* ARGSUSED */
518 int
519 ofstat(p, uap)
520 struct proc *p;
521 register struct ofstat_args *uap;
522 {
523 register struct filedesc *fdp = p->p_fd;
524 register struct file *fp;
525 struct stat ub;
526 struct ostat oub;
527 int error;
528
529 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
530 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
531 return (EBADF);
532 switch (fp->f_type) {
533
534 case DTYPE_FIFO:
535 case DTYPE_VNODE:
536 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
537 break;
538
539 case DTYPE_SOCKET:
540 error = soo_stat((struct socket *)fp->f_data, &ub);
541 break;
542
543 case DTYPE_PIPE:
544 error = pipe_stat((struct pipe *)fp->f_data, &ub);
545 break;
546
547 default:
548 panic("ofstat");
549 /*NOTREACHED*/
550 }
551 if (error == 0) {
552 cvtstat(&ub, &oub);
553 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
554 }
555 return (error);
556 }
557 #endif /* COMPAT_43 || COMPAT_SUNOS */
558
559 /*
560 * Return status information about a file descriptor.
561 */
562 #ifndef _SYS_SYSPROTO_H_
563 struct fstat_args {
564 int fd;
565 struct stat *sb;
566 };
567 #endif
568 /* ARGSUSED */
569 int
570 fstat(p, uap)
571 struct proc *p;
572 register struct fstat_args *uap;
573 {
574 register struct filedesc *fdp = p->p_fd;
575 register struct file *fp;
576 struct stat ub;
577 int error;
578
579 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
580 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
581 return (EBADF);
582 switch (fp->f_type) {
583
584 case DTYPE_FIFO:
585 case DTYPE_VNODE:
586 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
587 break;
588
589 case DTYPE_SOCKET:
590 error = soo_stat((struct socket *)fp->f_data, &ub);
591 break;
592
593 case DTYPE_PIPE:
594 error = pipe_stat((struct pipe *)fp->f_data, &ub);
595 break;
596
597 default:
598 panic("fstat");
599 /*NOTREACHED*/
600 }
601 if (error == 0)
602 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
603 return (error);
604 }
605
606 /*
607 * Return status information about a file descriptor.
608 */
609 #ifndef _SYS_SYSPROTO_H_
610 struct nfstat_args {
611 int fd;
612 struct nstat *sb;
613 };
614 #endif
615 /* ARGSUSED */
616 int
617 nfstat(p, uap)
618 struct proc *p;
619 register struct nfstat_args *uap;
620 {
621 register struct filedesc *fdp = p->p_fd;
622 register struct file *fp;
623 struct stat ub;
624 struct nstat nub;
625 int error;
626
627 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
628 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
629 return (EBADF);
630 switch (fp->f_type) {
631
632 case DTYPE_FIFO:
633 case DTYPE_VNODE:
634 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
635 break;
636
637 case DTYPE_SOCKET:
638 error = soo_stat((struct socket *)fp->f_data, &ub);
639 break;
640
641 case DTYPE_PIPE:
642 error = pipe_stat((struct pipe *)fp->f_data, &ub);
643 break;
644
645 default:
646 panic("fstat");
647 /*NOTREACHED*/
648 }
649 if (error == 0) {
650 cvtnstat(&ub, &nub);
651 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
652 }
653 return (error);
654 }
655
656 /*
657 * Return pathconf information about a file descriptor.
658 */
659 #ifndef _SYS_SYSPROTO_H_
660 struct fpathconf_args {
661 int fd;
662 int name;
663 };
664 #endif
665 /* ARGSUSED */
666 int
667 fpathconf(p, uap)
668 struct proc *p;
669 register struct fpathconf_args *uap;
670 {
671 struct filedesc *fdp = p->p_fd;
672 struct file *fp;
673 struct vnode *vp;
674
675 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
676 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
677 return (EBADF);
678 switch (fp->f_type) {
679
680 case DTYPE_PIPE:
681 case DTYPE_SOCKET:
682 if (uap->name != _PC_PIPE_BUF)
683 return (EINVAL);
684 p->p_retval[0] = PIPE_BUF;
685 return (0);
686
687 case DTYPE_FIFO:
688 case DTYPE_VNODE:
689 vp = (struct vnode *)fp->f_data;
690 return (VOP_PATHCONF(vp, uap->name, p->p_retval));
691
692 default:
693 panic("fpathconf");
694 }
695 /*NOTREACHED*/
696 }
697
698 /*
699 * Allocate a file descriptor for the process.
700 */
701 static int fdexpand;
702 SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
703
704 int
705 fdalloc(p, want, result)
706 struct proc *p;
707 int want;
708 int *result;
709 {
710 register struct filedesc *fdp = p->p_fd;
711 register int i;
712 int lim, last, nfiles;
713 struct file **newofile;
714 char *newofileflags;
715
716 /*
717 * Search for a free descriptor starting at the higher
718 * of want or fd_freefile. If that fails, consider
719 * expanding the ofile array.
720 */
721 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
722 for (;;) {
723 last = min(fdp->fd_nfiles, lim);
724 if ((i = want) < fdp->fd_freefile)
725 i = fdp->fd_freefile;
726 for (; i < last; i++) {
727 if (fdp->fd_ofiles[i] == NULL) {
728 fdp->fd_ofileflags[i] = 0;
729 if (i > fdp->fd_lastfile)
730 fdp->fd_lastfile = i;
731 if (want <= fdp->fd_freefile)
732 fdp->fd_freefile = i;
733 *result = i;
734 return (0);
735 }
736 }
737
738 /*
739 * No space in current array. Expand?
740 */
741 if (fdp->fd_nfiles >= lim)
742 return (EMFILE);
743 if (fdp->fd_nfiles < NDEXTENT)
744 nfiles = NDEXTENT;
745 else
746 nfiles = 2 * fdp->fd_nfiles;
747 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
748 M_FILEDESC, M_WAITOK);
749 newofileflags = (char *) &newofile[nfiles];
750 /*
751 * Copy the existing ofile and ofileflags arrays
752 * and zero the new portion of each array.
753 */
754 bcopy(fdp->fd_ofiles, newofile,
755 (i = sizeof(struct file *) * fdp->fd_nfiles));
756 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
757 bcopy(fdp->fd_ofileflags, newofileflags,
758 (i = sizeof(char) * fdp->fd_nfiles));
759 bzero(newofileflags + i, nfiles * sizeof(char) - i);
760 if (fdp->fd_nfiles > NDFILE)
761 FREE(fdp->fd_ofiles, M_FILEDESC);
762 fdp->fd_ofiles = newofile;
763 fdp->fd_ofileflags = newofileflags;
764 fdp->fd_nfiles = nfiles;
765 fdexpand++;
766 }
767 return (0);
768 }
769
770 /*
771 * Check to see whether n user file descriptors
772 * are available to the process p.
773 */
774 int
775 fdavail(p, n)
776 struct proc *p;
777 register int n;
778 {
779 register struct filedesc *fdp = p->p_fd;
780 register struct file **fpp;
781 register int i, lim, last;
782
783 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
784 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
785 return (1);
786
787 last = min(fdp->fd_nfiles, lim);
788 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
789 for (i = last - fdp->fd_freefile; --i >= 0; fpp++)
790 if (*fpp == NULL && --n <= 0)
791 return (1);
792 return (0);
793 }
794
795 /*
796 * Create a new open file structure and allocate
797 * a file decriptor for the process that refers to it.
798 */
799 int
800 falloc(p, resultfp, resultfd)
801 register struct proc *p;
802 struct file **resultfp;
803 int *resultfd;
804 {
805 register struct file *fp, *fq;
806 int error, i;
807
808 if ((error = fdalloc(p, 0, &i)))
809 return (error);
810 if (nfiles >= maxfiles) {
811 tablefull("file");
812 return (ENFILE);
813 }
814 /*
815 * Allocate a new file descriptor.
816 * If the process has file descriptor zero open, add to the list
817 * of open files at that point, otherwise put it at the front of
818 * the list of open files.
819 */
820 nfiles++;
821 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
822 bzero(fp, sizeof(struct file));
823 if ((fq = p->p_fd->fd_ofiles[0])) {
824 LIST_INSERT_AFTER(fq, fp, f_list);
825 } else {
826 LIST_INSERT_HEAD(&filehead, fp, f_list);
827 }
828 p->p_fd->fd_ofiles[i] = fp;
829 fp->f_count = 1;
830 fp->f_cred = p->p_ucred;
831 fp->f_seqcount = 1;
832 crhold(fp->f_cred);
833 if (resultfp)
834 *resultfp = fp;
835 if (resultfd)
836 *resultfd = i;
837 return (0);
838 }
839
840 /*
841 * Free a file descriptor.
842 */
843 void
844 ffree(fp)
845 register struct file *fp;
846 {
847 LIST_REMOVE(fp, f_list);
848 crfree(fp->f_cred);
849 #if defined(DIAGNOSTIC) || defined(INVARIANTS)
850 fp->f_count = 0;
851 #endif
852 nfiles--;
853 FREE(fp, M_FILE);
854 }
855
856 /*
857 * Build a new filedesc structure.
858 */
859 struct filedesc *
860 fdinit(p)
861 struct proc *p;
862 {
863 register struct filedesc0 *newfdp;
864 register struct filedesc *fdp = p->p_fd;
865
866 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
867 M_FILEDESC, M_WAITOK);
868 bzero(newfdp, sizeof(struct filedesc0));
869 newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
870 VREF(newfdp->fd_fd.fd_cdir);
871 newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
872 VREF(newfdp->fd_fd.fd_rdir);
873
874 /* Create the file descriptor table. */
875 newfdp->fd_fd.fd_refcnt = 1;
876 newfdp->fd_fd.fd_cmask = cmask;
877 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
878 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
879 newfdp->fd_fd.fd_nfiles = NDFILE;
880
881 newfdp->fd_fd.fd_freefile = 0;
882 newfdp->fd_fd.fd_lastfile = 0;
883
884 return (&newfdp->fd_fd);
885 }
886
887 /*
888 * Share a filedesc structure.
889 */
890 struct filedesc *
891 fdshare(p)
892 struct proc *p;
893 {
894 p->p_fd->fd_refcnt++;
895 return (p->p_fd);
896 }
897
898 /*
899 * Copy a filedesc structure.
900 */
901 struct filedesc *
902 fdcopy(p)
903 struct proc *p;
904 {
905 register struct filedesc *newfdp, *fdp = p->p_fd;
906 register struct file **fpp;
907 register int i;
908
909 /*
910 * Certain daemons might not have file descriptors
911 */
912 if (fdp == NULL)
913 return NULL;
914
915 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
916 M_FILEDESC, M_WAITOK);
917 bcopy(fdp, newfdp, sizeof(struct filedesc));
918 VREF(newfdp->fd_cdir);
919 VREF(newfdp->fd_rdir);
920 newfdp->fd_refcnt = 1;
921
922 /*
923 * If the number of open files fits in the internal arrays
924 * of the open file structure, use them, otherwise allocate
925 * additional memory for the number of descriptors currently
926 * in use.
927 */
928 if (newfdp->fd_lastfile < NDFILE) {
929 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
930 newfdp->fd_ofileflags =
931 ((struct filedesc0 *) newfdp)->fd_dfileflags;
932 i = NDFILE;
933 } else {
934 /*
935 * Compute the smallest multiple of NDEXTENT needed
936 * for the file descriptors currently in use,
937 * allowing the table to shrink.
938 */
939 i = newfdp->fd_nfiles;
940 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
941 i /= 2;
942 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
943 M_FILEDESC, M_WAITOK);
944 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
945 }
946 newfdp->fd_nfiles = i;
947 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
948 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
949 fpp = newfdp->fd_ofiles;
950 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++)
951 if (*fpp != NULL)
952 (*fpp)->f_count++;
953 return (newfdp);
954 }
955
956 /*
957 * Release a filedesc structure.
958 */
959 void
960 fdfree(p)
961 struct proc *p;
962 {
963 register struct filedesc *fdp = p->p_fd;
964 struct file **fpp;
965 register int i;
966
967 /*
968 * Certain daemons might not have file descriptors
969 */
970 if (fdp == NULL)
971 return;
972
973 if (--fdp->fd_refcnt > 0)
974 return;
975 fpp = fdp->fd_ofiles;
976 for (i = fdp->fd_lastfile; i-- >= 0; fpp++)
977 if (*fpp)
978 (void) closef(*fpp, p);
979 if (fdp->fd_nfiles > NDFILE)
980 FREE(fdp->fd_ofiles, M_FILEDESC);
981 vrele(fdp->fd_cdir);
982 vrele(fdp->fd_rdir);
983 FREE(fdp, M_FILEDESC);
984 }
985
986 /*
987 * For setugid programs, we don't want to people to use that setugidness
988 * to generate error messages which write to a file which otherwise would
989 * otherwise be off-limits to the process.
990 *
991 * This is a gross hack to plug the hole. A better solution would involve
992 * a special vop or other form of generalized access control mechanism. We
993 * go ahead and just reject all procfs file systems accesses as dangerous.
994 *
995 * Since setugidsafety calls this only for fd 0, 1 and 2, this check is
996 * sufficient. We also don't for check setugidness since we know we are.
997 */
998 static int
999 is_unsafe(struct file *fp)
1000 {
1001 if (fp->f_type == DTYPE_VNODE &&
1002 ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS)
1003 return (1);
1004 return (0);
1005 }
1006
1007 /*
1008 * Make this setguid thing safe, if at all possible.
1009 */
1010 void
1011 setugidsafety(p)
1012 struct proc *p;
1013 {
1014 struct filedesc *fdp = p->p_fd;
1015 struct file **fpp;
1016 char *fdfp;
1017 register int i;
1018
1019 /* Certain daemons might not have file descriptors. */
1020 if (fdp == NULL)
1021 return;
1022
1023 fpp = fdp->fd_ofiles;
1024 fdfp = fdp->fd_ofileflags;
1025 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) {
1026 if (i > 2)
1027 break;
1028 if (*fpp != NULL && is_unsafe(*fpp)) {
1029 if ((*fdfp & UF_MAPPED) != 0)
1030 (void) munmapfd(p, i);
1031 (void) closef(*fpp, p);
1032 *fpp = NULL;
1033 *fdfp = 0;
1034 if (i < fdp->fd_freefile)
1035 fdp->fd_freefile = i;
1036 }
1037 }
1038 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1039 fdp->fd_lastfile--;
1040 }
1041
1042 /*
1043 * Close any files on exec?
1044 */
1045 void
1046 fdcloseexec(p)
1047 struct proc *p;
1048 {
1049 struct filedesc *fdp = p->p_fd;
1050 struct file **fpp;
1051 char *fdfp;
1052 register int i;
1053
1054 /*
1055 * Certain daemons might not have file descriptors
1056 */
1057 if (fdp == NULL)
1058 return;
1059
1060 fpp = fdp->fd_ofiles;
1061 fdfp = fdp->fd_ofileflags;
1062 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++)
1063 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) {
1064 if (*fdfp & UF_MAPPED)
1065 (void) munmapfd(p, i);
1066 (void) closef(*fpp, p);
1067 *fpp = NULL;
1068 *fdfp = 0;
1069 if (i < fdp->fd_freefile)
1070 fdp->fd_freefile = i;
1071 }
1072 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1073 fdp->fd_lastfile--;
1074 }
1075
1076 /*
1077 * Internal form of close.
1078 * Decrement reference count on file structure.
1079 * Note: p may be NULL when closing a file
1080 * that was being passed in a message.
1081 */
1082 int
1083 closef(fp, p)
1084 register struct file *fp;
1085 register struct proc *p;
1086 {
1087 struct vnode *vp;
1088 struct flock lf;
1089 int error;
1090
1091 if (fp == NULL)
1092 return (0);
1093 /*
1094 * POSIX record locking dictates that any close releases ALL
1095 * locks owned by this process. This is handled by setting
1096 * a flag in the unlock to free ONLY locks obeying POSIX
1097 * semantics, and not to free BSD-style file locks.
1098 * If the descriptor was in a message, POSIX-style locks
1099 * aren't passed with the descriptor.
1100 */
1101 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
1102 lf.l_whence = SEEK_SET;
1103 lf.l_start = 0;
1104 lf.l_len = 0;
1105 lf.l_type = F_UNLCK;
1106 vp = (struct vnode *)fp->f_data;
1107 (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &lf, F_POSIX);
1108 }
1109 if (--fp->f_count > 0)
1110 return (0);
1111 if (fp->f_count < 0)
1112 panic("closef: count < 0");
1113 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1114 lf.l_whence = SEEK_SET;
1115 lf.l_start = 0;
1116 lf.l_len = 0;
1117 lf.l_type = F_UNLCK;
1118 vp = (struct vnode *)fp->f_data;
1119 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1120 }
1121 if (fp->f_ops)
1122 error = (*fp->f_ops->fo_close)(fp, p);
1123 else
1124 error = 0;
1125 ffree(fp);
1126 return (error);
1127 }
1128
1129 /*
1130 * Apply an advisory lock on a file descriptor.
1131 *
1132 * Just attempt to get a record lock of the requested type on
1133 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1134 */
1135 #ifndef _SYS_SYSPROTO_H_
1136 struct flock_args {
1137 int fd;
1138 int how;
1139 };
1140 #endif
1141 /* ARGSUSED */
1142 int
1143 flock(p, uap)
1144 struct proc *p;
1145 register struct flock_args *uap;
1146 {
1147 register struct filedesc *fdp = p->p_fd;
1148 register struct file *fp;
1149 struct vnode *vp;
1150 struct flock lf;
1151
1152 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1153 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1154 return (EBADF);
1155 if (fp->f_type != DTYPE_VNODE)
1156 return (EOPNOTSUPP);
1157 vp = (struct vnode *)fp->f_data;
1158 lf.l_whence = SEEK_SET;
1159 lf.l_start = 0;
1160 lf.l_len = 0;
1161 if (uap->how & LOCK_UN) {
1162 lf.l_type = F_UNLCK;
1163 fp->f_flag &= ~FHASLOCK;
1164 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
1165 }
1166 if (uap->how & LOCK_EX)
1167 lf.l_type = F_WRLCK;
1168 else if (uap->how & LOCK_SH)
1169 lf.l_type = F_RDLCK;
1170 else
1171 return (EBADF);
1172 fp->f_flag |= FHASLOCK;
1173 if (uap->how & LOCK_NB)
1174 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
1175 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
1176 }
1177
1178 /*
1179 * File Descriptor pseudo-device driver (/dev/fd/).
1180 *
1181 * Opening minor device N dup()s the file (if any) connected to file
1182 * descriptor N belonging to the calling process. Note that this driver
1183 * consists of only the ``open()'' routine, because all subsequent
1184 * references to this file will be direct to the other driver.
1185 */
1186 /* ARGSUSED */
1187 static int
1188 fdopen(dev, mode, type, p)
1189 dev_t dev;
1190 int mode, type;
1191 struct proc *p;
1192 {
1193
1194 /*
1195 * XXX Kludge: set curproc->p_dupfd to contain the value of the
1196 * the file descriptor being sought for duplication. The error
1197 * return ensures that the vnode for this device will be released
1198 * by vn_open. Open will detect this special error and take the
1199 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1200 * will simply report the error.
1201 */
1202 p->p_dupfd = minor(dev);
1203 return (ENODEV);
1204 }
1205
1206 /*
1207 * Duplicate the specified descriptor to a free descriptor.
1208 */
1209 int
1210 dupfdopen(fdp, indx, dfd, mode, error)
1211 register struct filedesc *fdp;
1212 register int indx, dfd;
1213 int mode;
1214 int error;
1215 {
1216 register struct file *wfp;
1217 struct file *fp;
1218
1219 /*
1220 * If the to-be-dup'd fd number is greater than the allowed number
1221 * of file descriptors, or the fd to be dup'd has already been
1222 * closed, reject. Note, check for new == old is necessary as
1223 * falloc could allocate an already closed to-be-dup'd descriptor
1224 * as the new descriptor.
1225 */
1226 fp = fdp->fd_ofiles[indx];
1227 if ((u_int)dfd >= fdp->fd_nfiles ||
1228 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp)
1229 return (EBADF);
1230
1231 /*
1232 * There are two cases of interest here.
1233 *
1234 * For ENODEV simply dup (dfd) to file descriptor
1235 * (indx) and return.
1236 *
1237 * For ENXIO steal away the file structure from (dfd) and
1238 * store it in (indx). (dfd) is effectively closed by
1239 * this operation.
1240 *
1241 * Any other error code is just returned.
1242 */
1243 switch (error) {
1244 case ENODEV:
1245 /*
1246 * Check that the mode the file is being opened for is a
1247 * subset of the mode of the existing descriptor.
1248 */
1249 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1250 return (EACCES);
1251 fdp->fd_ofiles[indx] = wfp;
1252 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1253 wfp->f_count++;
1254 if (indx > fdp->fd_lastfile)
1255 fdp->fd_lastfile = indx;
1256 return (0);
1257
1258 case ENXIO:
1259 /*
1260 * Steal away the file pointer from dfd, and stuff it into indx.
1261 */
1262 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1263 fdp->fd_ofiles[dfd] = NULL;
1264 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1265 fdp->fd_ofileflags[dfd] = 0;
1266 /*
1267 * Complete the clean up of the filedesc structure by
1268 * recomputing the various hints.
1269 */
1270 if (indx > fdp->fd_lastfile)
1271 fdp->fd_lastfile = indx;
1272 else
1273 while (fdp->fd_lastfile > 0 &&
1274 fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1275 fdp->fd_lastfile--;
1276 if (dfd < fdp->fd_freefile)
1277 fdp->fd_freefile = dfd;
1278 return (0);
1279
1280 default:
1281 return (error);
1282 }
1283 /* NOTREACHED */
1284 }
1285
1286 /*
1287 * Get file structures.
1288 */
1289 static int
1290 sysctl_kern_file SYSCTL_HANDLER_ARGS
1291 {
1292 int error;
1293 struct file *fp;
1294
1295 if (!req->oldptr) {
1296 /*
1297 * overestimate by 10 files
1298 */
1299 return (SYSCTL_OUT(req, 0, sizeof(filehead) +
1300 (nfiles + 10) * sizeof(struct file)));
1301 }
1302
1303 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1304 if (error)
1305 return (error);
1306
1307 /*
1308 * followed by an array of file structures
1309 */
1310 for (fp = filehead.lh_first; fp != NULL; fp = fp->f_list.le_next) {
1311 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1312 if (error)
1313 return (error);
1314 }
1315 return (0);
1316 }
1317
1318 SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1319 0, 0, sysctl_kern_file, "S,file", "");
1320
1321 SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc,
1322 CTLFLAG_RW, &maxfilesperproc, 0, "");
1323
1324 SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, &maxfiles, 0, "");
1325
1326 static fildesc_devsw_installed = 0;
1327 #ifdef DEVFS
1328 static void *devfs_token_stdin;
1329 static void *devfs_token_stdout;
1330 static void *devfs_token_stderr;
1331 static void *devfs_token_fildesc[NUMFDESC];
1332 #endif
1333
1334 static void fildesc_drvinit(void *unused)
1335 {
1336 dev_t dev;
1337 #ifdef DEVFS
1338 int fd;
1339 #endif
1340
1341 if( ! fildesc_devsw_installed ) {
1342 dev = makedev(CDEV_MAJOR,0);
1343 cdevsw_add(&dev,&fildesc_cdevsw,NULL);
1344 fildesc_devsw_installed = 1;
1345 #ifdef DEVFS
1346 for (fd = 0; fd < NUMFDESC; fd++)
1347 devfs_token_fildesc[fd] =
1348 devfs_add_devswf(&fildesc_cdevsw, fd, DV_CHR,
1349 UID_BIN, GID_BIN, 0666,
1350 "fd/%d", fd);
1351 devfs_token_stdin =
1352 devfs_add_devswf(&fildesc_cdevsw, 0, DV_CHR,
1353 UID_ROOT, GID_WHEEL, 0666,
1354 "stdin");
1355 devfs_token_stdout =
1356 devfs_add_devswf(&fildesc_cdevsw, 1, DV_CHR,
1357 UID_ROOT, GID_WHEEL, 0666,
1358 "stdout");
1359 devfs_token_stderr =
1360 devfs_add_devswf(&fildesc_cdevsw, 2, DV_CHR,
1361 UID_ROOT, GID_WHEEL, 0666,
1362 "stderr");
1363 #endif
1364 }
1365 }
1366
1367 SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1368 fildesc_drvinit,NULL)
1369
1370
Cache object: 6360aa79c0406e1cfb6f6621a726f452
|