kern_descrip.c revision 65052
167754Smsmith/* 267754Smsmith * Copyright (c) 1982, 1986, 1989, 1991, 1993 367754Smsmith * The Regents of the University of California. All rights reserved. 467754Smsmith * (c) UNIX System Laboratories, Inc. 567754Smsmith * All or some portions of this file are derived from material licensed 667754Smsmith * to the University of California by American Telephone and Telegraph 7316303Sjkim * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8316303Sjkim * the permission of UNIX System Laboratories, Inc. 9316303Sjkim * 10316303Sjkim * Redistribution and use in source and binary forms, with or without 11316303Sjkim * modification, are permitted provided that the following conditions 1270243Smsmith * are met: 1367754Smsmith * 1. Redistributions of source code must retain the above copyright 14316303Sjkim * notice, this list of conditions and the following disclaimer. 15316303Sjkim * 2. Redistributions in binary form must reproduce the above copyright 16316303Sjkim * notice, this list of conditions and the following disclaimer in the 17316303Sjkim * documentation and/or other materials provided with the distribution. 18316303Sjkim * 3. All advertising materials mentioning features or use of this software 19316303Sjkim * must display the following acknowledgement: 20316303Sjkim * This product includes software developed by the University of 21316303Sjkim * California, Berkeley and its contributors. 22316303Sjkim * 4. Neither the name of the University nor the names of its contributors 23316303Sjkim * may be used to endorse or promote products derived from this software 24316303Sjkim * without specific prior written permission. 25316303Sjkim * 26316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27316303Sjkim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29316303Sjkim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30316303Sjkim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31316303Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32316303Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33316303Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34316303Sjkim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35316303Sjkim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36316303Sjkim * SUCH DAMAGE. 37316303Sjkim * 38316303Sjkim * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94 39316303Sjkim * $FreeBSD: head/sys/kern/kern_descrip.c 65052 2000-08-24 15:59:44Z phk $ 40316303Sjkim */ 41316303Sjkim 42316303Sjkim#include "opt_compat.h" 43316303Sjkim#include "opt_devfs.h" 44316303Sjkim#include <sys/param.h> 45316303Sjkim#include <sys/systm.h> 46316303Sjkim#include <sys/sysproto.h> 47316303Sjkim#include <sys/conf.h> 48316303Sjkim#include <sys/filedesc.h> 49316303Sjkim#include <sys/kernel.h> 50316303Sjkim#include <sys/sysctl.h> 51316303Sjkim#include <sys/vnode.h> 52316303Sjkim#include <sys/proc.h> 53316303Sjkim#include <sys/file.h> 54316303Sjkim#include <sys/stat.h> 55316303Sjkim#include <sys/filio.h> 56316303Sjkim#include <sys/fcntl.h> 57316303Sjkim#include <sys/malloc.h> 58316303Sjkim#include <sys/unistd.h> 59316303Sjkim#include <sys/resourcevar.h> 60316303Sjkim#include <sys/event.h> 61316303Sjkim 62316303Sjkim#include <vm/vm.h> 63316303Sjkim#include <vm/vm_extern.h> 64316303Sjkim 65316303Sjkim#ifdef DEVFS 66316303Sjkim#include <sys/ctype.h> 67316303Sjkim#include <sys/eventhandler.h> 68316303Sjkim#include <fs/devfs/devfs.h> 69316303Sjkim#endif 70316303Sjkim 71316303Sjkimstatic MALLOC_DEFINE(M_FILEDESC, "file desc", "Open file descriptor table"); 72316303SjkimMALLOC_DEFINE(M_FILE, "file", "Open file structure"); 73316303Sjkimstatic MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures"); 74316303Sjkim 75316303Sjkimstatic d_open_t fdopen; 76316303Sjkim#define NUMFDESC 64 77316303Sjkim 78316303Sjkim#define CDEV_MAJOR 22 79316303Sjkimstatic struct cdevsw fildesc_cdevsw = { 80316303Sjkim /* open */ fdopen, 81316303Sjkim /* close */ noclose, 82316303Sjkim /* read */ noread, 83316303Sjkim /* write */ nowrite, 84316303Sjkim /* ioctl */ noioctl, 85316303Sjkim /* poll */ nopoll, 86316303Sjkim /* mmap */ nommap, 87316303Sjkim /* strategy */ nostrategy, 88316303Sjkim /* name */ "FD", 89316303Sjkim /* maj */ CDEV_MAJOR, 90316303Sjkim /* dump */ nodump, 91316303Sjkim /* psize */ nopsize, 92316303Sjkim /* flags */ 0, 93316303Sjkim /* bmaj */ -1 94316303Sjkim}; 95316303Sjkim 96316303Sjkimstatic int finishdup __P((struct filedesc *fdp, int old, int new, register_t *retval)); 97316303Sjkimstatic int badfo_readwrite __P((struct file *fp, struct uio *uio, 98316303Sjkim struct ucred *cred, int flags, struct proc *p)); 99316303Sjkimstatic int badfo_ioctl __P((struct file *fp, u_long com, caddr_t data, 100316303Sjkim struct proc *p)); 101316303Sjkimstatic int badfo_poll __P((struct file *fp, int events, 102316303Sjkim struct ucred *cred, struct proc *p)); 103316303Sjkimstatic int badfo_stat __P((struct file *fp, struct stat *sb, struct proc *p)); 104316303Sjkimstatic int badfo_close __P((struct file *fp, struct proc *p)); 105316303Sjkim 106316303Sjkim/* 107316303Sjkim * Descriptor management. 108316303Sjkim */ 109316303Sjkimstruct filelist filehead; /* head of list of open files */ 110316303Sjkimint nfiles; /* actual number of open files */ 111316303Sjkimextern int cmask; 112316303Sjkim 113316303Sjkim/* 114316303Sjkim * System calls on descriptors. 115316303Sjkim */ 116316303Sjkim#ifndef _SYS_SYSPROTO_H_ 117316303Sjkimstruct getdtablesize_args { 118316303Sjkim int dummy; 119217365Sjkim}; 120217365Sjkim#endif 121217365Sjkim/* ARGSUSED */ 122217365Sjkimint 123217365Sjkimgetdtablesize(p, uap) 124217365Sjkim struct proc *p; 125217365Sjkim struct getdtablesize_args *uap; 126217365Sjkim{ 127217365Sjkim 128217365Sjkim p->p_retval[0] = 129217365Sjkim min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 130217365Sjkim return (0); 131217365Sjkim} 132217365Sjkim 13367754Smsmith/* 134316303Sjkim * Duplicate a file descriptor to a particular value. 135316303Sjkim */ 136316303Sjkim#ifndef _SYS_SYSPROTO_H_ 137316303Sjkimstruct dup2_args { 138316303Sjkim u_int from; 139316303Sjkim u_int to; 140316303Sjkim}; 141316303Sjkim#endif 142316303Sjkim/* ARGSUSED */ 143316303Sjkimint 144316303Sjkimdup2(p, uap) 145316303Sjkim struct proc *p; 146316303Sjkim struct dup2_args *uap; 147217365Sjkim{ 148217365Sjkim register struct filedesc *fdp = p->p_fd; 14967754Smsmith register u_int old = uap->from, new = uap->to; 150316303Sjkim int i, error; 15167754Smsmith 152193341Sjkim if (old >= fdp->fd_nfiles || 153193341Sjkim fdp->fd_ofiles[old] == NULL || 154193341Sjkim new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 15567754Smsmith new >= maxfilesperproc) 15667754Smsmith return (EBADF); 15777424Smsmith if (old == new) { 15891116Smsmith p->p_retval[0] = new; 15967754Smsmith return (0); 16067754Smsmith } 16167754Smsmith if (new >= fdp->fd_nfiles) { 16267754Smsmith if ((error = fdalloc(p, new, &i))) 16367754Smsmith return (error); 16467754Smsmith if (new != i) 165151937Sjkim panic("dup2: fdalloc"); 16667754Smsmith } else if (fdp->fd_ofiles[new]) { 167151937Sjkim if (fdp->fd_ofileflags[new] & UF_MAPPED) 16867754Smsmith (void) munmapfd(p, new); 16983174Smsmith /* 17067754Smsmith * dup2() must succeed even if the close has an error. 17167754Smsmith */ 17267754Smsmith (void) closef(fdp->fd_ofiles[new], p); 17367754Smsmith } 17467754Smsmith return (finishdup(fdp, (int)old, (int)new, p->p_retval)); 17584491Smsmith} 17667754Smsmith 17767754Smsmith/* 178167802Sjkim * Duplicate a file descriptor. 179167802Sjkim */ 180167802Sjkim#ifndef _SYS_SYSPROTO_H_ 18167754Smsmithstruct dup_args { 18283174Smsmith u_int fd; 183167802Sjkim}; 18467754Smsmith#endif 18567754Smsmith/* ARGSUSED */ 186167802Sjkimint 18767754Smsmithdup(p, uap) 18867754Smsmith struct proc *p; 18967754Smsmith struct dup_args *uap; 19067754Smsmith{ 19167754Smsmith register struct filedesc *fdp; 192151937Sjkim u_int old; 19367754Smsmith int new, error; 194167802Sjkim 195193267Sjkim old = uap->fd; 196298714Sjkim fdp = p->p_fd; 197167802Sjkim if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) 198167802Sjkim return (EBADF); 199167802Sjkim if ((error = fdalloc(p, 0, &new))) 200167802Sjkim return (error); 201167802Sjkim return (finishdup(fdp, (int)old, new, p->p_retval)); 202167802Sjkim} 203167802Sjkim 20491116Smsmith/* 20567754Smsmith * The file control system call. 20667754Smsmith */ 20767754Smsmith#ifndef _SYS_SYSPROTO_H_ 20867754Smsmithstruct fcntl_args { 20967754Smsmith int fd; 21067754Smsmith int cmd; 21167754Smsmith long arg; 21267754Smsmith}; 21383174Smsmith#endif 21467754Smsmith/* ARGSUSED */ 21567754Smsmithint 21667754Smsmithfcntl(p, uap) 217197104Sjkim struct proc *p; 218197104Sjkim register struct fcntl_args *uap; 219197104Sjkim{ 220197104Sjkim register struct filedesc *fdp = p->p_fd; 22167754Smsmith register struct file *fp; 22267754Smsmith register char *pop; 22367754Smsmith struct vnode *vp; 22467754Smsmith int i, tmp, error, flg = F_POSIX; 22567754Smsmith struct flock fl; 22667754Smsmith u_int newmin; 22767754Smsmith 228197104Sjkim if ((unsigned)uap->fd >= fdp->fd_nfiles || 229272444Sjkim (fp = fdp->fd_ofiles[uap->fd]) == NULL) 230197104Sjkim return (EBADF); 231197104Sjkim pop = &fdp->fd_ofileflags[uap->fd]; 232197104Sjkim switch (uap->cmd) { 233197104Sjkim 234197104Sjkim case F_DUPFD: 235197104Sjkim newmin = uap->arg; 236197104Sjkim if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 237197104Sjkim newmin >= maxfilesperproc) 238197104Sjkim return (EINVAL); 239197104Sjkim if ((error = fdalloc(p, newmin, &i))) 240272444Sjkim return (error); 241272444Sjkim return (finishdup(fdp, uap->fd, i, p->p_retval)); 242272444Sjkim 243272444Sjkim case F_GETFD: 244197104Sjkim p->p_retval[0] = *pop & 1; 245197104Sjkim return (0); 246272444Sjkim 247197104Sjkim case F_SETFD: 248197104Sjkim *pop = (*pop &~ 1) | (uap->arg & 1); 249197104Sjkim return (0); 250197104Sjkim 251197104Sjkim case F_GETFL: 252197104Sjkim p->p_retval[0] = OFLAGS(fp->f_flag); 253197104Sjkim return (0); 254197104Sjkim 255197104Sjkim case F_SETFL: 256272444Sjkim fp->f_flag &= ~FCNTLFLAGS; 257197104Sjkim fp->f_flag |= FFLAGS(uap->arg & ~O_ACCMODE) & FCNTLFLAGS; 258272444Sjkim tmp = fp->f_flag & FNONBLOCK; 259197104Sjkim error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p); 260197104Sjkim if (error) 261272444Sjkim return (error); 262272444Sjkim tmp = fp->f_flag & FASYNC; 263272444Sjkim error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, p); 264272444Sjkim if (!error) 265272444Sjkim return (0); 266272444Sjkim fp->f_flag &= ~FNONBLOCK; 267272444Sjkim tmp = 0; 268197104Sjkim (void)fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, p); 269197104Sjkim return (error); 270197104Sjkim 271197104Sjkim case F_GETOWN: 272197104Sjkim return (fo_ioctl(fp, FIOGETOWN, (caddr_t)p->p_retval, p)); 273197104Sjkim 274197104Sjkim case F_SETOWN: 275197104Sjkim return (fo_ioctl(fp, FIOSETOWN, (caddr_t)&uap->arg, p)); 276197104Sjkim 277197104Sjkim case F_SETLKW: 278197104Sjkim flg |= F_WAIT; 279197104Sjkim /* Fall into F_SETLK */ 280197104Sjkim 281197104Sjkim case F_SETLK: 282197104Sjkim if (fp->f_type != DTYPE_VNODE) 283197104Sjkim return (EBADF); 284197104Sjkim vp = (struct vnode *)fp->f_data; 285197104Sjkim /* Copy in the lock structure */ 286197104Sjkim error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 287197104Sjkim sizeof(fl)); 288197104Sjkim if (error) 289197104Sjkim return (error); 290197104Sjkim if (fl.l_whence == SEEK_CUR) 291197104Sjkim fl.l_start += fp->f_offset; 292197104Sjkim switch (fl.l_type) { 293197104Sjkim 29467754Smsmith case F_RDLCK: 29567754Smsmith if ((fp->f_flag & FREAD) == 0) 29667754Smsmith return (EBADF); 29767754Smsmith p->p_flag |= P_ADVLOCK; 29867754Smsmith return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg)); 299197104Sjkim 30067754Smsmith case F_WRLCK: 30183174Smsmith if ((fp->f_flag & FWRITE) == 0) 302209746Sjkim return (EBADF); 30367754Smsmith p->p_flag |= P_ADVLOCK; 30467754Smsmith return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, &fl, flg)); 30567754Smsmith 30667754Smsmith case F_UNLCK: 307115351Snjl return (VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &fl, 308115351Snjl F_POSIX)); 30967754Smsmith 31067754Smsmith default: 31167754Smsmith return (EINVAL); 312209746Sjkim } 31367754Smsmith 31467754Smsmith case F_GETLK: 31567754Smsmith if (fp->f_type != DTYPE_VNODE) 31667754Smsmith return (EBADF); 317115351Snjl vp = (struct vnode *)fp->f_data; 318115351Snjl /* Copy in the lock structure */ 319209746Sjkim error = copyin((caddr_t)(intptr_t)uap->arg, (caddr_t)&fl, 32067754Smsmith sizeof(fl)); 32167754Smsmith if (error) 32267754Smsmith return (error); 323209746Sjkim if (fl.l_type != F_RDLCK && fl.l_type != F_WRLCK && 324209746Sjkim fl.l_type != F_UNLCK) 325209746Sjkim return (EINVAL); 326209746Sjkim if (fl.l_whence == SEEK_CUR) 327209746Sjkim fl.l_start += fp->f_offset; 32867754Smsmith if ((error = VOP_ADVLOCK(vp,(caddr_t)p->p_leader,F_GETLK,&fl,F_POSIX))) 32967754Smsmith return (error); 330197104Sjkim return (copyout((caddr_t)&fl, (caddr_t)(intptr_t)uap->arg, 33167754Smsmith sizeof(fl))); 332197104Sjkim 33367754Smsmith default: 33467754Smsmith return (EINVAL); 33567754Smsmith } 33667754Smsmith /* NOTREACHED */ 33767754Smsmith} 33867754Smsmith 33967754Smsmith/* 34067754Smsmith * Common code for dup, dup2, and fcntl(F_DUPFD). 34167754Smsmith */ 34267754Smsmithstatic int 34383174Smsmithfinishdup(fdp, old, new, retval) 34467754Smsmith register struct filedesc *fdp; 34567754Smsmith register int old, new; 34667754Smsmith register_t *retval; 34767754Smsmith{ 34887031Smsmith register struct file *fp; 34987031Smsmith 35067754Smsmith fp = fdp->fd_ofiles[old]; 351151937Sjkim fdp->fd_ofiles[new] = fp; 352151937Sjkim fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; 353151937Sjkim fhold(fp); 35487031Smsmith if (new > fdp->fd_lastfile) 35567754Smsmith fdp->fd_lastfile = new; 35667754Smsmith *retval = new; 35767754Smsmith return (0); 35867754Smsmith} 35967754Smsmith 36067754Smsmith/* 36183174Smsmith * If sigio is on the list associated with a process or process group, 36291116Smsmith * disable signalling from the device, remove sigio from the list and 36367754Smsmith * free sigio. 364151937Sjkim */ 36567754Smsmithvoid 36667754Smsmithfunsetown(sigio) 36767754Smsmith struct sigio *sigio; 368167802Sjkim{ 36967754Smsmith int s; 37067754Smsmith 37167754Smsmith if (sigio == NULL) 37267754Smsmith return; 373209746Sjkim s = splhigh(); 374209746Sjkim *(sigio->sio_myref) = NULL; 375209746Sjkim splx(s); 376209746Sjkim if (sigio->sio_pgid < 0) { 37767754Smsmith SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio, 378209746Sjkim sigio, sio_pgsigio); 379209746Sjkim } else /* if ((*sigiop)->sio_pgid > 0) */ { 380209746Sjkim SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio, 381209746Sjkim sigio, sio_pgsigio); 382209746Sjkim } 383209746Sjkim crfree(sigio->sio_ucred); 384209746Sjkim FREE(sigio, M_SIGIO); 385209746Sjkim} 386209746Sjkim 387209746Sjkim/* Free a list of sigio structures. */ 388298714Sjkimvoid 389298714Sjkimfunsetownlst(sigiolst) 390209746Sjkim struct sigiolst *sigiolst; 39167754Smsmith{ 39267754Smsmith struct sigio *sigio; 39387031Smsmith 39467754Smsmith while ((sigio = SLIST_FIRST(sigiolst)) != NULL) 395209746Sjkim funsetown(sigio); 396209746Sjkim} 39767754Smsmith 398209746Sjkim/* 39967754Smsmith * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg). 40067754Smsmith * 40167754Smsmith * After permission checking, add a sigio structure to the sigio list for 40267754Smsmith * the process or process group. 40367754Smsmith */ 40467754Smsmithint 405209746Sjkimfsetown(pgid, sigiop) 406209746Sjkim pid_t pgid; 407209746Sjkim struct sigio **sigiop; 40867754Smsmith{ 40967754Smsmith struct proc *proc; 41067754Smsmith struct pgrp *pgrp; 41167754Smsmith struct sigio *sigio; 41267754Smsmith int s; 41367754Smsmith 41467754Smsmith if (pgid == 0) { 41567754Smsmith funsetown(*sigiop); 41667754Smsmith return (0); 417107325Siwasaki } 418107325Siwasaki if (pgid > 0) { 41967754Smsmith proc = pfind(pgid); 420129684Snjl if (proc == NULL) 421127175Snjl return (ESRCH); 422127175Snjl 423123315Snjl /* 424127175Snjl * Policy - Don't allow a process to FSETOWN a process 42567754Smsmith * in another session. 42667754Smsmith * 42767754Smsmith * Remove this test to allow maximum flexibility or 42867754Smsmith * restrict FSETOWN to the current process or process 42967754Smsmith * group for maximum safety. 43067754Smsmith */ 43167754Smsmith if (proc->p_session != curproc->p_session) 43267754Smsmith return (EPERM); 43367754Smsmith 43467754Smsmith pgrp = NULL; 43567754Smsmith } else /* if (pgid < 0) */ { 43667754Smsmith pgrp = pgfind(-pgid); 43767754Smsmith if (pgrp == NULL) 43891116Smsmith return (ESRCH); 43991116Smsmith 44067754Smsmith /* 44167754Smsmith * Policy - Don't allow a process to FSETOWN a process 44267754Smsmith * in another session. 44367754Smsmith * 44467754Smsmith * Remove this test to allow maximum flexibility or 44567754Smsmith * restrict FSETOWN to the current process or process 44667754Smsmith * group for maximum safety. 44767754Smsmith */ 448209746Sjkim if (pgrp->pg_session != curproc->p_session) 44967754Smsmith return (EPERM); 45067754Smsmith 451167802Sjkim proc = NULL; 45267754Smsmith } 45367754Smsmith funsetown(*sigiop); 45467754Smsmith MALLOC(sigio, struct sigio *, sizeof(struct sigio), M_SIGIO, M_WAITOK); 45567754Smsmith if (pgid > 0) { 45667754Smsmith SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio); 45767754Smsmith sigio->sio_proc = proc; 45867754Smsmith } else { 459193267Sjkim SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio); 460193267Sjkim sigio->sio_pgrp = pgrp; 461209746Sjkim } 462209746Sjkim sigio->sio_pgid = pgid; 46367754Smsmith crhold(curproc->p_ucred); 46467754Smsmith sigio->sio_ucred = curproc->p_ucred; 46567754Smsmith /* It would be convenient if p_ruid was in ucred. */ 466209746Sjkim sigio->sio_ruid = curproc->p_cred->p_ruid; 46767754Smsmith sigio->sio_myref = sigiop; 468167802Sjkim s = splhigh(); 469209746Sjkim *sigiop = sigio; 47067754Smsmith splx(s); 47167754Smsmith return (0); 472197104Sjkim} 473197104Sjkim 474197104Sjkim/* 475197104Sjkim * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg). 476209746Sjkim */ 477209746Sjkimpid_t 478209746Sjkimfgetown(sigio) 479209746Sjkim struct sigio *sigio; 48067754Smsmith{ 48167754Smsmith return (sigio != NULL ? sigio->sio_pgid : 0); 48267754Smsmith} 48367754Smsmith 48467754Smsmith/* 48567754Smsmith * Close a file descriptor. 48667754Smsmith */ 48767754Smsmith#ifndef _SYS_SYSPROTO_H_ 48867754Smsmithstruct close_args { 48967754Smsmith int fd; 49067754Smsmith}; 49167754Smsmith#endif 49283174Smsmith/* ARGSUSED */ 49367754Smsmithint 49467754Smsmithclose(p, uap) 49567754Smsmith struct proc *p; 496241973Sjkim struct close_args *uap; 49791116Smsmith{ 49867754Smsmith register struct filedesc *fdp = p->p_fd; 49967754Smsmith register struct file *fp; 50067754Smsmith register int fd = uap->fd; 50199679Siwasaki register u_char *pf; 50267754Smsmith 50367754Smsmith if ((unsigned)fd >= fdp->fd_nfiles || 50467754Smsmith (fp = fdp->fd_ofiles[fd]) == NULL) 50584491Smsmith return (EBADF); 50684491Smsmith pf = (u_char *)&fdp->fd_ofileflags[fd]; 507217365Sjkim if (*pf & UF_MAPPED) 50867754Smsmith (void) munmapfd(p, fd); 50967754Smsmith fdp->fd_ofiles[fd] = NULL; 510167802Sjkim while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 51167754Smsmith fdp->fd_lastfile--; 51267754Smsmith if (fd < fdp->fd_freefile) 51367754Smsmith fdp->fd_freefile = fd; 51467754Smsmith *pf = 0; 51599679Siwasaki if (fd < fdp->fd_knlistsize) 51667754Smsmith knote_fdclose(p, fd); 51767754Smsmith return (closef(fp, p)); 518217365Sjkim} 519217365Sjkim 520217365Sjkim#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 521217365Sjkim/* 522217365Sjkim * Return status information about a file descriptor. 523217365Sjkim */ 524217365Sjkim#ifndef _SYS_SYSPROTO_H_ 525217365Sjkimstruct ofstat_args { 52667754Smsmith int fd; 52767754Smsmith struct ostat *sb; 52867754Smsmith}; 52967754Smsmith#endif 53067754Smsmith/* ARGSUSED */ 53167754Smsmithint 53285756Smsmithofstat(p, uap) 53385756Smsmith struct proc *p; 534193267Sjkim register struct ofstat_args *uap; 53567754Smsmith{ 53667754Smsmith register struct filedesc *fdp = p->p_fd; 53785756Smsmith register struct file *fp; 53867754Smsmith struct stat ub; 53985756Smsmith struct ostat oub; 54067754Smsmith int error; 54185756Smsmith 54267754Smsmith if ((unsigned)uap->fd >= fdp->fd_nfiles || 543193267Sjkim (fp = fdp->fd_ofiles[uap->fd]) == NULL) 54467754Smsmith return (EBADF); 54567754Smsmith error = fo_stat(fp, &ub, p); 54685756Smsmith if (error == 0) { 54785756Smsmith cvtstat(&ub, &oub); 54867754Smsmith error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub)); 54967754Smsmith } 550138287Smarks return (error); 551138287Smarks} 55267754Smsmith#endif /* COMPAT_43 || COMPAT_SUNOS */ 55367754Smsmith 55467754Smsmith/* 55567754Smsmith * Return status information about a file descriptor. 55667754Smsmith */ 55785756Smsmith#ifndef _SYS_SYSPROTO_H_ 55885756Smsmithstruct fstat_args { 55967754Smsmith int fd; 56067754Smsmith struct stat *sb; 56167754Smsmith}; 56267754Smsmith#endif 56367754Smsmith/* ARGSUSED */ 56467754Smsmithint 56567754Smsmithfstat(p, uap) 56667754Smsmith struct proc *p; 56767754Smsmith register struct fstat_args *uap; 56885756Smsmith{ 56967754Smsmith register struct filedesc *fdp = p->p_fd; 57067754Smsmith register struct file *fp; 57167754Smsmith struct stat ub; 57285756Smsmith int error; 57367754Smsmith 574209746Sjkim if ((unsigned)uap->fd >= fdp->fd_nfiles || 57567754Smsmith (fp = fdp->fd_ofiles[uap->fd]) == NULL) 57667754Smsmith return (EBADF); 57767754Smsmith error = fo_stat(fp, &ub, p); 578217365Sjkim if (error == 0) 57999679Siwasaki error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub)); 58067754Smsmith return (error); 58167754Smsmith} 58267754Smsmith 58367754Smsmith/* 58467754Smsmith * Return status information about a file descriptor. 58567754Smsmith */ 58667754Smsmith#ifndef _SYS_SYSPROTO_H_ 58783174Smsmithstruct nfstat_args { 58867754Smsmith int fd; 58983174Smsmith struct nstat *sb; 59067754Smsmith}; 59167754Smsmith#endif 592241973Sjkim/* ARGSUSED */ 59367754Smsmithint 59467754Smsmithnfstat(p, uap) 595167802Sjkim struct proc *p; 596167802Sjkim register struct nfstat_args *uap; 59767754Smsmith{ 59867754Smsmith register struct filedesc *fdp = p->p_fd; 59999679Siwasaki register struct file *fp; 60067754Smsmith struct stat ub; 601151937Sjkim struct nstat nub; 60267754Smsmith int error; 60367754Smsmith 60491116Smsmith if ((unsigned)uap->fd >= fdp->fd_nfiles || 605167802Sjkim (fp = fdp->fd_ofiles[uap->fd]) == NULL) 60667754Smsmith return (EBADF); 607167802Sjkim error = fo_stat(fp, &ub, p); 60867754Smsmith if (error == 0) { 60967754Smsmith cvtnstat(&ub, &nub); 610167802Sjkim error = copyout((caddr_t)&nub, (caddr_t)uap->sb, sizeof (nub)); 61167754Smsmith } 61267754Smsmith return (error); 613151937Sjkim} 614151937Sjkim 615151937Sjkim/* 616151937Sjkim * Return pathconf information about a file descriptor. 617151937Sjkim */ 618167802Sjkim#ifndef _SYS_SYSPROTO_H_ 61967754Smsmithstruct fpathconf_args { 620167802Sjkim int fd; 621167802Sjkim int name; 622167802Sjkim}; 623167802Sjkim#endif 624167802Sjkim/* ARGSUSED */ 625167802Sjkimint 626167802Sjkimfpathconf(p, uap) 627167802Sjkim struct proc *p; 628167802Sjkim register struct fpathconf_args *uap; 629167802Sjkim{ 630167802Sjkim struct filedesc *fdp = p->p_fd; 63167754Smsmith struct file *fp; 63285756Smsmith struct vnode *vp; 63367754Smsmith 63467754Smsmith if ((unsigned)uap->fd >= fdp->fd_nfiles || 63567754Smsmith (fp = fdp->fd_ofiles[uap->fd]) == NULL) 63667754Smsmith return (EBADF); 63791116Smsmith switch (fp->f_type) { 63891116Smsmith 63991116Smsmith case DTYPE_PIPE: 64091116Smsmith case DTYPE_SOCKET: 641193267Sjkim if (uap->name != _PC_PIPE_BUF) 64285756Smsmith return (EINVAL); 64391116Smsmith p->p_retval[0] = PIPE_BUF; 64491116Smsmith return (0); 645167802Sjkim 646197104Sjkim case DTYPE_FIFO: 64791116Smsmith case DTYPE_VNODE: 64891116Smsmith vp = (struct vnode *)fp->f_data; 64991116Smsmith return (VOP_PATHCONF(vp, uap->name, p->p_retval)); 65067754Smsmith 65167754Smsmith default: 65267754Smsmith return (EOPNOTSUPP); 65367754Smsmith } 65491116Smsmith /*NOTREACHED*/ 65585756Smsmith} 65685756Smsmith 65767754Smsmith/* 65867754Smsmith * Allocate a file descriptor for the process. 65985756Smsmith */ 66067754Smsmithstatic int fdexpand; 661193267SjkimSYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, ""); 66267754Smsmith 66367754Smsmithint 66485756Smsmithfdalloc(p, want, result) 66585756Smsmith struct proc *p; 66667754Smsmith int want; 66767754Smsmith int *result; 668138287Smarks{ 669138287Smarks register struct filedesc *fdp = p->p_fd; 67067754Smsmith register int i; 67167754Smsmith int lim, last, nfiles; 67267754Smsmith struct file **newofile; 67391116Smsmith char *newofileflags; 67467754Smsmith 67567754Smsmith /* 67667754Smsmith * Search for a free descriptor starting at the higher 67767754Smsmith * of want or fd_freefile. If that fails, consider 67867754Smsmith * expanding the ofile array. 67985756Smsmith */ 68085756Smsmith lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 68167754Smsmith for (;;) { 68267754Smsmith last = min(fdp->fd_nfiles, lim); 68367754Smsmith if ((i = want) < fdp->fd_freefile) 68467754Smsmith i = fdp->fd_freefile; 68567754Smsmith for (; i < last; i++) { 68667754Smsmith if (fdp->fd_ofiles[i] == NULL) { 68791116Smsmith fdp->fd_ofileflags[i] = 0; 68867754Smsmith if (i > fdp->fd_lastfile) 68967754Smsmith fdp->fd_lastfile = i; 69067754Smsmith if (want <= fdp->fd_freefile) 69185756Smsmith fdp->fd_freefile = i; 69267754Smsmith *result = i; 69367754Smsmith return (0); 69467754Smsmith } 69585756Smsmith } 69667754Smsmith 697209746Sjkim /* 69867754Smsmith * No space in current array. Expand? 69967754Smsmith */ 70067754Smsmith if (fdp->fd_nfiles >= lim) 701167802Sjkim return (EMFILE); 70299679Siwasaki if (fdp->fd_nfiles < NDEXTENT) 70367754Smsmith nfiles = NDEXTENT; 704 else 705 nfiles = 2 * fdp->fd_nfiles; 706 MALLOC(newofile, struct file **, nfiles * OFILESIZE, 707 M_FILEDESC, M_WAITOK); 708 newofileflags = (char *) &newofile[nfiles]; 709 /* 710 * Copy the existing ofile and ofileflags arrays 711 * and zero the new portion of each array. 712 */ 713 bcopy(fdp->fd_ofiles, newofile, 714 (i = sizeof(struct file *) * fdp->fd_nfiles)); 715 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i); 716 bcopy(fdp->fd_ofileflags, newofileflags, 717 (i = sizeof(char) * fdp->fd_nfiles)); 718 bzero(newofileflags + i, nfiles * sizeof(char) - i); 719 if (fdp->fd_nfiles > NDFILE) 720 FREE(fdp->fd_ofiles, M_FILEDESC); 721 fdp->fd_ofiles = newofile; 722 fdp->fd_ofileflags = newofileflags; 723 fdp->fd_nfiles = nfiles; 724 fdexpand++; 725 } 726 return (0); 727} 728 729/* 730 * Check to see whether n user file descriptors 731 * are available to the process p. 732 */ 733int 734fdavail(p, n) 735 struct proc *p; 736 register int n; 737{ 738 register struct filedesc *fdp = p->p_fd; 739 register struct file **fpp; 740 register int i, lim, last; 741 742 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 743 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) 744 return (1); 745 746 last = min(fdp->fd_nfiles, lim); 747 fpp = &fdp->fd_ofiles[fdp->fd_freefile]; 748 for (i = last - fdp->fd_freefile; --i >= 0; fpp++) 749 if (*fpp == NULL && --n <= 0) 750 return (1); 751 return (0); 752} 753 754/* 755 * Create a new open file structure and allocate 756 * a file decriptor for the process that refers to it. 757 */ 758int 759falloc(p, resultfp, resultfd) 760 register struct proc *p; 761 struct file **resultfp; 762 int *resultfd; 763{ 764 register struct file *fp, *fq; 765 int error, i; 766 767 if ((error = fdalloc(p, 0, &i))) 768 return (error); 769 if (nfiles >= maxfiles) { 770 tablefull("file"); 771 return (ENFILE); 772 } 773 /* 774 * Allocate a new file descriptor. 775 * If the process has file descriptor zero open, add to the list 776 * of open files at that point, otherwise put it at the front of 777 * the list of open files. 778 */ 779 nfiles++; 780 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK); 781 bzero(fp, sizeof(struct file)); 782 fp->f_count = 1; 783 fp->f_cred = p->p_ucred; 784 fp->f_ops = &badfileops; 785 fp->f_seqcount = 1; 786 crhold(fp->f_cred); 787 if ((fq = p->p_fd->fd_ofiles[0])) { 788 LIST_INSERT_AFTER(fq, fp, f_list); 789 } else { 790 LIST_INSERT_HEAD(&filehead, fp, f_list); 791 } 792 p->p_fd->fd_ofiles[i] = fp; 793 if (resultfp) 794 *resultfp = fp; 795 if (resultfd) 796 *resultfd = i; 797 return (0); 798} 799 800/* 801 * Free a file descriptor. 802 */ 803void 804ffree(fp) 805 register struct file *fp; 806{ 807 LIST_REMOVE(fp, f_list); 808 crfree(fp->f_cred); 809#if defined(DIAGNOSTIC) || defined(INVARIANTS) 810 fp->f_count = 0; 811#endif 812 nfiles--; 813 FREE(fp, M_FILE); 814} 815 816/* 817 * Build a new filedesc structure. 818 */ 819struct filedesc * 820fdinit(p) 821 struct proc *p; 822{ 823 register struct filedesc0 *newfdp; 824 register struct filedesc *fdp = p->p_fd; 825 826 MALLOC(newfdp, struct filedesc0 *, sizeof(struct filedesc0), 827 M_FILEDESC, M_WAITOK); 828 bzero(newfdp, sizeof(struct filedesc0)); 829 newfdp->fd_fd.fd_cdir = fdp->fd_cdir; 830 if (newfdp->fd_fd.fd_cdir) 831 VREF(newfdp->fd_fd.fd_cdir); 832 newfdp->fd_fd.fd_rdir = fdp->fd_rdir; 833 if (newfdp->fd_fd.fd_rdir) 834 VREF(newfdp->fd_fd.fd_rdir); 835 newfdp->fd_fd.fd_jdir = fdp->fd_jdir; 836 if (newfdp->fd_fd.fd_jdir) 837 VREF(newfdp->fd_fd.fd_jdir); 838 839 /* Create the file descriptor table. */ 840 newfdp->fd_fd.fd_refcnt = 1; 841 newfdp->fd_fd.fd_cmask = cmask; 842 newfdp->fd_fd.fd_ofiles = newfdp->fd_dfiles; 843 newfdp->fd_fd.fd_ofileflags = newfdp->fd_dfileflags; 844 newfdp->fd_fd.fd_nfiles = NDFILE; 845 newfdp->fd_fd.fd_knlistsize = -1; 846 847 return (&newfdp->fd_fd); 848} 849 850/* 851 * Share a filedesc structure. 852 */ 853struct filedesc * 854fdshare(p) 855 struct proc *p; 856{ 857 p->p_fd->fd_refcnt++; 858 return (p->p_fd); 859} 860 861/* 862 * Copy a filedesc structure. 863 */ 864struct filedesc * 865fdcopy(p) 866 struct proc *p; 867{ 868 register struct filedesc *newfdp, *fdp = p->p_fd; 869 register struct file **fpp; 870 register int i; 871 872 /* Certain daemons might not have file descriptors. */ 873 if (fdp == NULL) 874 return (NULL); 875 876 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), 877 M_FILEDESC, M_WAITOK); 878 bcopy(fdp, newfdp, sizeof(struct filedesc)); 879 if (newfdp->fd_cdir) 880 VREF(newfdp->fd_cdir); 881 if (newfdp->fd_rdir) 882 VREF(newfdp->fd_rdir); 883 if (newfdp->fd_jdir) 884 VREF(newfdp->fd_jdir); 885 newfdp->fd_refcnt = 1; 886 887 /* 888 * If the number of open files fits in the internal arrays 889 * of the open file structure, use them, otherwise allocate 890 * additional memory for the number of descriptors currently 891 * in use. 892 */ 893 if (newfdp->fd_lastfile < NDFILE) { 894 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles; 895 newfdp->fd_ofileflags = 896 ((struct filedesc0 *) newfdp)->fd_dfileflags; 897 i = NDFILE; 898 } else { 899 /* 900 * Compute the smallest multiple of NDEXTENT needed 901 * for the file descriptors currently in use, 902 * allowing the table to shrink. 903 */ 904 i = newfdp->fd_nfiles; 905 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2) 906 i /= 2; 907 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE, 908 M_FILEDESC, M_WAITOK); 909 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i]; 910 } 911 newfdp->fd_nfiles = i; 912 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); 913 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); 914 915 /* 916 * kq descriptors cannot be copied. 917 */ 918 if (newfdp->fd_knlistsize != -1) { 919 fpp = newfdp->fd_ofiles; 920 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) 921 if (*fpp != NULL && (*fpp)->f_type == DTYPE_KQUEUE) 922 *fpp = NULL; 923 newfdp->fd_knlist = NULL; 924 newfdp->fd_knlistsize = -1; 925 newfdp->fd_knhash = NULL; 926 newfdp->fd_knhashmask = 0; 927 } 928 929 fpp = newfdp->fd_ofiles; 930 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) 931 if (*fpp != NULL) 932 fhold(*fpp); 933 return (newfdp); 934} 935 936/* 937 * Release a filedesc structure. 938 */ 939void 940fdfree(p) 941 struct proc *p; 942{ 943 register struct filedesc *fdp = p->p_fd; 944 struct file **fpp; 945 register int i; 946 947 /* Certain daemons might not have file descriptors. */ 948 if (fdp == NULL) 949 return; 950 951 if (--fdp->fd_refcnt > 0) 952 return; 953 fpp = fdp->fd_ofiles; 954 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) 955 if (*fpp) 956 (void) closef(*fpp, p); 957 if (fdp->fd_nfiles > NDFILE) 958 FREE(fdp->fd_ofiles, M_FILEDESC); 959 if (fdp->fd_cdir) 960 vrele(fdp->fd_cdir); 961 if (fdp->fd_rdir) 962 vrele(fdp->fd_rdir); 963 if (fdp->fd_jdir) 964 vrele(fdp->fd_jdir); 965 if (fdp->fd_knlist) 966 FREE(fdp->fd_knlist, M_TEMP); 967 if (fdp->fd_knhash) 968 FREE(fdp->fd_knhash, M_TEMP); 969 FREE(fdp, M_FILEDESC); 970} 971 972/* 973 * For setugid programs, we don't want to people to use that setugidness 974 * to generate error messages which write to a file which otherwise would 975 * otherwise be off-limits to the process. 976 * 977 * This is a gross hack to plug the hole. A better solution would involve 978 * a special vop or other form of generalized access control mechanism. We 979 * go ahead and just reject all procfs file systems accesses as dangerous. 980 * 981 * Since setugidsafety calls this only for fd 0, 1 and 2, this check is 982 * sufficient. We also don't for check setugidness since we know we are. 983 */ 984static int 985is_unsafe(struct file *fp) 986{ 987 if (fp->f_type == DTYPE_VNODE && 988 ((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS) 989 return (1); 990 return (0); 991} 992 993/* 994 * Make this setguid thing safe, if at all possible. 995 */ 996void 997setugidsafety(p) 998 struct proc *p; 999{ 1000 struct filedesc *fdp = p->p_fd; 1001 struct file **fpp; 1002 char *fdfp; 1003 register int i; 1004 1005 /* Certain daemons might not have file descriptors. */ 1006 if (fdp == NULL) 1007 return; 1008 1009 fpp = fdp->fd_ofiles; 1010 fdfp = fdp->fd_ofileflags; 1011 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) { 1012 if (i > 2) 1013 break; 1014 if (*fpp != NULL && is_unsafe(*fpp)) { 1015 if ((*fdfp & UF_MAPPED) != 0) 1016 (void) munmapfd(p, i); 1017 (void) closef(*fpp, p); 1018 *fpp = NULL; 1019 *fdfp = 0; 1020 if (i < fdp->fd_freefile) 1021 fdp->fd_freefile = i; 1022 } 1023 } 1024 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1025 fdp->fd_lastfile--; 1026} 1027 1028/* 1029 * Close any files on exec? 1030 */ 1031void 1032fdcloseexec(p) 1033 struct proc *p; 1034{ 1035 struct filedesc *fdp = p->p_fd; 1036 struct file **fpp; 1037 char *fdfp; 1038 register int i; 1039 1040 /* Certain daemons might not have file descriptors. */ 1041 if (fdp == NULL) 1042 return; 1043 1044 fpp = fdp->fd_ofiles; 1045 fdfp = fdp->fd_ofileflags; 1046 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) 1047 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) { 1048 if (*fdfp & UF_MAPPED) 1049 (void) munmapfd(p, i); 1050 (void) closef(*fpp, p); 1051 *fpp = NULL; 1052 *fdfp = 0; 1053 if (i < fdp->fd_freefile) 1054 fdp->fd_freefile = i; 1055 } 1056 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1057 fdp->fd_lastfile--; 1058} 1059 1060/* 1061 * Internal form of close. 1062 * Decrement reference count on file structure. 1063 * Note: p may be NULL when closing a file 1064 * that was being passed in a message. 1065 */ 1066int 1067closef(fp, p) 1068 register struct file *fp; 1069 register struct proc *p; 1070{ 1071 struct vnode *vp; 1072 struct flock lf; 1073 1074 if (fp == NULL) 1075 return (0); 1076 /* 1077 * POSIX record locking dictates that any close releases ALL 1078 * locks owned by this process. This is handled by setting 1079 * a flag in the unlock to free ONLY locks obeying POSIX 1080 * semantics, and not to free BSD-style file locks. 1081 * If the descriptor was in a message, POSIX-style locks 1082 * aren't passed with the descriptor. 1083 */ 1084 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) { 1085 lf.l_whence = SEEK_SET; 1086 lf.l_start = 0; 1087 lf.l_len = 0; 1088 lf.l_type = F_UNLCK; 1089 vp = (struct vnode *)fp->f_data; 1090 (void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &lf, F_POSIX); 1091 } 1092 return (fdrop(fp, p)); 1093} 1094 1095int 1096fdrop(fp, p) 1097 struct file *fp; 1098 struct proc *p; 1099{ 1100 struct flock lf; 1101 struct vnode *vp; 1102 int error; 1103 1104 if (--fp->f_count > 0) 1105 return (0); 1106 if (fp->f_count < 0) 1107 panic("fdrop: count < 0"); 1108 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) { 1109 lf.l_whence = SEEK_SET; 1110 lf.l_start = 0; 1111 lf.l_len = 0; 1112 lf.l_type = F_UNLCK; 1113 vp = (struct vnode *)fp->f_data; 1114 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); 1115 } 1116 if (fp->f_ops != &badfileops) 1117 error = fo_close(fp, p); 1118 else 1119 error = 0; 1120 ffree(fp); 1121 return (error); 1122} 1123 1124/* 1125 * Apply an advisory lock on a file descriptor. 1126 * 1127 * Just attempt to get a record lock of the requested type on 1128 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). 1129 */ 1130#ifndef _SYS_SYSPROTO_H_ 1131struct flock_args { 1132 int fd; 1133 int how; 1134}; 1135#endif 1136/* ARGSUSED */ 1137int 1138flock(p, uap) 1139 struct proc *p; 1140 register struct flock_args *uap; 1141{ 1142 register struct filedesc *fdp = p->p_fd; 1143 register struct file *fp; 1144 struct vnode *vp; 1145 struct flock lf; 1146 1147 if ((unsigned)uap->fd >= fdp->fd_nfiles || 1148 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 1149 return (EBADF); 1150 if (fp->f_type != DTYPE_VNODE) 1151 return (EOPNOTSUPP); 1152 vp = (struct vnode *)fp->f_data; 1153 lf.l_whence = SEEK_SET; 1154 lf.l_start = 0; 1155 lf.l_len = 0; 1156 if (uap->how & LOCK_UN) { 1157 lf.l_type = F_UNLCK; 1158 fp->f_flag &= ~FHASLOCK; 1159 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK)); 1160 } 1161 if (uap->how & LOCK_EX) 1162 lf.l_type = F_WRLCK; 1163 else if (uap->how & LOCK_SH) 1164 lf.l_type = F_RDLCK; 1165 else 1166 return (EBADF); 1167 fp->f_flag |= FHASLOCK; 1168 if (uap->how & LOCK_NB) 1169 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK)); 1170 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT)); 1171} 1172 1173/* 1174 * File Descriptor pseudo-device driver (/dev/fd/). 1175 * 1176 * Opening minor device N dup()s the file (if any) connected to file 1177 * descriptor N belonging to the calling process. Note that this driver 1178 * consists of only the ``open()'' routine, because all subsequent 1179 * references to this file will be direct to the other driver. 1180 */ 1181/* ARGSUSED */ 1182static int 1183fdopen(dev, mode, type, p) 1184 dev_t dev; 1185 int mode, type; 1186 struct proc *p; 1187{ 1188 1189 /* 1190 * XXX Kludge: set curproc->p_dupfd to contain the value of the 1191 * the file descriptor being sought for duplication. The error 1192 * return ensures that the vnode for this device will be released 1193 * by vn_open. Open will detect this special error and take the 1194 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN 1195 * will simply report the error. 1196 */ 1197 p->p_dupfd = minor(dev); 1198 return (ENODEV); 1199} 1200 1201/* 1202 * Duplicate the specified descriptor to a free descriptor. 1203 */ 1204int 1205dupfdopen(fdp, indx, dfd, mode, error) 1206 register struct filedesc *fdp; 1207 register int indx, dfd; 1208 int mode; 1209 int error; 1210{ 1211 register struct file *wfp; 1212 struct file *fp; 1213 1214 /* 1215 * If the to-be-dup'd fd number is greater than the allowed number 1216 * of file descriptors, or the fd to be dup'd has already been 1217 * closed, reject. Note, check for new == old is necessary as 1218 * falloc could allocate an already closed to-be-dup'd descriptor 1219 * as the new descriptor. 1220 */ 1221 fp = fdp->fd_ofiles[indx]; 1222 if ((u_int)dfd >= fdp->fd_nfiles || 1223 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp) 1224 return (EBADF); 1225 1226 /* 1227 * There are two cases of interest here. 1228 * 1229 * For ENODEV simply dup (dfd) to file descriptor 1230 * (indx) and return. 1231 * 1232 * For ENXIO steal away the file structure from (dfd) and 1233 * store it in (indx). (dfd) is effectively closed by 1234 * this operation. 1235 * 1236 * Any other error code is just returned. 1237 */ 1238 switch (error) { 1239 case ENODEV: 1240 /* 1241 * Check that the mode the file is being opened for is a 1242 * subset of the mode of the existing descriptor. 1243 */ 1244 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) 1245 return (EACCES); 1246 fdp->fd_ofiles[indx] = wfp; 1247 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 1248 fhold(wfp); 1249 if (indx > fdp->fd_lastfile) 1250 fdp->fd_lastfile = indx; 1251 return (0); 1252 1253 case ENXIO: 1254 /* 1255 * Steal away the file pointer from dfd, and stuff it into indx. 1256 */ 1257 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; 1258 fdp->fd_ofiles[dfd] = NULL; 1259 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 1260 fdp->fd_ofileflags[dfd] = 0; 1261 /* 1262 * Complete the clean up of the filedesc structure by 1263 * recomputing the various hints. 1264 */ 1265 if (indx > fdp->fd_lastfile) 1266 fdp->fd_lastfile = indx; 1267 else 1268 while (fdp->fd_lastfile > 0 && 1269 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 1270 fdp->fd_lastfile--; 1271 if (dfd < fdp->fd_freefile) 1272 fdp->fd_freefile = dfd; 1273 return (0); 1274 1275 default: 1276 return (error); 1277 } 1278 /* NOTREACHED */ 1279} 1280 1281/* 1282 * Get file structures. 1283 */ 1284static int 1285sysctl_kern_file(SYSCTL_HANDLER_ARGS) 1286{ 1287 int error; 1288 struct file *fp; 1289 1290 if (!req->oldptr) { 1291 /* 1292 * overestimate by 10 files 1293 */ 1294 return (SYSCTL_OUT(req, 0, sizeof(filehead) + 1295 (nfiles + 10) * sizeof(struct file))); 1296 } 1297 1298 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead)); 1299 if (error) 1300 return (error); 1301 1302 /* 1303 * followed by an array of file structures 1304 */ 1305 LIST_FOREACH(fp, &filehead, f_list) { 1306 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file)); 1307 if (error) 1308 return (error); 1309 } 1310 return (0); 1311} 1312 1313SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 1314 0, 0, sysctl_kern_file, "S,file", "Entire file table"); 1315 1316SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, 1317 &maxfilesperproc, 0, "Maximum files allowed open per process"); 1318 1319SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, 1320 &maxfiles, 0, "Maximum number of files"); 1321 1322#ifdef DEVFS 1323static void 1324fildesc_clone(void *arg, char *name, int namelen, dev_t *dev) 1325{ 1326 int u; 1327 1328 if (*dev != NODEV) 1329 return; 1330 if (devfs_stdclone(name, NULL, "fd/", &u) != 1) 1331 return; 1332 if (u <= 2) 1333 return; 1334 *dev = make_dev(&fildesc_cdevsw, u, UID_BIN, GID_BIN, 0666, name); 1335 return; 1336} 1337#endif 1338 1339static void 1340fildesc_drvinit(void *unused) 1341{ 1342 dev_t dev; 1343 1344 dev = make_dev(&fildesc_cdevsw, 0, UID_BIN, GID_BIN, 0666, "fd/0"); 1345 make_dev_alias(dev, "stdin"); 1346 dev = make_dev(&fildesc_cdevsw, 1, UID_BIN, GID_BIN, 0666, "fd/1"); 1347 make_dev_alias(dev, "stdout"); 1348 dev = make_dev(&fildesc_cdevsw, 2, UID_BIN, GID_BIN, 0666, "fd/2"); 1349 make_dev_alias(dev, "stderr"); 1350#ifdef DEVFS 1351 EVENTHANDLER_REGISTER(devfs_clone, fildesc_clone, 0, 1000); 1352#else 1353 { 1354 int fd; 1355 1356 for (fd = 3; fd < NUMFDESC; fd++) 1357 make_dev(&fildesc_cdevsw, fd, UID_BIN, GID_BIN, 0666, "fd/%d", fd); 1358 } 1359#endif 1360} 1361 1362struct fileops badfileops = { 1363 badfo_readwrite, 1364 badfo_readwrite, 1365 badfo_ioctl, 1366 badfo_poll, 1367 badfo_stat, 1368 badfo_close 1369}; 1370 1371static int 1372badfo_readwrite(fp, uio, cred, flags, p) 1373 struct file *fp; 1374 struct uio *uio; 1375 struct ucred *cred; 1376 struct proc *p; 1377 int flags; 1378{ 1379 1380 return (EBADF); 1381} 1382 1383static int 1384badfo_ioctl(fp, com, data, p) 1385 struct file *fp; 1386 u_long com; 1387 caddr_t data; 1388 struct proc *p; 1389{ 1390 1391 return (EBADF); 1392} 1393 1394static int 1395badfo_poll(fp, events, cred, p) 1396 struct file *fp; 1397 int events; 1398 struct ucred *cred; 1399 struct proc *p; 1400{ 1401 1402 return (0); 1403} 1404 1405static int 1406badfo_stat(fp, sb, p) 1407 struct file *fp; 1408 struct stat *sb; 1409 struct proc *p; 1410{ 1411 1412 return (EBADF); 1413} 1414 1415static int 1416badfo_close(fp, p) 1417 struct file *fp; 1418 struct proc *p; 1419{ 1420 1421 return (EBADF); 1422} 1423 1424SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, 1425 fildesc_drvinit,NULL) 1426