Deleted Added
full compact
kern_descrip.c (46381) kern_descrip.c (47028)
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
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 * $Id: kern_descrip.c,v 1.59 1999/04/28 10:53:22 dt Exp $
39 * $Id: kern_descrip.c,v 1.60 1999/05/03 23:57:20 billf Exp $
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
72static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
73MALLOC_DEFINE(M_FILE, "file", "Open file structure");
74static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
75
76
77static d_open_t fdopen;
78#define NUMFDESC 64
79
80#define CDEV_MAJOR 22
81static struct cdevsw fildesc_cdevsw =
82 { fdopen, noclose, noread, nowrite,
83 noioc, nostop, nullreset, nodevtotty,
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
72static MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table");
73MALLOC_DEFINE(M_FILE, "file", "Open file structure");
74static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures");
75
76
77static d_open_t fdopen;
78#define NUMFDESC 64
79
80#define CDEV_MAJOR 22
81static struct cdevsw fildesc_cdevsw =
82 { fdopen, noclose, noread, nowrite,
83 noioc, nostop, nullreset, nodevtotty,
84 seltrue, nommap, nostrat };
84 seltrue, nommap, nostrat, "FD" };
85
86static int finishdup __P((struct filedesc *fdp, int old, int new, register_t *retval));
87/*
88 * Descriptor management.
89 */
90struct filelist filehead; /* head of list of open files */
91int nfiles; /* actual number of open files */
92extern int cmask;
93
94/*
95 * System calls on descriptors.
96 */
97#ifndef _SYS_SYSPROTO_H_
98struct getdtablesize_args {
99 int dummy;
100};
101#endif
102/* ARGSUSED */
103int
104getdtablesize(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_
118struct dup2_args {
119 u_int from;
120 u_int to;
121};
122#endif
123/* ARGSUSED */
124int
125dup2(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_
162struct dup_args {
163 u_int fd;
164};
165#endif
166/* ARGSUSED */
167int
168dup(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_
197struct fcntl_args {
198 int fd;
199 int cmd;
200 long arg;
201};
202#endif
203/* ARGSUSED */
204int
205fcntl(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, 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, F_SETLK, &fl, flg));
297
298 case F_UNLCK:
299 return (VOP_ADVLOCK(vp, (caddr_t)p, 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,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 */
334static int
335finishdup(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 */
357void
358funsetown(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. */
380void
381funsetownlst(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 */
396int
397fsetown(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 */
466pid_t
467fgetown(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_
477struct close_args {
478 int fd;
479};
480#endif
481/* ARGSUSED */
482int
483close(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_
512struct ofstat_args {
513 int fd;
514 struct ostat *sb;
515};
516#endif
517/* ARGSUSED */
518int
519ofstat(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 cvtstat(&ub, &oub);
552 if (error == 0)
553 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
554 return (error);
555}
556#endif /* COMPAT_43 || COMPAT_SUNOS */
557
558/*
559 * Return status information about a file descriptor.
560 */
561#ifndef _SYS_SYSPROTO_H_
562struct fstat_args {
563 int fd;
564 struct stat *sb;
565};
566#endif
567/* ARGSUSED */
568int
569fstat(p, uap)
570 struct proc *p;
571 register struct fstat_args *uap;
572{
573 register struct filedesc *fdp = p->p_fd;
574 register struct file *fp;
575 struct stat ub;
576 int error;
577
578 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
579 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
580 return (EBADF);
581 switch (fp->f_type) {
582
583 case DTYPE_FIFO:
584 case DTYPE_VNODE:
585 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
586 break;
587
588 case DTYPE_SOCKET:
589 error = soo_stat((struct socket *)fp->f_data, &ub);
590 break;
591
592 case DTYPE_PIPE:
593 error = pipe_stat((struct pipe *)fp->f_data, &ub);
594 break;
595
596 default:
597 panic("fstat");
598 /*NOTREACHED*/
599 }
600 if (error == 0)
601 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
602 return (error);
603}
604
605/*
606 * Return status information about a file descriptor.
607 */
608#ifndef _SYS_SYSPROTO_H_
609struct nfstat_args {
610 int fd;
611 struct nstat *sb;
612};
613#endif
614/* ARGSUSED */
615int
616nfstat(p, uap)
617 struct proc *p;
618 register struct nfstat_args *uap;
619{
620 register struct filedesc *fdp = p->p_fd;
621 register struct file *fp;
622 struct stat ub;
623 struct nstat nub;
624 int error;
625
626 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
627 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
628 return (EBADF);
629 switch (fp->f_type) {
630
631 case DTYPE_FIFO:
632 case DTYPE_VNODE:
633 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
634 break;
635
636 case DTYPE_SOCKET:
637 error = soo_stat((struct socket *)fp->f_data, &ub);
638 break;
639
640 case DTYPE_PIPE:
641 error = pipe_stat((struct pipe *)fp->f_data, &ub);
642 break;
643
644 default:
645 panic("fstat");
646 /*NOTREACHED*/
647 }
648 if (error == 0) {
649 cvtnstat(&ub, &nub);
650 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
651 }
652 return (error);
653}
654
655/*
656 * Return pathconf information about a file descriptor.
657 */
658#ifndef _SYS_SYSPROTO_H_
659struct fpathconf_args {
660 int fd;
661 int name;
662};
663#endif
664/* ARGSUSED */
665int
666fpathconf(p, uap)
667 struct proc *p;
668 register struct fpathconf_args *uap;
669{
670 struct filedesc *fdp = p->p_fd;
671 struct file *fp;
672 struct vnode *vp;
673
674 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
675 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
676 return (EBADF);
677 switch (fp->f_type) {
678
679 case DTYPE_PIPE:
680 case DTYPE_SOCKET:
681 if (uap->name != _PC_PIPE_BUF)
682 return (EINVAL);
683 p->p_retval[0] = PIPE_BUF;
684 return (0);
685
686 case DTYPE_FIFO:
687 case DTYPE_VNODE:
688 vp = (struct vnode *)fp->f_data;
689 return (VOP_PATHCONF(vp, uap->name, p->p_retval));
690
691 default:
692 panic("fpathconf");
693 }
694 /*NOTREACHED*/
695}
696
697/*
698 * Allocate a file descriptor for the process.
699 */
700static int fdexpand;
701SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
702
703int
704fdalloc(p, want, result)
705 struct proc *p;
706 int want;
707 int *result;
708{
709 register struct filedesc *fdp = p->p_fd;
710 register int i;
711 int lim, last, nfiles;
712 struct file **newofile;
713 char *newofileflags;
714
715 /*
716 * Search for a free descriptor starting at the higher
717 * of want or fd_freefile. If that fails, consider
718 * expanding the ofile array.
719 */
720 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
721 for (;;) {
722 last = min(fdp->fd_nfiles, lim);
723 if ((i = want) < fdp->fd_freefile)
724 i = fdp->fd_freefile;
725 for (; i < last; i++) {
726 if (fdp->fd_ofiles[i] == NULL) {
727 fdp->fd_ofileflags[i] = 0;
728 if (i > fdp->fd_lastfile)
729 fdp->fd_lastfile = i;
730 if (want <= fdp->fd_freefile)
731 fdp->fd_freefile = i;
732 *result = i;
733 return (0);
734 }
735 }
736
737 /*
738 * No space in current array. Expand?
739 */
740 if (fdp->fd_nfiles >= lim)
741 return (EMFILE);
742 if (fdp->fd_nfiles < NDEXTENT)
743 nfiles = NDEXTENT;
744 else
745 nfiles = 2 * fdp->fd_nfiles;
746 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
747 M_FILEDESC, M_WAITOK);
748 newofileflags = (char *) &newofile[nfiles];
749 /*
750 * Copy the existing ofile and ofileflags arrays
751 * and zero the new portion of each array.
752 */
753 bcopy(fdp->fd_ofiles, newofile,
754 (i = sizeof(struct file *) * fdp->fd_nfiles));
755 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
756 bcopy(fdp->fd_ofileflags, newofileflags,
757 (i = sizeof(char) * fdp->fd_nfiles));
758 bzero(newofileflags + i, nfiles * sizeof(char) - i);
759 if (fdp->fd_nfiles > NDFILE)
760 FREE(fdp->fd_ofiles, M_FILEDESC);
761 fdp->fd_ofiles = newofile;
762 fdp->fd_ofileflags = newofileflags;
763 fdp->fd_nfiles = nfiles;
764 fdexpand++;
765 }
766 return (0);
767}
768
769/*
770 * Check to see whether n user file descriptors
771 * are available to the process p.
772 */
773int
774fdavail(p, n)
775 struct proc *p;
776 register int n;
777{
778 register struct filedesc *fdp = p->p_fd;
779 register struct file **fpp;
780 register int i, lim, last;
781
782 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
783 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
784 return (1);
785
786 last = min(fdp->fd_nfiles, lim);
787 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
788 for (i = last - fdp->fd_freefile; --i >= 0; fpp++)
789 if (*fpp == NULL && --n <= 0)
790 return (1);
791 return (0);
792}
793
794/*
795 * Create a new open file structure and allocate
796 * a file decriptor for the process that refers to it.
797 */
798int
799falloc(p, resultfp, resultfd)
800 register struct proc *p;
801 struct file **resultfp;
802 int *resultfd;
803{
804 register struct file *fp, *fq;
805 int error, i;
806
807 if ((error = fdalloc(p, 0, &i)))
808 return (error);
809 if (nfiles >= maxfiles) {
810 tablefull("file");
811 return (ENFILE);
812 }
813 /*
814 * Allocate a new file descriptor.
815 * If the process has file descriptor zero open, add to the list
816 * of open files at that point, otherwise put it at the front of
817 * the list of open files.
818 */
819 nfiles++;
820 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
821 bzero(fp, sizeof(struct file));
822 if ((fq = p->p_fd->fd_ofiles[0])) {
823 LIST_INSERT_AFTER(fq, fp, f_list);
824 } else {
825 LIST_INSERT_HEAD(&filehead, fp, f_list);
826 }
827 p->p_fd->fd_ofiles[i] = fp;
828 fp->f_count = 1;
829 fp->f_cred = p->p_ucred;
830 fp->f_seqcount = 1;
831 crhold(fp->f_cred);
832 if (resultfp)
833 *resultfp = fp;
834 if (resultfd)
835 *resultfd = i;
836 return (0);
837}
838
839/*
840 * Free a file descriptor.
841 */
842void
843ffree(fp)
844 register struct file *fp;
845{
846 LIST_REMOVE(fp, f_list);
847 crfree(fp->f_cred);
848#if defined(DIAGNOSTIC) || defined(INVARIANTS)
849 fp->f_count = 0;
850#endif
851 nfiles--;
852 FREE(fp, M_FILE);
853}
854
855/*
856 * Build a new filedesc structure.
857 */
858struct filedesc *
859fdinit(p)
860 struct proc *p;
861{
862 register struct filedesc0 *newfdp;
863 register struct filedesc *fdp = p->p_fd;
864
865 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
866 M_FILEDESC, M_WAITOK);
867 bzero(newfdp, sizeof(struct filedesc0));
868 newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
869 VREF(newfdp->fd_fd.fd_cdir);
870 newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
871 VREF(newfdp->fd_fd.fd_rdir);
872
873 /* Create the file descriptor table. */
874 newfdp->fd_fd.fd_refcnt = 1;
875 newfdp->fd_fd.fd_cmask = cmask;
876 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
877 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
878 newfdp->fd_fd.fd_nfiles = NDFILE;
879
880 newfdp->fd_fd.fd_freefile = 0;
881 newfdp->fd_fd.fd_lastfile = 0;
882
883 return (&newfdp->fd_fd);
884}
885
886/*
887 * Share a filedesc structure.
888 */
889struct filedesc *
890fdshare(p)
891 struct proc *p;
892{
893 p->p_fd->fd_refcnt++;
894 return (p->p_fd);
895}
896
897/*
898 * Copy a filedesc structure.
899 */
900struct filedesc *
901fdcopy(p)
902 struct proc *p;
903{
904 register struct filedesc *newfdp, *fdp = p->p_fd;
905 register struct file **fpp;
906 register int i;
907
908/*
909 * Certain daemons might not have file descriptors
910 */
911 if (fdp == NULL)
912 return NULL;
913
914 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
915 M_FILEDESC, M_WAITOK);
916 bcopy(fdp, newfdp, sizeof(struct filedesc));
917 VREF(newfdp->fd_cdir);
918 VREF(newfdp->fd_rdir);
919 newfdp->fd_refcnt = 1;
920
921 /*
922 * If the number of open files fits in the internal arrays
923 * of the open file structure, use them, otherwise allocate
924 * additional memory for the number of descriptors currently
925 * in use.
926 */
927 if (newfdp->fd_lastfile < NDFILE) {
928 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
929 newfdp->fd_ofileflags =
930 ((struct filedesc0 *) newfdp)->fd_dfileflags;
931 i = NDFILE;
932 } else {
933 /*
934 * Compute the smallest multiple of NDEXTENT needed
935 * for the file descriptors currently in use,
936 * allowing the table to shrink.
937 */
938 i = newfdp->fd_nfiles;
939 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
940 i /= 2;
941 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
942 M_FILEDESC, M_WAITOK);
943 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
944 }
945 newfdp->fd_nfiles = i;
946 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
947 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
948 fpp = newfdp->fd_ofiles;
949 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++)
950 if (*fpp != NULL)
951 (*fpp)->f_count++;
952 return (newfdp);
953}
954
955/*
956 * Release a filedesc structure.
957 */
958void
959fdfree(p)
960 struct proc *p;
961{
962 register struct filedesc *fdp = p->p_fd;
963 struct file **fpp;
964 register int i;
965
966/*
967 * Certain daemons might not have file descriptors
968 */
969 if (fdp == NULL)
970 return;
971
972 if (--fdp->fd_refcnt > 0)
973 return;
974 fpp = fdp->fd_ofiles;
975 for (i = fdp->fd_lastfile; i-- >= 0; fpp++)
976 if (*fpp)
977 (void) closef(*fpp, p);
978 if (fdp->fd_nfiles > NDFILE)
979 FREE(fdp->fd_ofiles, M_FILEDESC);
980 vrele(fdp->fd_cdir);
981 vrele(fdp->fd_rdir);
982 FREE(fdp, M_FILEDESC);
983}
984
985/*
986 * Close any files on exec?
987 */
988void
989fdcloseexec(p)
990 struct proc *p;
991{
992 struct filedesc *fdp = p->p_fd;
993 struct file **fpp;
994 char *fdfp;
995 register int i;
996
997/*
998 * Certain daemons might not have file descriptors
999 */
1000 if (fdp == NULL)
1001 return;
1002
1003 fpp = fdp->fd_ofiles;
1004 fdfp = fdp->fd_ofileflags;
1005 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++)
1006 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) {
1007 if (*fdfp & UF_MAPPED)
1008 (void) munmapfd(p, i);
1009 (void) closef(*fpp, p);
1010 *fpp = NULL;
1011 *fdfp = 0;
1012 if (i < fdp->fd_freefile)
1013 fdp->fd_freefile = i;
1014 }
1015 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1016 fdp->fd_lastfile--;
1017}
1018
1019/*
1020 * Internal form of close.
1021 * Decrement reference count on file structure.
1022 * Note: p may be NULL when closing a file
1023 * that was being passed in a message.
1024 */
1025int
1026closef(fp, p)
1027 register struct file *fp;
1028 register struct proc *p;
1029{
1030 struct vnode *vp;
1031 struct flock lf;
1032 int error;
1033
1034 if (fp == NULL)
1035 return (0);
1036 /*
1037 * POSIX record locking dictates that any close releases ALL
1038 * locks owned by this process. This is handled by setting
1039 * a flag in the unlock to free ONLY locks obeying POSIX
1040 * semantics, and not to free BSD-style file locks.
1041 * If the descriptor was in a message, POSIX-style locks
1042 * aren't passed with the descriptor.
1043 */
1044 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
1045 lf.l_whence = SEEK_SET;
1046 lf.l_start = 0;
1047 lf.l_len = 0;
1048 lf.l_type = F_UNLCK;
1049 vp = (struct vnode *)fp->f_data;
1050 (void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX);
1051 }
1052 if (--fp->f_count > 0)
1053 return (0);
1054 if (fp->f_count < 0)
1055 panic("closef: count < 0");
1056 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1057 lf.l_whence = SEEK_SET;
1058 lf.l_start = 0;
1059 lf.l_len = 0;
1060 lf.l_type = F_UNLCK;
1061 vp = (struct vnode *)fp->f_data;
1062 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1063 }
1064 if (fp->f_ops)
1065 error = (*fp->f_ops->fo_close)(fp, p);
1066 else
1067 error = 0;
1068 ffree(fp);
1069 return (error);
1070}
1071
1072/*
1073 * Apply an advisory lock on a file descriptor.
1074 *
1075 * Just attempt to get a record lock of the requested type on
1076 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1077 */
1078#ifndef _SYS_SYSPROTO_H_
1079struct flock_args {
1080 int fd;
1081 int how;
1082};
1083#endif
1084/* ARGSUSED */
1085int
1086flock(p, uap)
1087 struct proc *p;
1088 register struct flock_args *uap;
1089{
1090 register struct filedesc *fdp = p->p_fd;
1091 register struct file *fp;
1092 struct vnode *vp;
1093 struct flock lf;
1094
1095 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1096 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1097 return (EBADF);
1098 if (fp->f_type != DTYPE_VNODE)
1099 return (EOPNOTSUPP);
1100 vp = (struct vnode *)fp->f_data;
1101 lf.l_whence = SEEK_SET;
1102 lf.l_start = 0;
1103 lf.l_len = 0;
1104 if (uap->how & LOCK_UN) {
1105 lf.l_type = F_UNLCK;
1106 fp->f_flag &= ~FHASLOCK;
1107 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
1108 }
1109 if (uap->how & LOCK_EX)
1110 lf.l_type = F_WRLCK;
1111 else if (uap->how & LOCK_SH)
1112 lf.l_type = F_RDLCK;
1113 else
1114 return (EBADF);
1115 fp->f_flag |= FHASLOCK;
1116 if (uap->how & LOCK_NB)
1117 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
1118 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
1119}
1120
1121/*
1122 * File Descriptor pseudo-device driver (/dev/fd/).
1123 *
1124 * Opening minor device N dup()s the file (if any) connected to file
1125 * descriptor N belonging to the calling process. Note that this driver
1126 * consists of only the ``open()'' routine, because all subsequent
1127 * references to this file will be direct to the other driver.
1128 */
1129/* ARGSUSED */
1130static int
1131fdopen(dev, mode, type, p)
1132 dev_t dev;
1133 int mode, type;
1134 struct proc *p;
1135{
1136
1137 /*
1138 * XXX Kludge: set curproc->p_dupfd to contain the value of the
1139 * the file descriptor being sought for duplication. The error
1140 * return ensures that the vnode for this device will be released
1141 * by vn_open. Open will detect this special error and take the
1142 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1143 * will simply report the error.
1144 */
1145 p->p_dupfd = minor(dev);
1146 return (ENODEV);
1147}
1148
1149/*
1150 * Duplicate the specified descriptor to a free descriptor.
1151 */
1152int
1153dupfdopen(fdp, indx, dfd, mode, error)
1154 register struct filedesc *fdp;
1155 register int indx, dfd;
1156 int mode;
1157 int error;
1158{
1159 register struct file *wfp;
1160 struct file *fp;
1161
1162 /*
1163 * If the to-be-dup'd fd number is greater than the allowed number
1164 * of file descriptors, or the fd to be dup'd has already been
1165 * closed, reject. Note, check for new == old is necessary as
1166 * falloc could allocate an already closed to-be-dup'd descriptor
1167 * as the new descriptor.
1168 */
1169 fp = fdp->fd_ofiles[indx];
1170 if ((u_int)dfd >= fdp->fd_nfiles ||
1171 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp)
1172 return (EBADF);
1173
1174 /*
1175 * There are two cases of interest here.
1176 *
1177 * For ENODEV simply dup (dfd) to file descriptor
1178 * (indx) and return.
1179 *
1180 * For ENXIO steal away the file structure from (dfd) and
1181 * store it in (indx). (dfd) is effectively closed by
1182 * this operation.
1183 *
1184 * Any other error code is just returned.
1185 */
1186 switch (error) {
1187 case ENODEV:
1188 /*
1189 * Check that the mode the file is being opened for is a
1190 * subset of the mode of the existing descriptor.
1191 */
1192 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1193 return (EACCES);
1194 fdp->fd_ofiles[indx] = wfp;
1195 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1196 wfp->f_count++;
1197 if (indx > fdp->fd_lastfile)
1198 fdp->fd_lastfile = indx;
1199 return (0);
1200
1201 case ENXIO:
1202 /*
1203 * Steal away the file pointer from dfd, and stuff it into indx.
1204 */
1205 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1206 fdp->fd_ofiles[dfd] = NULL;
1207 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1208 fdp->fd_ofileflags[dfd] = 0;
1209 /*
1210 * Complete the clean up of the filedesc structure by
1211 * recomputing the various hints.
1212 */
1213 if (indx > fdp->fd_lastfile)
1214 fdp->fd_lastfile = indx;
1215 else
1216 while (fdp->fd_lastfile > 0 &&
1217 fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1218 fdp->fd_lastfile--;
1219 if (dfd < fdp->fd_freefile)
1220 fdp->fd_freefile = dfd;
1221 return (0);
1222
1223 default:
1224 return (error);
1225 }
1226 /* NOTREACHED */
1227}
1228
1229/*
1230 * Get file structures.
1231 */
1232static int
1233sysctl_kern_file SYSCTL_HANDLER_ARGS
1234{
1235 int error;
1236 struct file *fp;
1237
1238 if (!req->oldptr) {
1239 /*
1240 * overestimate by 10 files
1241 */
1242 return (SYSCTL_OUT(req, 0, sizeof(filehead) +
1243 (nfiles + 10) * sizeof(struct file)));
1244 }
1245
1246 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1247 if (error)
1248 return (error);
1249
1250 /*
1251 * followed by an array of file structures
1252 */
1253 for (fp = filehead.lh_first; fp != NULL; fp = fp->f_list.le_next) {
1254 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1255 if (error)
1256 return (error);
1257 }
1258 return (0);
1259}
1260
1261SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1262 0, 0, sysctl_kern_file, "S,file", "Entire file table");
1263
1264SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
1265 &maxfilesperproc, 0, "Maximum files allowed open per process");
1266
1267SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW,
1268 &maxfiles, 0, "Maximum number of files");
1269
1270static int fildesc_devsw_installed;
1271#ifdef DEVFS
1272static void *devfs_token_stdin;
1273static void *devfs_token_stdout;
1274static void *devfs_token_stderr;
1275static void *devfs_token_fildesc[NUMFDESC];
1276#endif
1277
1278static void fildesc_drvinit(void *unused)
1279{
1280 dev_t dev;
1281#ifdef DEVFS
1282 int fd;
1283#endif
1284
1285 if( ! fildesc_devsw_installed ) {
1286 dev = makedev(CDEV_MAJOR,0);
1287 cdevsw_add(&dev,&fildesc_cdevsw,NULL);
1288 fildesc_devsw_installed = 1;
1289#ifdef DEVFS
1290 for (fd = 0; fd < NUMFDESC; fd++)
1291 devfs_token_fildesc[fd] =
1292 devfs_add_devswf(&fildesc_cdevsw, fd, DV_CHR,
1293 UID_BIN, GID_BIN, 0666,
1294 "fd/%d", fd);
1295 devfs_token_stdin =
1296 devfs_add_devswf(&fildesc_cdevsw, 0, DV_CHR,
1297 UID_ROOT, GID_WHEEL, 0666,
1298 "stdin");
1299 devfs_token_stdout =
1300 devfs_add_devswf(&fildesc_cdevsw, 1, DV_CHR,
1301 UID_ROOT, GID_WHEEL, 0666,
1302 "stdout");
1303 devfs_token_stderr =
1304 devfs_add_devswf(&fildesc_cdevsw, 2, DV_CHR,
1305 UID_ROOT, GID_WHEEL, 0666,
1306 "stderr");
1307#endif
1308 }
1309}
1310
1311SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1312 fildesc_drvinit,NULL)
1313
1314
85
86static int finishdup __P((struct filedesc *fdp, int old, int new, register_t *retval));
87/*
88 * Descriptor management.
89 */
90struct filelist filehead; /* head of list of open files */
91int nfiles; /* actual number of open files */
92extern int cmask;
93
94/*
95 * System calls on descriptors.
96 */
97#ifndef _SYS_SYSPROTO_H_
98struct getdtablesize_args {
99 int dummy;
100};
101#endif
102/* ARGSUSED */
103int
104getdtablesize(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_
118struct dup2_args {
119 u_int from;
120 u_int to;
121};
122#endif
123/* ARGSUSED */
124int
125dup2(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_
162struct dup_args {
163 u_int fd;
164};
165#endif
166/* ARGSUSED */
167int
168dup(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_
197struct fcntl_args {
198 int fd;
199 int cmd;
200 long arg;
201};
202#endif
203/* ARGSUSED */
204int
205fcntl(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, 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, F_SETLK, &fl, flg));
297
298 case F_UNLCK:
299 return (VOP_ADVLOCK(vp, (caddr_t)p, 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,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 */
334static int
335finishdup(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 */
357void
358funsetown(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. */
380void
381funsetownlst(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 */
396int
397fsetown(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 */
466pid_t
467fgetown(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_
477struct close_args {
478 int fd;
479};
480#endif
481/* ARGSUSED */
482int
483close(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_
512struct ofstat_args {
513 int fd;
514 struct ostat *sb;
515};
516#endif
517/* ARGSUSED */
518int
519ofstat(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 cvtstat(&ub, &oub);
552 if (error == 0)
553 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub));
554 return (error);
555}
556#endif /* COMPAT_43 || COMPAT_SUNOS */
557
558/*
559 * Return status information about a file descriptor.
560 */
561#ifndef _SYS_SYSPROTO_H_
562struct fstat_args {
563 int fd;
564 struct stat *sb;
565};
566#endif
567/* ARGSUSED */
568int
569fstat(p, uap)
570 struct proc *p;
571 register struct fstat_args *uap;
572{
573 register struct filedesc *fdp = p->p_fd;
574 register struct file *fp;
575 struct stat ub;
576 int error;
577
578 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
579 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
580 return (EBADF);
581 switch (fp->f_type) {
582
583 case DTYPE_FIFO:
584 case DTYPE_VNODE:
585 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
586 break;
587
588 case DTYPE_SOCKET:
589 error = soo_stat((struct socket *)fp->f_data, &ub);
590 break;
591
592 case DTYPE_PIPE:
593 error = pipe_stat((struct pipe *)fp->f_data, &ub);
594 break;
595
596 default:
597 panic("fstat");
598 /*NOTREACHED*/
599 }
600 if (error == 0)
601 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub));
602 return (error);
603}
604
605/*
606 * Return status information about a file descriptor.
607 */
608#ifndef _SYS_SYSPROTO_H_
609struct nfstat_args {
610 int fd;
611 struct nstat *sb;
612};
613#endif
614/* ARGSUSED */
615int
616nfstat(p, uap)
617 struct proc *p;
618 register struct nfstat_args *uap;
619{
620 register struct filedesc *fdp = p->p_fd;
621 register struct file *fp;
622 struct stat ub;
623 struct nstat nub;
624 int error;
625
626 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
627 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
628 return (EBADF);
629 switch (fp->f_type) {
630
631 case DTYPE_FIFO:
632 case DTYPE_VNODE:
633 error = vn_stat((struct vnode *)fp->f_data, &ub, p);
634 break;
635
636 case DTYPE_SOCKET:
637 error = soo_stat((struct socket *)fp->f_data, &ub);
638 break;
639
640 case DTYPE_PIPE:
641 error = pipe_stat((struct pipe *)fp->f_data, &ub);
642 break;
643
644 default:
645 panic("fstat");
646 /*NOTREACHED*/
647 }
648 if (error == 0) {
649 cvtnstat(&ub, &nub);
650 error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub));
651 }
652 return (error);
653}
654
655/*
656 * Return pathconf information about a file descriptor.
657 */
658#ifndef _SYS_SYSPROTO_H_
659struct fpathconf_args {
660 int fd;
661 int name;
662};
663#endif
664/* ARGSUSED */
665int
666fpathconf(p, uap)
667 struct proc *p;
668 register struct fpathconf_args *uap;
669{
670 struct filedesc *fdp = p->p_fd;
671 struct file *fp;
672 struct vnode *vp;
673
674 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
675 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
676 return (EBADF);
677 switch (fp->f_type) {
678
679 case DTYPE_PIPE:
680 case DTYPE_SOCKET:
681 if (uap->name != _PC_PIPE_BUF)
682 return (EINVAL);
683 p->p_retval[0] = PIPE_BUF;
684 return (0);
685
686 case DTYPE_FIFO:
687 case DTYPE_VNODE:
688 vp = (struct vnode *)fp->f_data;
689 return (VOP_PATHCONF(vp, uap->name, p->p_retval));
690
691 default:
692 panic("fpathconf");
693 }
694 /*NOTREACHED*/
695}
696
697/*
698 * Allocate a file descriptor for the process.
699 */
700static int fdexpand;
701SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
702
703int
704fdalloc(p, want, result)
705 struct proc *p;
706 int want;
707 int *result;
708{
709 register struct filedesc *fdp = p->p_fd;
710 register int i;
711 int lim, last, nfiles;
712 struct file **newofile;
713 char *newofileflags;
714
715 /*
716 * Search for a free descriptor starting at the higher
717 * of want or fd_freefile. If that fails, consider
718 * expanding the ofile array.
719 */
720 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
721 for (;;) {
722 last = min(fdp->fd_nfiles, lim);
723 if ((i = want) < fdp->fd_freefile)
724 i = fdp->fd_freefile;
725 for (; i < last; i++) {
726 if (fdp->fd_ofiles[i] == NULL) {
727 fdp->fd_ofileflags[i] = 0;
728 if (i > fdp->fd_lastfile)
729 fdp->fd_lastfile = i;
730 if (want <= fdp->fd_freefile)
731 fdp->fd_freefile = i;
732 *result = i;
733 return (0);
734 }
735 }
736
737 /*
738 * No space in current array. Expand?
739 */
740 if (fdp->fd_nfiles >= lim)
741 return (EMFILE);
742 if (fdp->fd_nfiles < NDEXTENT)
743 nfiles = NDEXTENT;
744 else
745 nfiles = 2 * fdp->fd_nfiles;
746 MALLOC(newofile, struct file **, nfiles * OFILESIZE,
747 M_FILEDESC, M_WAITOK);
748 newofileflags = (char *) &newofile[nfiles];
749 /*
750 * Copy the existing ofile and ofileflags arrays
751 * and zero the new portion of each array.
752 */
753 bcopy(fdp->fd_ofiles, newofile,
754 (i = sizeof(struct file *) * fdp->fd_nfiles));
755 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i);
756 bcopy(fdp->fd_ofileflags, newofileflags,
757 (i = sizeof(char) * fdp->fd_nfiles));
758 bzero(newofileflags + i, nfiles * sizeof(char) - i);
759 if (fdp->fd_nfiles > NDFILE)
760 FREE(fdp->fd_ofiles, M_FILEDESC);
761 fdp->fd_ofiles = newofile;
762 fdp->fd_ofileflags = newofileflags;
763 fdp->fd_nfiles = nfiles;
764 fdexpand++;
765 }
766 return (0);
767}
768
769/*
770 * Check to see whether n user file descriptors
771 * are available to the process p.
772 */
773int
774fdavail(p, n)
775 struct proc *p;
776 register int n;
777{
778 register struct filedesc *fdp = p->p_fd;
779 register struct file **fpp;
780 register int i, lim, last;
781
782 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc);
783 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0)
784 return (1);
785
786 last = min(fdp->fd_nfiles, lim);
787 fpp = &fdp->fd_ofiles[fdp->fd_freefile];
788 for (i = last - fdp->fd_freefile; --i >= 0; fpp++)
789 if (*fpp == NULL && --n <= 0)
790 return (1);
791 return (0);
792}
793
794/*
795 * Create a new open file structure and allocate
796 * a file decriptor for the process that refers to it.
797 */
798int
799falloc(p, resultfp, resultfd)
800 register struct proc *p;
801 struct file **resultfp;
802 int *resultfd;
803{
804 register struct file *fp, *fq;
805 int error, i;
806
807 if ((error = fdalloc(p, 0, &i)))
808 return (error);
809 if (nfiles >= maxfiles) {
810 tablefull("file");
811 return (ENFILE);
812 }
813 /*
814 * Allocate a new file descriptor.
815 * If the process has file descriptor zero open, add to the list
816 * of open files at that point, otherwise put it at the front of
817 * the list of open files.
818 */
819 nfiles++;
820 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK);
821 bzero(fp, sizeof(struct file));
822 if ((fq = p->p_fd->fd_ofiles[0])) {
823 LIST_INSERT_AFTER(fq, fp, f_list);
824 } else {
825 LIST_INSERT_HEAD(&filehead, fp, f_list);
826 }
827 p->p_fd->fd_ofiles[i] = fp;
828 fp->f_count = 1;
829 fp->f_cred = p->p_ucred;
830 fp->f_seqcount = 1;
831 crhold(fp->f_cred);
832 if (resultfp)
833 *resultfp = fp;
834 if (resultfd)
835 *resultfd = i;
836 return (0);
837}
838
839/*
840 * Free a file descriptor.
841 */
842void
843ffree(fp)
844 register struct file *fp;
845{
846 LIST_REMOVE(fp, f_list);
847 crfree(fp->f_cred);
848#if defined(DIAGNOSTIC) || defined(INVARIANTS)
849 fp->f_count = 0;
850#endif
851 nfiles--;
852 FREE(fp, M_FILE);
853}
854
855/*
856 * Build a new filedesc structure.
857 */
858struct filedesc *
859fdinit(p)
860 struct proc *p;
861{
862 register struct filedesc0 *newfdp;
863 register struct filedesc *fdp = p->p_fd;
864
865 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0),
866 M_FILEDESC, M_WAITOK);
867 bzero(newfdp, sizeof(struct filedesc0));
868 newfdp->fd_fd.fd_cdir = fdp->fd_cdir;
869 VREF(newfdp->fd_fd.fd_cdir);
870 newfdp->fd_fd.fd_rdir = fdp->fd_rdir;
871 VREF(newfdp->fd_fd.fd_rdir);
872
873 /* Create the file descriptor table. */
874 newfdp->fd_fd.fd_refcnt = 1;
875 newfdp->fd_fd.fd_cmask = cmask;
876 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles;
877 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags;
878 newfdp->fd_fd.fd_nfiles = NDFILE;
879
880 newfdp->fd_fd.fd_freefile = 0;
881 newfdp->fd_fd.fd_lastfile = 0;
882
883 return (&newfdp->fd_fd);
884}
885
886/*
887 * Share a filedesc structure.
888 */
889struct filedesc *
890fdshare(p)
891 struct proc *p;
892{
893 p->p_fd->fd_refcnt++;
894 return (p->p_fd);
895}
896
897/*
898 * Copy a filedesc structure.
899 */
900struct filedesc *
901fdcopy(p)
902 struct proc *p;
903{
904 register struct filedesc *newfdp, *fdp = p->p_fd;
905 register struct file **fpp;
906 register int i;
907
908/*
909 * Certain daemons might not have file descriptors
910 */
911 if (fdp == NULL)
912 return NULL;
913
914 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0),
915 M_FILEDESC, M_WAITOK);
916 bcopy(fdp, newfdp, sizeof(struct filedesc));
917 VREF(newfdp->fd_cdir);
918 VREF(newfdp->fd_rdir);
919 newfdp->fd_refcnt = 1;
920
921 /*
922 * If the number of open files fits in the internal arrays
923 * of the open file structure, use them, otherwise allocate
924 * additional memory for the number of descriptors currently
925 * in use.
926 */
927 if (newfdp->fd_lastfile < NDFILE) {
928 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles;
929 newfdp->fd_ofileflags =
930 ((struct filedesc0 *) newfdp)->fd_dfileflags;
931 i = NDFILE;
932 } else {
933 /*
934 * Compute the smallest multiple of NDEXTENT needed
935 * for the file descriptors currently in use,
936 * allowing the table to shrink.
937 */
938 i = newfdp->fd_nfiles;
939 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2)
940 i /= 2;
941 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE,
942 M_FILEDESC, M_WAITOK);
943 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i];
944 }
945 newfdp->fd_nfiles = i;
946 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **));
947 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char));
948 fpp = newfdp->fd_ofiles;
949 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++)
950 if (*fpp != NULL)
951 (*fpp)->f_count++;
952 return (newfdp);
953}
954
955/*
956 * Release a filedesc structure.
957 */
958void
959fdfree(p)
960 struct proc *p;
961{
962 register struct filedesc *fdp = p->p_fd;
963 struct file **fpp;
964 register int i;
965
966/*
967 * Certain daemons might not have file descriptors
968 */
969 if (fdp == NULL)
970 return;
971
972 if (--fdp->fd_refcnt > 0)
973 return;
974 fpp = fdp->fd_ofiles;
975 for (i = fdp->fd_lastfile; i-- >= 0; fpp++)
976 if (*fpp)
977 (void) closef(*fpp, p);
978 if (fdp->fd_nfiles > NDFILE)
979 FREE(fdp->fd_ofiles, M_FILEDESC);
980 vrele(fdp->fd_cdir);
981 vrele(fdp->fd_rdir);
982 FREE(fdp, M_FILEDESC);
983}
984
985/*
986 * Close any files on exec?
987 */
988void
989fdcloseexec(p)
990 struct proc *p;
991{
992 struct filedesc *fdp = p->p_fd;
993 struct file **fpp;
994 char *fdfp;
995 register int i;
996
997/*
998 * Certain daemons might not have file descriptors
999 */
1000 if (fdp == NULL)
1001 return;
1002
1003 fpp = fdp->fd_ofiles;
1004 fdfp = fdp->fd_ofileflags;
1005 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++)
1006 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) {
1007 if (*fdfp & UF_MAPPED)
1008 (void) munmapfd(p, i);
1009 (void) closef(*fpp, p);
1010 *fpp = NULL;
1011 *fdfp = 0;
1012 if (i < fdp->fd_freefile)
1013 fdp->fd_freefile = i;
1014 }
1015 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1016 fdp->fd_lastfile--;
1017}
1018
1019/*
1020 * Internal form of close.
1021 * Decrement reference count on file structure.
1022 * Note: p may be NULL when closing a file
1023 * that was being passed in a message.
1024 */
1025int
1026closef(fp, p)
1027 register struct file *fp;
1028 register struct proc *p;
1029{
1030 struct vnode *vp;
1031 struct flock lf;
1032 int error;
1033
1034 if (fp == NULL)
1035 return (0);
1036 /*
1037 * POSIX record locking dictates that any close releases ALL
1038 * locks owned by this process. This is handled by setting
1039 * a flag in the unlock to free ONLY locks obeying POSIX
1040 * semantics, and not to free BSD-style file locks.
1041 * If the descriptor was in a message, POSIX-style locks
1042 * aren't passed with the descriptor.
1043 */
1044 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
1045 lf.l_whence = SEEK_SET;
1046 lf.l_start = 0;
1047 lf.l_len = 0;
1048 lf.l_type = F_UNLCK;
1049 vp = (struct vnode *)fp->f_data;
1050 (void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX);
1051 }
1052 if (--fp->f_count > 0)
1053 return (0);
1054 if (fp->f_count < 0)
1055 panic("closef: count < 0");
1056 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) {
1057 lf.l_whence = SEEK_SET;
1058 lf.l_start = 0;
1059 lf.l_len = 0;
1060 lf.l_type = F_UNLCK;
1061 vp = (struct vnode *)fp->f_data;
1062 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK);
1063 }
1064 if (fp->f_ops)
1065 error = (*fp->f_ops->fo_close)(fp, p);
1066 else
1067 error = 0;
1068 ffree(fp);
1069 return (error);
1070}
1071
1072/*
1073 * Apply an advisory lock on a file descriptor.
1074 *
1075 * Just attempt to get a record lock of the requested type on
1076 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0).
1077 */
1078#ifndef _SYS_SYSPROTO_H_
1079struct flock_args {
1080 int fd;
1081 int how;
1082};
1083#endif
1084/* ARGSUSED */
1085int
1086flock(p, uap)
1087 struct proc *p;
1088 register struct flock_args *uap;
1089{
1090 register struct filedesc *fdp = p->p_fd;
1091 register struct file *fp;
1092 struct vnode *vp;
1093 struct flock lf;
1094
1095 if ((unsigned)uap->fd >= fdp->fd_nfiles ||
1096 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
1097 return (EBADF);
1098 if (fp->f_type != DTYPE_VNODE)
1099 return (EOPNOTSUPP);
1100 vp = (struct vnode *)fp->f_data;
1101 lf.l_whence = SEEK_SET;
1102 lf.l_start = 0;
1103 lf.l_len = 0;
1104 if (uap->how & LOCK_UN) {
1105 lf.l_type = F_UNLCK;
1106 fp->f_flag &= ~FHASLOCK;
1107 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK));
1108 }
1109 if (uap->how & LOCK_EX)
1110 lf.l_type = F_WRLCK;
1111 else if (uap->how & LOCK_SH)
1112 lf.l_type = F_RDLCK;
1113 else
1114 return (EBADF);
1115 fp->f_flag |= FHASLOCK;
1116 if (uap->how & LOCK_NB)
1117 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK));
1118 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT));
1119}
1120
1121/*
1122 * File Descriptor pseudo-device driver (/dev/fd/).
1123 *
1124 * Opening minor device N dup()s the file (if any) connected to file
1125 * descriptor N belonging to the calling process. Note that this driver
1126 * consists of only the ``open()'' routine, because all subsequent
1127 * references to this file will be direct to the other driver.
1128 */
1129/* ARGSUSED */
1130static int
1131fdopen(dev, mode, type, p)
1132 dev_t dev;
1133 int mode, type;
1134 struct proc *p;
1135{
1136
1137 /*
1138 * XXX Kludge: set curproc->p_dupfd to contain the value of the
1139 * the file descriptor being sought for duplication. The error
1140 * return ensures that the vnode for this device will be released
1141 * by vn_open. Open will detect this special error and take the
1142 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN
1143 * will simply report the error.
1144 */
1145 p->p_dupfd = minor(dev);
1146 return (ENODEV);
1147}
1148
1149/*
1150 * Duplicate the specified descriptor to a free descriptor.
1151 */
1152int
1153dupfdopen(fdp, indx, dfd, mode, error)
1154 register struct filedesc *fdp;
1155 register int indx, dfd;
1156 int mode;
1157 int error;
1158{
1159 register struct file *wfp;
1160 struct file *fp;
1161
1162 /*
1163 * If the to-be-dup'd fd number is greater than the allowed number
1164 * of file descriptors, or the fd to be dup'd has already been
1165 * closed, reject. Note, check for new == old is necessary as
1166 * falloc could allocate an already closed to-be-dup'd descriptor
1167 * as the new descriptor.
1168 */
1169 fp = fdp->fd_ofiles[indx];
1170 if ((u_int)dfd >= fdp->fd_nfiles ||
1171 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp)
1172 return (EBADF);
1173
1174 /*
1175 * There are two cases of interest here.
1176 *
1177 * For ENODEV simply dup (dfd) to file descriptor
1178 * (indx) and return.
1179 *
1180 * For ENXIO steal away the file structure from (dfd) and
1181 * store it in (indx). (dfd) is effectively closed by
1182 * this operation.
1183 *
1184 * Any other error code is just returned.
1185 */
1186 switch (error) {
1187 case ENODEV:
1188 /*
1189 * Check that the mode the file is being opened for is a
1190 * subset of the mode of the existing descriptor.
1191 */
1192 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag)
1193 return (EACCES);
1194 fdp->fd_ofiles[indx] = wfp;
1195 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1196 wfp->f_count++;
1197 if (indx > fdp->fd_lastfile)
1198 fdp->fd_lastfile = indx;
1199 return (0);
1200
1201 case ENXIO:
1202 /*
1203 * Steal away the file pointer from dfd, and stuff it into indx.
1204 */
1205 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
1206 fdp->fd_ofiles[dfd] = NULL;
1207 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd];
1208 fdp->fd_ofileflags[dfd] = 0;
1209 /*
1210 * Complete the clean up of the filedesc structure by
1211 * recomputing the various hints.
1212 */
1213 if (indx > fdp->fd_lastfile)
1214 fdp->fd_lastfile = indx;
1215 else
1216 while (fdp->fd_lastfile > 0 &&
1217 fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
1218 fdp->fd_lastfile--;
1219 if (dfd < fdp->fd_freefile)
1220 fdp->fd_freefile = dfd;
1221 return (0);
1222
1223 default:
1224 return (error);
1225 }
1226 /* NOTREACHED */
1227}
1228
1229/*
1230 * Get file structures.
1231 */
1232static int
1233sysctl_kern_file SYSCTL_HANDLER_ARGS
1234{
1235 int error;
1236 struct file *fp;
1237
1238 if (!req->oldptr) {
1239 /*
1240 * overestimate by 10 files
1241 */
1242 return (SYSCTL_OUT(req, 0, sizeof(filehead) +
1243 (nfiles + 10) * sizeof(struct file)));
1244 }
1245
1246 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead));
1247 if (error)
1248 return (error);
1249
1250 /*
1251 * followed by an array of file structures
1252 */
1253 for (fp = filehead.lh_first; fp != NULL; fp = fp->f_list.le_next) {
1254 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file));
1255 if (error)
1256 return (error);
1257 }
1258 return (0);
1259}
1260
1261SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD,
1262 0, 0, sysctl_kern_file, "S,file", "Entire file table");
1263
1264SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW,
1265 &maxfilesperproc, 0, "Maximum files allowed open per process");
1266
1267SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW,
1268 &maxfiles, 0, "Maximum number of files");
1269
1270static int fildesc_devsw_installed;
1271#ifdef DEVFS
1272static void *devfs_token_stdin;
1273static void *devfs_token_stdout;
1274static void *devfs_token_stderr;
1275static void *devfs_token_fildesc[NUMFDESC];
1276#endif
1277
1278static void fildesc_drvinit(void *unused)
1279{
1280 dev_t dev;
1281#ifdef DEVFS
1282 int fd;
1283#endif
1284
1285 if( ! fildesc_devsw_installed ) {
1286 dev = makedev(CDEV_MAJOR,0);
1287 cdevsw_add(&dev,&fildesc_cdevsw,NULL);
1288 fildesc_devsw_installed = 1;
1289#ifdef DEVFS
1290 for (fd = 0; fd < NUMFDESC; fd++)
1291 devfs_token_fildesc[fd] =
1292 devfs_add_devswf(&fildesc_cdevsw, fd, DV_CHR,
1293 UID_BIN, GID_BIN, 0666,
1294 "fd/%d", fd);
1295 devfs_token_stdin =
1296 devfs_add_devswf(&fildesc_cdevsw, 0, DV_CHR,
1297 UID_ROOT, GID_WHEEL, 0666,
1298 "stdin");
1299 devfs_token_stdout =
1300 devfs_add_devswf(&fildesc_cdevsw, 1, DV_CHR,
1301 UID_ROOT, GID_WHEEL, 0666,
1302 "stdout");
1303 devfs_token_stderr =
1304 devfs_add_devswf(&fildesc_cdevsw, 2, DV_CHR,
1305 UID_ROOT, GID_WHEEL, 0666,
1306 "stderr");
1307#endif
1308 }
1309}
1310
1311SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,
1312 fildesc_drvinit,NULL)
1313
1314