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.21 1995/12/08 11:16:59 julian Exp $
| 39 * $Id: kern_descrip.c,v 1.22 1995/12/08 23:21:31 phk Exp $
|
40 */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/sysproto.h> 45#include <sys/conf.h> 46#include <sys/filedesc.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49#include <sys/vnode.h> 50#include <sys/proc.h> 51#include <sys/file.h> 52#include <sys/socket.h> 53#include <sys/socketvar.h> 54#include <sys/stat.h> 55#include <sys/ioctl.h> 56#include <sys/fcntl.h> 57#include <sys/malloc.h> 58#include <sys/unistd.h> 59#include <sys/resourcevar.h> 60 61#include <vm/vm.h> 62#include <vm/vm_param.h> 63#include <vm/vm_extern.h> 64 65#ifdef DEVFS 66#include <sys/devfsext.h> 67#endif /*DEVFS*/ 68 69static d_open_t fdopen; 70#define NUMFDESC 64 71 72#define CDEV_MAJOR 22 73static struct cdevsw fildesc_cdevsw = 74 { fdopen, noclose, noread, nowrite, /*22*/ 75 noioc, nostop, nullreset, nodevtotty,/*fd(!=Fd)*/ 76 noselect, nommap, nostrat }; 77
| 40 */ 41 42#include <sys/param.h> 43#include <sys/systm.h> 44#include <sys/sysproto.h> 45#include <sys/conf.h> 46#include <sys/filedesc.h> 47#include <sys/kernel.h> 48#include <sys/sysctl.h> 49#include <sys/vnode.h> 50#include <sys/proc.h> 51#include <sys/file.h> 52#include <sys/socket.h> 53#include <sys/socketvar.h> 54#include <sys/stat.h> 55#include <sys/ioctl.h> 56#include <sys/fcntl.h> 57#include <sys/malloc.h> 58#include <sys/unistd.h> 59#include <sys/resourcevar.h> 60 61#include <vm/vm.h> 62#include <vm/vm_param.h> 63#include <vm/vm_extern.h> 64 65#ifdef DEVFS 66#include <sys/devfsext.h> 67#endif /*DEVFS*/ 68 69static d_open_t fdopen; 70#define NUMFDESC 64 71 72#define CDEV_MAJOR 22 73static struct cdevsw fildesc_cdevsw = 74 { fdopen, noclose, noread, nowrite, /*22*/ 75 noioc, nostop, nullreset, nodevtotty,/*fd(!=Fd)*/ 76 noselect, nommap, nostrat }; 77
|
78int finishdup(struct filedesc *fdp, int old, int new, int *retval);
| 78static int finishdup(struct filedesc *fdp, int old, int new, int *retval);
|
79/* 80 * Descriptor management. 81 */ 82struct file *filehead; /* head of list of open files */ 83int nfiles; /* actual number of open files */ 84 85/* 86 * System calls on descriptors. 87 */ 88#ifndef _SYS_SYSPROTO_H_ 89struct getdtablesize_args { 90 int dummy; 91}; 92#endif 93/* ARGSUSED */ 94int 95getdtablesize(p, uap, retval) 96 struct proc *p; 97 struct getdtablesize_args *uap; 98 int *retval; 99{ 100 101 *retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 102 return (0); 103} 104 105/* 106 * Duplicate a file descriptor to a particular value. 107 */ 108#ifndef _SYS_SYSPROTO_H_ 109struct dup2_args { 110 u_int from; 111 u_int to; 112}; 113#endif 114/* ARGSUSED */ 115int 116dup2(p, uap, retval) 117 struct proc *p; 118 struct dup2_args *uap; 119 int *retval; 120{ 121 register struct filedesc *fdp = p->p_fd; 122 register u_int old = uap->from, new = uap->to; 123 int i, error; 124 125 if (old >= fdp->fd_nfiles || 126 fdp->fd_ofiles[old] == NULL || 127 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 128 new >= maxfilesperproc) 129 return (EBADF); 130 if (old == new) { 131 *retval = new; 132 return (0); 133 } 134 if (new >= fdp->fd_nfiles) { 135 if ((error = fdalloc(p, new, &i))) 136 return (error); 137 if (new != i) 138 panic("dup2: fdalloc"); 139 } else if (fdp->fd_ofiles[new]) { 140 if (fdp->fd_ofileflags[new] & UF_MAPPED) 141 (void) munmapfd(p, new); 142 /* 143 * dup2() must succeed even if the close has an error. 144 */ 145 (void) closef(fdp->fd_ofiles[new], p); 146 } 147 return (finishdup(fdp, (int)old, (int)new, retval)); 148} 149 150/* 151 * Duplicate a file descriptor. 152 */ 153#ifndef _SYS_SYSPROTO_H_ 154struct dup_args { 155 u_int fd; 156}; 157#endif 158/* ARGSUSED */ 159int 160dup(p, uap, retval) 161 struct proc *p; 162 struct dup_args *uap; 163 int *retval; 164{ 165 register struct filedesc *fdp; 166 u_int old; 167 int new, error; 168 169 old = uap->fd; 170 171#if 0 172 /* 173 * XXX Compatibility 174 */ 175 if (old &~ 077) { uap->fd &= 077; return (dup2(p, uap, retval)); } 176#endif 177 178 fdp = p->p_fd; 179 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) 180 return (EBADF); 181 if ((error = fdalloc(p, 0, &new))) 182 return (error); 183 return (finishdup(fdp, (int)old, new, retval)); 184} 185 186/* 187 * The file control system call. 188 */ 189#ifndef _SYS_SYSPROTO_H_ 190struct fcntl_args { 191 int fd; 192 int cmd; 193 int arg; 194}; 195#endif 196/* ARGSUSED */ 197int 198fcntl(p, uap, retval) 199 struct proc *p; 200 register struct fcntl_args *uap; 201 int *retval; 202{ 203 register struct filedesc *fdp = p->p_fd; 204 register struct file *fp; 205 register char *pop; 206 struct vnode *vp; 207 int i, tmp, error, flg = F_POSIX; 208 struct flock fl; 209 u_int newmin; 210 211 if ((unsigned)uap->fd >= fdp->fd_nfiles || 212 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 213 return (EBADF); 214 pop = &fdp->fd_ofileflags[uap->fd]; 215 switch (uap->cmd) { 216 217 case F_DUPFD: 218 newmin = uap->arg; 219 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 220 newmin >= maxfilesperproc) 221 return (EINVAL); 222 if ((error = fdalloc(p, newmin, &i))) 223 return (error); 224 return (finishdup(fdp, uap->fd, i, retval)); 225 226 case F_GETFD: 227 *retval = *pop & 1; 228 return (0); 229 230 case F_SETFD: 231 *pop = (*pop &~ 1) | (uap->arg & 1); 232 return (0); 233 234 case F_GETFL: 235 *retval = OFLAGS(fp->f_flag); 236 return (0); 237 238 case F_SETFL: 239 fp->f_flag &= ~FCNTLFLAGS; 240 fp->f_flag |= FFLAGS(uap->arg) & FCNTLFLAGS; 241 tmp = fp->f_flag & FNONBLOCK; 242 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 243 if (error) 244 return (error); 245 tmp = fp->f_flag & FASYNC; 246 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 247 if (!error) 248 return (0); 249 fp->f_flag &= ~FNONBLOCK; 250 tmp = 0; 251 (void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 252 return (error); 253 254 case F_GETOWN: 255 if (fp->f_type == DTYPE_SOCKET) { 256 *retval = ((struct socket *)fp->f_data)->so_pgid; 257 return (0); 258 } 259 error = (*fp->f_ops->fo_ioctl) 260 (fp, (int)TIOCGPGRP, (caddr_t)retval, p); 261 *retval = -*retval; 262 return (error); 263 264 case F_SETOWN: 265 if (fp->f_type == DTYPE_SOCKET) { 266 ((struct socket *)fp->f_data)->so_pgid = uap->arg; 267 return (0); 268 } 269 if (uap->arg <= 0) { 270 uap->arg = -uap->arg; 271 } else { 272 struct proc *p1 = pfind(uap->arg); 273 if (p1 == 0) 274 return (ESRCH); 275 uap->arg = p1->p_pgrp->pg_id; 276 } 277 return ((*fp->f_ops->fo_ioctl) 278 (fp, (int)TIOCSPGRP, (caddr_t)&uap->arg, p)); 279 280 case F_SETLKW: 281 flg |= F_WAIT; 282 /* Fall into F_SETLK */ 283 284 case F_SETLK: 285 if (fp->f_type != DTYPE_VNODE) 286 return (EBADF); 287 vp = (struct vnode *)fp->f_data; 288 /* Copy in the lock structure */ 289 error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl)); 290 if (error) 291 return (error); 292 if (fl.l_whence == SEEK_CUR) 293 fl.l_start += fp->f_offset; 294 switch (fl.l_type) { 295 296 case F_RDLCK: 297 if ((fp->f_flag & FREAD) == 0) 298 return (EBADF); 299 p->p_flag |= P_ADVLOCK; 300 return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg)); 301 302 case F_WRLCK: 303 if ((fp->f_flag & FWRITE) == 0) 304 return (EBADF); 305 p->p_flag |= P_ADVLOCK; 306 return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg)); 307 308 case F_UNLCK: 309 return (VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &fl, 310 F_POSIX)); 311 312 default: 313 return (EINVAL); 314 } 315 316 case F_GETLK: 317 if (fp->f_type != DTYPE_VNODE) 318 return (EBADF); 319 vp = (struct vnode *)fp->f_data; 320 /* Copy in the lock structure */ 321 error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl)); 322 if (error) 323 return (error); 324 if (fl.l_whence == SEEK_CUR) 325 fl.l_start += fp->f_offset; 326 if ((error = VOP_ADVLOCK(vp,(caddr_t)p,F_GETLK,&fl,F_POSIX))) 327 return (error); 328 return (copyout((caddr_t)&fl, (caddr_t)uap->arg, sizeof (fl))); 329 330 default: 331 return (EINVAL); 332 } 333 /* NOTREACHED */ 334} 335 336/* 337 * Common code for dup, dup2, and fcntl(F_DUPFD). 338 */
| 79/* 80 * Descriptor management. 81 */ 82struct file *filehead; /* head of list of open files */ 83int nfiles; /* actual number of open files */ 84 85/* 86 * System calls on descriptors. 87 */ 88#ifndef _SYS_SYSPROTO_H_ 89struct getdtablesize_args { 90 int dummy; 91}; 92#endif 93/* ARGSUSED */ 94int 95getdtablesize(p, uap, retval) 96 struct proc *p; 97 struct getdtablesize_args *uap; 98 int *retval; 99{ 100 101 *retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 102 return (0); 103} 104 105/* 106 * Duplicate a file descriptor to a particular value. 107 */ 108#ifndef _SYS_SYSPROTO_H_ 109struct dup2_args { 110 u_int from; 111 u_int to; 112}; 113#endif 114/* ARGSUSED */ 115int 116dup2(p, uap, retval) 117 struct proc *p; 118 struct dup2_args *uap; 119 int *retval; 120{ 121 register struct filedesc *fdp = p->p_fd; 122 register u_int old = uap->from, new = uap->to; 123 int i, error; 124 125 if (old >= fdp->fd_nfiles || 126 fdp->fd_ofiles[old] == NULL || 127 new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 128 new >= maxfilesperproc) 129 return (EBADF); 130 if (old == new) { 131 *retval = new; 132 return (0); 133 } 134 if (new >= fdp->fd_nfiles) { 135 if ((error = fdalloc(p, new, &i))) 136 return (error); 137 if (new != i) 138 panic("dup2: fdalloc"); 139 } else if (fdp->fd_ofiles[new]) { 140 if (fdp->fd_ofileflags[new] & UF_MAPPED) 141 (void) munmapfd(p, new); 142 /* 143 * dup2() must succeed even if the close has an error. 144 */ 145 (void) closef(fdp->fd_ofiles[new], p); 146 } 147 return (finishdup(fdp, (int)old, (int)new, retval)); 148} 149 150/* 151 * Duplicate a file descriptor. 152 */ 153#ifndef _SYS_SYSPROTO_H_ 154struct dup_args { 155 u_int fd; 156}; 157#endif 158/* ARGSUSED */ 159int 160dup(p, uap, retval) 161 struct proc *p; 162 struct dup_args *uap; 163 int *retval; 164{ 165 register struct filedesc *fdp; 166 u_int old; 167 int new, error; 168 169 old = uap->fd; 170 171#if 0 172 /* 173 * XXX Compatibility 174 */ 175 if (old &~ 077) { uap->fd &= 077; return (dup2(p, uap, retval)); } 176#endif 177 178 fdp = p->p_fd; 179 if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) 180 return (EBADF); 181 if ((error = fdalloc(p, 0, &new))) 182 return (error); 183 return (finishdup(fdp, (int)old, new, retval)); 184} 185 186/* 187 * The file control system call. 188 */ 189#ifndef _SYS_SYSPROTO_H_ 190struct fcntl_args { 191 int fd; 192 int cmd; 193 int arg; 194}; 195#endif 196/* ARGSUSED */ 197int 198fcntl(p, uap, retval) 199 struct proc *p; 200 register struct fcntl_args *uap; 201 int *retval; 202{ 203 register struct filedesc *fdp = p->p_fd; 204 register struct file *fp; 205 register char *pop; 206 struct vnode *vp; 207 int i, tmp, error, flg = F_POSIX; 208 struct flock fl; 209 u_int newmin; 210 211 if ((unsigned)uap->fd >= fdp->fd_nfiles || 212 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 213 return (EBADF); 214 pop = &fdp->fd_ofileflags[uap->fd]; 215 switch (uap->cmd) { 216 217 case F_DUPFD: 218 newmin = uap->arg; 219 if (newmin >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur || 220 newmin >= maxfilesperproc) 221 return (EINVAL); 222 if ((error = fdalloc(p, newmin, &i))) 223 return (error); 224 return (finishdup(fdp, uap->fd, i, retval)); 225 226 case F_GETFD: 227 *retval = *pop & 1; 228 return (0); 229 230 case F_SETFD: 231 *pop = (*pop &~ 1) | (uap->arg & 1); 232 return (0); 233 234 case F_GETFL: 235 *retval = OFLAGS(fp->f_flag); 236 return (0); 237 238 case F_SETFL: 239 fp->f_flag &= ~FCNTLFLAGS; 240 fp->f_flag |= FFLAGS(uap->arg) & FCNTLFLAGS; 241 tmp = fp->f_flag & FNONBLOCK; 242 error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 243 if (error) 244 return (error); 245 tmp = fp->f_flag & FASYNC; 246 error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p); 247 if (!error) 248 return (0); 249 fp->f_flag &= ~FNONBLOCK; 250 tmp = 0; 251 (void) (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p); 252 return (error); 253 254 case F_GETOWN: 255 if (fp->f_type == DTYPE_SOCKET) { 256 *retval = ((struct socket *)fp->f_data)->so_pgid; 257 return (0); 258 } 259 error = (*fp->f_ops->fo_ioctl) 260 (fp, (int)TIOCGPGRP, (caddr_t)retval, p); 261 *retval = -*retval; 262 return (error); 263 264 case F_SETOWN: 265 if (fp->f_type == DTYPE_SOCKET) { 266 ((struct socket *)fp->f_data)->so_pgid = uap->arg; 267 return (0); 268 } 269 if (uap->arg <= 0) { 270 uap->arg = -uap->arg; 271 } else { 272 struct proc *p1 = pfind(uap->arg); 273 if (p1 == 0) 274 return (ESRCH); 275 uap->arg = p1->p_pgrp->pg_id; 276 } 277 return ((*fp->f_ops->fo_ioctl) 278 (fp, (int)TIOCSPGRP, (caddr_t)&uap->arg, p)); 279 280 case F_SETLKW: 281 flg |= F_WAIT; 282 /* Fall into F_SETLK */ 283 284 case F_SETLK: 285 if (fp->f_type != DTYPE_VNODE) 286 return (EBADF); 287 vp = (struct vnode *)fp->f_data; 288 /* Copy in the lock structure */ 289 error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl)); 290 if (error) 291 return (error); 292 if (fl.l_whence == SEEK_CUR) 293 fl.l_start += fp->f_offset; 294 switch (fl.l_type) { 295 296 case F_RDLCK: 297 if ((fp->f_flag & FREAD) == 0) 298 return (EBADF); 299 p->p_flag |= P_ADVLOCK; 300 return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg)); 301 302 case F_WRLCK: 303 if ((fp->f_flag & FWRITE) == 0) 304 return (EBADF); 305 p->p_flag |= P_ADVLOCK; 306 return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg)); 307 308 case F_UNLCK: 309 return (VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &fl, 310 F_POSIX)); 311 312 default: 313 return (EINVAL); 314 } 315 316 case F_GETLK: 317 if (fp->f_type != DTYPE_VNODE) 318 return (EBADF); 319 vp = (struct vnode *)fp->f_data; 320 /* Copy in the lock structure */ 321 error = copyin((caddr_t)uap->arg, (caddr_t)&fl, sizeof (fl)); 322 if (error) 323 return (error); 324 if (fl.l_whence == SEEK_CUR) 325 fl.l_start += fp->f_offset; 326 if ((error = VOP_ADVLOCK(vp,(caddr_t)p,F_GETLK,&fl,F_POSIX))) 327 return (error); 328 return (copyout((caddr_t)&fl, (caddr_t)uap->arg, sizeof (fl))); 329 330 default: 331 return (EINVAL); 332 } 333 /* NOTREACHED */ 334} 335 336/* 337 * Common code for dup, dup2, and fcntl(F_DUPFD). 338 */
|
339int
| 339static int
|
340finishdup(fdp, old, new, retval) 341 register struct filedesc *fdp; 342 register int old, new, *retval; 343{ 344 register struct file *fp; 345 346 fp = fdp->fd_ofiles[old]; 347 fdp->fd_ofiles[new] = fp; 348 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; 349 fp->f_count++; 350 if (new > fdp->fd_lastfile) 351 fdp->fd_lastfile = new; 352 *retval = new; 353 return (0); 354} 355 356/* 357 * Close a file descriptor. 358 */ 359#ifndef _SYS_SYSPROTO_H_ 360struct close_args { 361 int fd; 362}; 363#endif 364/* ARGSUSED */ 365int 366close(p, uap, retval) 367 struct proc *p; 368 struct close_args *uap; 369 int *retval; 370{ 371 register struct filedesc *fdp = p->p_fd; 372 register struct file *fp; 373 register int fd = uap->fd; 374 register u_char *pf; 375 376 if ((unsigned)fd >= fdp->fd_nfiles || 377 (fp = fdp->fd_ofiles[fd]) == NULL) 378 return (EBADF); 379 pf = (u_char *)&fdp->fd_ofileflags[fd]; 380 if (*pf & UF_MAPPED) 381 (void) munmapfd(p, fd); 382 fdp->fd_ofiles[fd] = NULL; 383 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 384 fdp->fd_lastfile--; 385 if (fd < fdp->fd_freefile) 386 fdp->fd_freefile = fd; 387 *pf = 0; 388 return (closef(fp, p)); 389} 390 391#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 392/* 393 * Return status information about a file descriptor. 394 */ 395#ifndef _SYS_SYSPROTO_H_ 396struct ofstat_args { 397 int fd; 398 struct ostat *sb; 399}; 400#endif 401/* ARGSUSED */ 402int 403ofstat(p, uap, retval) 404 struct proc *p; 405 register struct ofstat_args *uap; 406 int *retval; 407{ 408 register struct filedesc *fdp = p->p_fd; 409 register struct file *fp; 410 struct stat ub; 411 struct ostat oub; 412 int error; 413 414 if ((unsigned)uap->fd >= fdp->fd_nfiles || 415 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 416 return (EBADF); 417 switch (fp->f_type) { 418 419 case DTYPE_VNODE: 420 error = vn_stat((struct vnode *)fp->f_data, &ub, p); 421 break; 422 423 case DTYPE_SOCKET: 424 error = soo_stat((struct socket *)fp->f_data, &ub); 425 break; 426 427 default: 428 panic("ofstat"); 429 /*NOTREACHED*/ 430 } 431 cvtstat(&ub, &oub); 432 if (error == 0) 433 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub)); 434 return (error); 435} 436#endif /* COMPAT_43 || COMPAT_SUNOS */ 437 438/* 439 * Return status information about a file descriptor. 440 */ 441#ifndef _SYS_SYSPROTO_H_ 442struct fstat_args { 443 int fd; 444 struct stat *sb; 445}; 446#endif 447/* ARGSUSED */ 448int 449fstat(p, uap, retval) 450 struct proc *p; 451 register struct fstat_args *uap; 452 int *retval; 453{ 454 register struct filedesc *fdp = p->p_fd; 455 register struct file *fp; 456 struct stat ub; 457 int error; 458 459 if ((unsigned)uap->fd >= fdp->fd_nfiles || 460 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 461 return (EBADF); 462 switch (fp->f_type) { 463 464 case DTYPE_VNODE: 465 error = vn_stat((struct vnode *)fp->f_data, &ub, p); 466 break; 467 468 case DTYPE_SOCKET: 469 error = soo_stat((struct socket *)fp->f_data, &ub); 470 break; 471 472 default: 473 panic("fstat"); 474 /*NOTREACHED*/ 475 } 476 if (error == 0) 477 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub)); 478 return (error); 479} 480 481/* 482 * Return pathconf information about a file descriptor. 483 */ 484#ifndef _SYS_SYSPROTO_H_ 485struct fpathconf_args { 486 int fd; 487 int name; 488}; 489#endif 490/* ARGSUSED */ 491int 492fpathconf(p, uap, retval) 493 struct proc *p; 494 register struct fpathconf_args *uap; 495 int *retval; 496{ 497 struct filedesc *fdp = p->p_fd; 498 struct file *fp; 499 struct vnode *vp; 500 501 if ((unsigned)uap->fd >= fdp->fd_nfiles || 502 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 503 return (EBADF); 504 switch (fp->f_type) { 505 506 case DTYPE_SOCKET: 507 if (uap->name != _PC_PIPE_BUF) 508 return (EINVAL); 509 *retval = PIPE_BUF; 510 return (0); 511 512 case DTYPE_VNODE: 513 vp = (struct vnode *)fp->f_data; 514 return (VOP_PATHCONF(vp, uap->name, retval)); 515 516 default: 517 panic("fpathconf"); 518 } 519 /*NOTREACHED*/ 520} 521 522/* 523 * Allocate a file descriptor for the process. 524 */
| 340finishdup(fdp, old, new, retval) 341 register struct filedesc *fdp; 342 register int old, new, *retval; 343{ 344 register struct file *fp; 345 346 fp = fdp->fd_ofiles[old]; 347 fdp->fd_ofiles[new] = fp; 348 fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; 349 fp->f_count++; 350 if (new > fdp->fd_lastfile) 351 fdp->fd_lastfile = new; 352 *retval = new; 353 return (0); 354} 355 356/* 357 * Close a file descriptor. 358 */ 359#ifndef _SYS_SYSPROTO_H_ 360struct close_args { 361 int fd; 362}; 363#endif 364/* ARGSUSED */ 365int 366close(p, uap, retval) 367 struct proc *p; 368 struct close_args *uap; 369 int *retval; 370{ 371 register struct filedesc *fdp = p->p_fd; 372 register struct file *fp; 373 register int fd = uap->fd; 374 register u_char *pf; 375 376 if ((unsigned)fd >= fdp->fd_nfiles || 377 (fp = fdp->fd_ofiles[fd]) == NULL) 378 return (EBADF); 379 pf = (u_char *)&fdp->fd_ofileflags[fd]; 380 if (*pf & UF_MAPPED) 381 (void) munmapfd(p, fd); 382 fdp->fd_ofiles[fd] = NULL; 383 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 384 fdp->fd_lastfile--; 385 if (fd < fdp->fd_freefile) 386 fdp->fd_freefile = fd; 387 *pf = 0; 388 return (closef(fp, p)); 389} 390 391#if defined(COMPAT_43) || defined(COMPAT_SUNOS) 392/* 393 * Return status information about a file descriptor. 394 */ 395#ifndef _SYS_SYSPROTO_H_ 396struct ofstat_args { 397 int fd; 398 struct ostat *sb; 399}; 400#endif 401/* ARGSUSED */ 402int 403ofstat(p, uap, retval) 404 struct proc *p; 405 register struct ofstat_args *uap; 406 int *retval; 407{ 408 register struct filedesc *fdp = p->p_fd; 409 register struct file *fp; 410 struct stat ub; 411 struct ostat oub; 412 int error; 413 414 if ((unsigned)uap->fd >= fdp->fd_nfiles || 415 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 416 return (EBADF); 417 switch (fp->f_type) { 418 419 case DTYPE_VNODE: 420 error = vn_stat((struct vnode *)fp->f_data, &ub, p); 421 break; 422 423 case DTYPE_SOCKET: 424 error = soo_stat((struct socket *)fp->f_data, &ub); 425 break; 426 427 default: 428 panic("ofstat"); 429 /*NOTREACHED*/ 430 } 431 cvtstat(&ub, &oub); 432 if (error == 0) 433 error = copyout((caddr_t)&oub, (caddr_t)uap->sb, sizeof (oub)); 434 return (error); 435} 436#endif /* COMPAT_43 || COMPAT_SUNOS */ 437 438/* 439 * Return status information about a file descriptor. 440 */ 441#ifndef _SYS_SYSPROTO_H_ 442struct fstat_args { 443 int fd; 444 struct stat *sb; 445}; 446#endif 447/* ARGSUSED */ 448int 449fstat(p, uap, retval) 450 struct proc *p; 451 register struct fstat_args *uap; 452 int *retval; 453{ 454 register struct filedesc *fdp = p->p_fd; 455 register struct file *fp; 456 struct stat ub; 457 int error; 458 459 if ((unsigned)uap->fd >= fdp->fd_nfiles || 460 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 461 return (EBADF); 462 switch (fp->f_type) { 463 464 case DTYPE_VNODE: 465 error = vn_stat((struct vnode *)fp->f_data, &ub, p); 466 break; 467 468 case DTYPE_SOCKET: 469 error = soo_stat((struct socket *)fp->f_data, &ub); 470 break; 471 472 default: 473 panic("fstat"); 474 /*NOTREACHED*/ 475 } 476 if (error == 0) 477 error = copyout((caddr_t)&ub, (caddr_t)uap->sb, sizeof (ub)); 478 return (error); 479} 480 481/* 482 * Return pathconf information about a file descriptor. 483 */ 484#ifndef _SYS_SYSPROTO_H_ 485struct fpathconf_args { 486 int fd; 487 int name; 488}; 489#endif 490/* ARGSUSED */ 491int 492fpathconf(p, uap, retval) 493 struct proc *p; 494 register struct fpathconf_args *uap; 495 int *retval; 496{ 497 struct filedesc *fdp = p->p_fd; 498 struct file *fp; 499 struct vnode *vp; 500 501 if ((unsigned)uap->fd >= fdp->fd_nfiles || 502 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 503 return (EBADF); 504 switch (fp->f_type) { 505 506 case DTYPE_SOCKET: 507 if (uap->name != _PC_PIPE_BUF) 508 return (EINVAL); 509 *retval = PIPE_BUF; 510 return (0); 511 512 case DTYPE_VNODE: 513 vp = (struct vnode *)fp->f_data; 514 return (VOP_PATHCONF(vp, uap->name, retval)); 515 516 default: 517 panic("fpathconf"); 518 } 519 /*NOTREACHED*/ 520} 521 522/* 523 * Allocate a file descriptor for the process. 524 */
|
525int fdexpand;
| 525static int fdexpand; 526SYSCTL_INT(_debug, OID_AUTO, fdexpand, CTLFLAG_RD, &fdexpand, 0, "");
|
526 527int 528fdalloc(p, want, result) 529 struct proc *p; 530 int want; 531 int *result; 532{ 533 register struct filedesc *fdp = p->p_fd; 534 register int i; 535 int lim, last, nfiles; 536 struct file **newofile; 537 char *newofileflags; 538 539 /* 540 * Search for a free descriptor starting at the higher 541 * of want or fd_freefile. If that fails, consider 542 * expanding the ofile array. 543 */ 544 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 545 for (;;) { 546 last = min(fdp->fd_nfiles, lim); 547 if ((i = want) < fdp->fd_freefile) 548 i = fdp->fd_freefile; 549 for (; i < last; i++) { 550 if (fdp->fd_ofiles[i] == NULL) { 551 fdp->fd_ofileflags[i] = 0; 552 if (i > fdp->fd_lastfile) 553 fdp->fd_lastfile = i; 554 if (want <= fdp->fd_freefile) 555 fdp->fd_freefile = i; 556 *result = i; 557 return (0); 558 } 559 } 560 561 /* 562 * No space in current array. Expand? 563 */ 564 if (fdp->fd_nfiles >= lim) 565 return (EMFILE); 566 if (fdp->fd_nfiles < NDEXTENT) 567 nfiles = NDEXTENT; 568 else 569 nfiles = 2 * fdp->fd_nfiles; 570 MALLOC(newofile, struct file **, nfiles * OFILESIZE, 571 M_FILEDESC, M_WAITOK); 572 newofileflags = (char *) &newofile[nfiles]; 573 /* 574 * Copy the existing ofile and ofileflags arrays 575 * and zero the new portion of each array. 576 */ 577 bcopy(fdp->fd_ofiles, newofile, 578 (i = sizeof(struct file *) * fdp->fd_nfiles)); 579 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i); 580 bcopy(fdp->fd_ofileflags, newofileflags, 581 (i = sizeof(char) * fdp->fd_nfiles)); 582 bzero(newofileflags + i, nfiles * sizeof(char) - i); 583 if (fdp->fd_nfiles > NDFILE) 584 FREE(fdp->fd_ofiles, M_FILEDESC); 585 fdp->fd_ofiles = newofile; 586 fdp->fd_ofileflags = newofileflags; 587 fdp->fd_nfiles = nfiles; 588 fdexpand++; 589 } 590 return (0); 591} 592 593/* 594 * Check to see whether n user file descriptors 595 * are available to the process p. 596 */ 597int 598fdavail(p, n) 599 struct proc *p; 600 register int n; 601{ 602 register struct filedesc *fdp = p->p_fd; 603 register struct file **fpp; 604 register int i, lim; 605 606 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 607 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) 608 return (1); 609 fpp = &fdp->fd_ofiles[fdp->fd_freefile]; 610 for (i = fdp->fd_nfiles - fdp->fd_freefile; --i >= 0; fpp++) 611 if (*fpp == NULL && --n <= 0) 612 return (1); 613 return (0); 614} 615 616/* 617 * Create a new open file structure and allocate 618 * a file decriptor for the process that refers to it. 619 */ 620int 621falloc(p, resultfp, resultfd) 622 register struct proc *p; 623 struct file **resultfp; 624 int *resultfd; 625{ 626 register struct file *fp, *fq, **fpp; 627 int error, i; 628 629 if ((error = fdalloc(p, 0, &i))) 630 return (error); 631 if (nfiles >= maxfiles) { 632 tablefull("file"); 633 return (ENFILE); 634 } 635 /* 636 * Allocate a new file descriptor. 637 * If the process has file descriptor zero open, add to the list 638 * of open files at that point, otherwise put it at the front of 639 * the list of open files. 640 */ 641 nfiles++; 642 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK); 643 bzero(fp, sizeof(struct file)); 644 if ((fq = p->p_fd->fd_ofiles[0])) 645 fpp = &fq->f_filef; 646 else 647 fpp = &filehead; 648 p->p_fd->fd_ofiles[i] = fp; 649 if ((fq = *fpp)) 650 fq->f_fileb = &fp->f_filef; 651 fp->f_filef = fq; 652 fp->f_fileb = fpp; 653 *fpp = fp; 654 fp->f_count = 1; 655 fp->f_cred = p->p_ucred; 656 crhold(fp->f_cred); 657 if (resultfp) 658 *resultfp = fp; 659 if (resultfd) 660 *resultfd = i; 661 return (0); 662} 663 664/* 665 * Free a file descriptor. 666 */ 667void 668ffree(fp) 669 register struct file *fp; 670{ 671 register struct file *fq; 672 673 if ((fq = fp->f_filef)) 674 fq->f_fileb = fp->f_fileb; 675 *fp->f_fileb = fq; 676 crfree(fp->f_cred); 677#ifdef DIAGNOSTIC 678 fp->f_filef = NULL; 679 fp->f_fileb = NULL; 680 fp->f_count = 0; 681#endif 682 nfiles--; 683 FREE(fp, M_FILE); 684} 685 686/* 687 * Copy a filedesc structure. 688 */ 689struct filedesc * 690fdcopy(p) 691 struct proc *p; 692{ 693 register struct filedesc *newfdp, *fdp = p->p_fd; 694 register struct file **fpp; 695 register int i; 696 697 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), 698 M_FILEDESC, M_WAITOK); 699 bcopy(fdp, newfdp, sizeof(struct filedesc)); 700 VREF(newfdp->fd_cdir); 701 if (newfdp->fd_rdir) 702 VREF(newfdp->fd_rdir); 703 newfdp->fd_refcnt = 1; 704 705 /* 706 * If the number of open files fits in the internal arrays 707 * of the open file structure, use them, otherwise allocate 708 * additional memory for the number of descriptors currently 709 * in use. 710 */ 711 if (newfdp->fd_lastfile < NDFILE) { 712 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles; 713 newfdp->fd_ofileflags = 714 ((struct filedesc0 *) newfdp)->fd_dfileflags; 715 i = NDFILE; 716 } else { 717 /* 718 * Compute the smallest multiple of NDEXTENT needed 719 * for the file descriptors currently in use, 720 * allowing the table to shrink. 721 */ 722 i = newfdp->fd_nfiles; 723 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2) 724 i /= 2; 725 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE, 726 M_FILEDESC, M_WAITOK); 727 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i]; 728 } 729 newfdp->fd_nfiles = i; 730 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); 731 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); 732 fpp = newfdp->fd_ofiles; 733 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) 734 if (*fpp != NULL) 735 (*fpp)->f_count++; 736 return (newfdp); 737} 738 739/* 740 * Release a filedesc structure. 741 */ 742void 743fdfree(p) 744 struct proc *p; 745{ 746 register struct filedesc *fdp = p->p_fd; 747 struct file **fpp; 748 register int i; 749 750 if (--fdp->fd_refcnt > 0) 751 return; 752 fpp = fdp->fd_ofiles; 753 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) 754 if (*fpp) 755 (void) closef(*fpp, p); 756 if (fdp->fd_nfiles > NDFILE) 757 FREE(fdp->fd_ofiles, M_FILEDESC); 758 vrele(fdp->fd_cdir); 759 if (fdp->fd_rdir) 760 vrele(fdp->fd_rdir); 761 FREE(fdp, M_FILEDESC); 762} 763 764/* 765 * Close any files on exec? 766 */ 767void 768fdcloseexec(p) 769 struct proc *p; 770{ 771 struct filedesc *fdp = p->p_fd; 772 struct file **fpp; 773 char *fdfp; 774 register int i; 775 776 fpp = fdp->fd_ofiles; 777 fdfp = fdp->fd_ofileflags; 778 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) 779 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) { 780 if (*fdfp & UF_MAPPED) 781 (void) munmapfd(p, i); 782 (void) closef(*fpp, p); 783 *fpp = NULL; 784 *fdfp = 0; 785 if (i < fdp->fd_freefile) 786 fdp->fd_freefile = i; 787 } 788 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 789 fdp->fd_lastfile--; 790} 791 792/* 793 * Internal form of close. 794 * Decrement reference count on file structure. 795 * Note: p may be NULL when closing a file 796 * that was being passed in a message. 797 */ 798int 799closef(fp, p) 800 register struct file *fp; 801 register struct proc *p; 802{ 803 struct vnode *vp; 804 struct flock lf; 805 int error; 806 807 if (fp == NULL) 808 return (0); 809 /* 810 * POSIX record locking dictates that any close releases ALL 811 * locks owned by this process. This is handled by setting 812 * a flag in the unlock to free ONLY locks obeying POSIX 813 * semantics, and not to free BSD-style file locks. 814 * If the descriptor was in a message, POSIX-style locks 815 * aren't passed with the descriptor. 816 */ 817 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) { 818 lf.l_whence = SEEK_SET; 819 lf.l_start = 0; 820 lf.l_len = 0; 821 lf.l_type = F_UNLCK; 822 vp = (struct vnode *)fp->f_data; 823 (void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX); 824 } 825 if (--fp->f_count > 0) 826 return (0); 827 if (fp->f_count < 0) 828 panic("closef: count < 0"); 829 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) { 830 lf.l_whence = SEEK_SET; 831 lf.l_start = 0; 832 lf.l_len = 0; 833 lf.l_type = F_UNLCK; 834 vp = (struct vnode *)fp->f_data; 835 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); 836 } 837 if (fp->f_ops) 838 error = (*fp->f_ops->fo_close)(fp, p); 839 else 840 error = 0; 841 ffree(fp); 842 return (error); 843} 844 845/* 846 * Apply an advisory lock on a file descriptor. 847 * 848 * Just attempt to get a record lock of the requested type on 849 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). 850 */ 851#ifndef _SYS_SYSPROTO_H_ 852struct flock_args { 853 int fd; 854 int how; 855}; 856#endif 857/* ARGSUSED */ 858int 859flock(p, uap, retval) 860 struct proc *p; 861 register struct flock_args *uap; 862 int *retval; 863{ 864 register struct filedesc *fdp = p->p_fd; 865 register struct file *fp; 866 struct vnode *vp; 867 struct flock lf; 868 869 if ((unsigned)uap->fd >= fdp->fd_nfiles || 870 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 871 return (EBADF); 872 if (fp->f_type != DTYPE_VNODE) 873 return (EOPNOTSUPP); 874 vp = (struct vnode *)fp->f_data; 875 lf.l_whence = SEEK_SET; 876 lf.l_start = 0; 877 lf.l_len = 0; 878 if (uap->how & LOCK_UN) { 879 lf.l_type = F_UNLCK; 880 fp->f_flag &= ~FHASLOCK; 881 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK)); 882 } 883 if (uap->how & LOCK_EX) 884 lf.l_type = F_WRLCK; 885 else if (uap->how & LOCK_SH) 886 lf.l_type = F_RDLCK; 887 else 888 return (EBADF); 889 fp->f_flag |= FHASLOCK; 890 if (uap->how & LOCK_NB) 891 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK)); 892 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT)); 893} 894 895/* 896 * File Descriptor pseudo-device driver (/dev/fd/). 897 * 898 * Opening minor device N dup()s the file (if any) connected to file 899 * descriptor N belonging to the calling process. Note that this driver 900 * consists of only the ``open()'' routine, because all subsequent 901 * references to this file will be direct to the other driver. 902 */ 903/* ARGSUSED */ 904static int 905fdopen(dev, mode, type, p) 906 dev_t dev; 907 int mode, type; 908 struct proc *p; 909{ 910 911 /* 912 * XXX Kludge: set curproc->p_dupfd to contain the value of the 913 * the file descriptor being sought for duplication. The error 914 * return ensures that the vnode for this device will be released 915 * by vn_open. Open will detect this special error and take the 916 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN 917 * will simply report the error. 918 */ 919 p->p_dupfd = minor(dev); 920 return (ENODEV); 921} 922 923/* 924 * Duplicate the specified descriptor to a free descriptor. 925 */ 926int 927dupfdopen(fdp, indx, dfd, mode, error) 928 register struct filedesc *fdp; 929 register int indx, dfd; 930 int mode; 931 int error; 932{ 933 register struct file *wfp; 934 struct file *fp; 935 936 /* 937 * If the to-be-dup'd fd number is greater than the allowed number 938 * of file descriptors, or the fd to be dup'd has already been 939 * closed, reject. Note, check for new == old is necessary as 940 * falloc could allocate an already closed to-be-dup'd descriptor 941 * as the new descriptor. 942 */ 943 fp = fdp->fd_ofiles[indx]; 944 if ((u_int)dfd >= fdp->fd_nfiles || 945 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp) 946 return (EBADF); 947 948 /* 949 * There are two cases of interest here. 950 * 951 * For ENODEV simply dup (dfd) to file descriptor 952 * (indx) and return. 953 * 954 * For ENXIO steal away the file structure from (dfd) and 955 * store it in (indx). (dfd) is effectively closed by 956 * this operation. 957 * 958 * Any other error code is just returned. 959 */ 960 switch (error) { 961 case ENODEV: 962 /* 963 * Check that the mode the file is being opened for is a 964 * subset of the mode of the existing descriptor. 965 */ 966 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) 967 return (EACCES); 968 fdp->fd_ofiles[indx] = wfp; 969 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 970 wfp->f_count++; 971 if (indx > fdp->fd_lastfile) 972 fdp->fd_lastfile = indx; 973 return (0); 974 975 case ENXIO: 976 /* 977 * Steal away the file pointer from dfd, and stuff it into indx. 978 */ 979 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; 980 fdp->fd_ofiles[dfd] = NULL; 981 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 982 fdp->fd_ofileflags[dfd] = 0; 983 /* 984 * Complete the clean up of the filedesc structure by 985 * recomputing the various hints. 986 */ 987 if (indx > fdp->fd_lastfile) 988 fdp->fd_lastfile = indx; 989 else 990 while (fdp->fd_lastfile > 0 && 991 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 992 fdp->fd_lastfile--; 993 if (dfd < fdp->fd_freefile) 994 fdp->fd_freefile = dfd; 995 return (0); 996 997 default: 998 return (error); 999 } 1000 /* NOTREACHED */ 1001} 1002 1003/* 1004 * Get file structures. 1005 */ 1006static int 1007sysctl_kern_file SYSCTL_HANDLER_ARGS 1008{ 1009 int error; 1010 struct file *fp; 1011 1012 if (!req->oldptr) { 1013 /* 1014 * overestimate by 10 files 1015 */ 1016 return (SYSCTL_OUT(req, 0, sizeof(filehead) + 1017 (nfiles + 10) * sizeof(struct file))); 1018 } 1019 1020 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead)); 1021 if (error) 1022 return (error); 1023 1024 /* 1025 * followed by an array of file structures 1026 */ 1027 for (fp = filehead; fp != NULL; fp = fp->f_filef) { 1028 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file)); 1029 if (error) 1030 return (error); 1031 } 1032 return (0); 1033} 1034 1035SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 1036 0, 0, sysctl_kern_file, "S,file", ""); 1037 1038SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, 1039 CTLFLAG_RD, &maxfilesperproc, 0, ""); 1040 1041SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, &maxfiles, 0, ""); 1042 1043static fildesc_devsw_installed = 0; 1044static void *devfs_token_stdin; 1045static void *devfs_token_stdout; 1046static void *devfs_token_stderr; 1047static void *devfs_token_fildesc[NUMFDESC]; 1048 1049static void fildesc_drvinit(void *unused) 1050{ 1051 dev_t dev; 1052 int i; 1053 char name[32]; 1054 1055 if( ! fildesc_devsw_installed ) { 1056 dev = makedev(CDEV_MAJOR,0); 1057 cdevsw_add(&dev,&fildesc_cdevsw,NULL); 1058 fildesc_devsw_installed = 1; 1059#ifdef DEVFS 1060 for ( i = 0 ; i < NUMFDESC ; i++ ) { 1061 sprintf(name,"%d",i); 1062 devfs_token_fildesc[i] = devfs_add_devsw("fd",name, 1063 &fildesc_cdevsw,0, 1064 DV_CHR, 0, 0, 0666); 1065 } 1066 devfs_token_stdin = 1067 dev_link("/","stdin",devfs_token_fildesc[0]); 1068 devfs_token_stdout = 1069 dev_link("/","stdout",devfs_token_fildesc[1]); 1070 devfs_token_stderr = 1071 dev_link("/","stderr",devfs_token_fildesc[2]); 1072#endif 1073 } 1074} 1075 1076SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, 1077 fildesc_drvinit,NULL) 1078 1079
| 527 528int 529fdalloc(p, want, result) 530 struct proc *p; 531 int want; 532 int *result; 533{ 534 register struct filedesc *fdp = p->p_fd; 535 register int i; 536 int lim, last, nfiles; 537 struct file **newofile; 538 char *newofileflags; 539 540 /* 541 * Search for a free descriptor starting at the higher 542 * of want or fd_freefile. If that fails, consider 543 * expanding the ofile array. 544 */ 545 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 546 for (;;) { 547 last = min(fdp->fd_nfiles, lim); 548 if ((i = want) < fdp->fd_freefile) 549 i = fdp->fd_freefile; 550 for (; i < last; i++) { 551 if (fdp->fd_ofiles[i] == NULL) { 552 fdp->fd_ofileflags[i] = 0; 553 if (i > fdp->fd_lastfile) 554 fdp->fd_lastfile = i; 555 if (want <= fdp->fd_freefile) 556 fdp->fd_freefile = i; 557 *result = i; 558 return (0); 559 } 560 } 561 562 /* 563 * No space in current array. Expand? 564 */ 565 if (fdp->fd_nfiles >= lim) 566 return (EMFILE); 567 if (fdp->fd_nfiles < NDEXTENT) 568 nfiles = NDEXTENT; 569 else 570 nfiles = 2 * fdp->fd_nfiles; 571 MALLOC(newofile, struct file **, nfiles * OFILESIZE, 572 M_FILEDESC, M_WAITOK); 573 newofileflags = (char *) &newofile[nfiles]; 574 /* 575 * Copy the existing ofile and ofileflags arrays 576 * and zero the new portion of each array. 577 */ 578 bcopy(fdp->fd_ofiles, newofile, 579 (i = sizeof(struct file *) * fdp->fd_nfiles)); 580 bzero((char *)newofile + i, nfiles * sizeof(struct file *) - i); 581 bcopy(fdp->fd_ofileflags, newofileflags, 582 (i = sizeof(char) * fdp->fd_nfiles)); 583 bzero(newofileflags + i, nfiles * sizeof(char) - i); 584 if (fdp->fd_nfiles > NDFILE) 585 FREE(fdp->fd_ofiles, M_FILEDESC); 586 fdp->fd_ofiles = newofile; 587 fdp->fd_ofileflags = newofileflags; 588 fdp->fd_nfiles = nfiles; 589 fdexpand++; 590 } 591 return (0); 592} 593 594/* 595 * Check to see whether n user file descriptors 596 * are available to the process p. 597 */ 598int 599fdavail(p, n) 600 struct proc *p; 601 register int n; 602{ 603 register struct filedesc *fdp = p->p_fd; 604 register struct file **fpp; 605 register int i, lim; 606 607 lim = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfilesperproc); 608 if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) 609 return (1); 610 fpp = &fdp->fd_ofiles[fdp->fd_freefile]; 611 for (i = fdp->fd_nfiles - fdp->fd_freefile; --i >= 0; fpp++) 612 if (*fpp == NULL && --n <= 0) 613 return (1); 614 return (0); 615} 616 617/* 618 * Create a new open file structure and allocate 619 * a file decriptor for the process that refers to it. 620 */ 621int 622falloc(p, resultfp, resultfd) 623 register struct proc *p; 624 struct file **resultfp; 625 int *resultfd; 626{ 627 register struct file *fp, *fq, **fpp; 628 int error, i; 629 630 if ((error = fdalloc(p, 0, &i))) 631 return (error); 632 if (nfiles >= maxfiles) { 633 tablefull("file"); 634 return (ENFILE); 635 } 636 /* 637 * Allocate a new file descriptor. 638 * If the process has file descriptor zero open, add to the list 639 * of open files at that point, otherwise put it at the front of 640 * the list of open files. 641 */ 642 nfiles++; 643 MALLOC(fp, struct file *, sizeof(struct file), M_FILE, M_WAITOK); 644 bzero(fp, sizeof(struct file)); 645 if ((fq = p->p_fd->fd_ofiles[0])) 646 fpp = &fq->f_filef; 647 else 648 fpp = &filehead; 649 p->p_fd->fd_ofiles[i] = fp; 650 if ((fq = *fpp)) 651 fq->f_fileb = &fp->f_filef; 652 fp->f_filef = fq; 653 fp->f_fileb = fpp; 654 *fpp = fp; 655 fp->f_count = 1; 656 fp->f_cred = p->p_ucred; 657 crhold(fp->f_cred); 658 if (resultfp) 659 *resultfp = fp; 660 if (resultfd) 661 *resultfd = i; 662 return (0); 663} 664 665/* 666 * Free a file descriptor. 667 */ 668void 669ffree(fp) 670 register struct file *fp; 671{ 672 register struct file *fq; 673 674 if ((fq = fp->f_filef)) 675 fq->f_fileb = fp->f_fileb; 676 *fp->f_fileb = fq; 677 crfree(fp->f_cred); 678#ifdef DIAGNOSTIC 679 fp->f_filef = NULL; 680 fp->f_fileb = NULL; 681 fp->f_count = 0; 682#endif 683 nfiles--; 684 FREE(fp, M_FILE); 685} 686 687/* 688 * Copy a filedesc structure. 689 */ 690struct filedesc * 691fdcopy(p) 692 struct proc *p; 693{ 694 register struct filedesc *newfdp, *fdp = p->p_fd; 695 register struct file **fpp; 696 register int i; 697 698 MALLOC(newfdp, struct filedesc *, sizeof(struct filedesc0), 699 M_FILEDESC, M_WAITOK); 700 bcopy(fdp, newfdp, sizeof(struct filedesc)); 701 VREF(newfdp->fd_cdir); 702 if (newfdp->fd_rdir) 703 VREF(newfdp->fd_rdir); 704 newfdp->fd_refcnt = 1; 705 706 /* 707 * If the number of open files fits in the internal arrays 708 * of the open file structure, use them, otherwise allocate 709 * additional memory for the number of descriptors currently 710 * in use. 711 */ 712 if (newfdp->fd_lastfile < NDFILE) { 713 newfdp->fd_ofiles = ((struct filedesc0 *) newfdp)->fd_dfiles; 714 newfdp->fd_ofileflags = 715 ((struct filedesc0 *) newfdp)->fd_dfileflags; 716 i = NDFILE; 717 } else { 718 /* 719 * Compute the smallest multiple of NDEXTENT needed 720 * for the file descriptors currently in use, 721 * allowing the table to shrink. 722 */ 723 i = newfdp->fd_nfiles; 724 while (i > 2 * NDEXTENT && i > newfdp->fd_lastfile * 2) 725 i /= 2; 726 MALLOC(newfdp->fd_ofiles, struct file **, i * OFILESIZE, 727 M_FILEDESC, M_WAITOK); 728 newfdp->fd_ofileflags = (char *) &newfdp->fd_ofiles[i]; 729 } 730 newfdp->fd_nfiles = i; 731 bcopy(fdp->fd_ofiles, newfdp->fd_ofiles, i * sizeof(struct file **)); 732 bcopy(fdp->fd_ofileflags, newfdp->fd_ofileflags, i * sizeof(char)); 733 fpp = newfdp->fd_ofiles; 734 for (i = newfdp->fd_lastfile; i-- >= 0; fpp++) 735 if (*fpp != NULL) 736 (*fpp)->f_count++; 737 return (newfdp); 738} 739 740/* 741 * Release a filedesc structure. 742 */ 743void 744fdfree(p) 745 struct proc *p; 746{ 747 register struct filedesc *fdp = p->p_fd; 748 struct file **fpp; 749 register int i; 750 751 if (--fdp->fd_refcnt > 0) 752 return; 753 fpp = fdp->fd_ofiles; 754 for (i = fdp->fd_lastfile; i-- >= 0; fpp++) 755 if (*fpp) 756 (void) closef(*fpp, p); 757 if (fdp->fd_nfiles > NDFILE) 758 FREE(fdp->fd_ofiles, M_FILEDESC); 759 vrele(fdp->fd_cdir); 760 if (fdp->fd_rdir) 761 vrele(fdp->fd_rdir); 762 FREE(fdp, M_FILEDESC); 763} 764 765/* 766 * Close any files on exec? 767 */ 768void 769fdcloseexec(p) 770 struct proc *p; 771{ 772 struct filedesc *fdp = p->p_fd; 773 struct file **fpp; 774 char *fdfp; 775 register int i; 776 777 fpp = fdp->fd_ofiles; 778 fdfp = fdp->fd_ofileflags; 779 for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) 780 if (*fpp != NULL && (*fdfp & UF_EXCLOSE)) { 781 if (*fdfp & UF_MAPPED) 782 (void) munmapfd(p, i); 783 (void) closef(*fpp, p); 784 *fpp = NULL; 785 *fdfp = 0; 786 if (i < fdp->fd_freefile) 787 fdp->fd_freefile = i; 788 } 789 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 790 fdp->fd_lastfile--; 791} 792 793/* 794 * Internal form of close. 795 * Decrement reference count on file structure. 796 * Note: p may be NULL when closing a file 797 * that was being passed in a message. 798 */ 799int 800closef(fp, p) 801 register struct file *fp; 802 register struct proc *p; 803{ 804 struct vnode *vp; 805 struct flock lf; 806 int error; 807 808 if (fp == NULL) 809 return (0); 810 /* 811 * POSIX record locking dictates that any close releases ALL 812 * locks owned by this process. This is handled by setting 813 * a flag in the unlock to free ONLY locks obeying POSIX 814 * semantics, and not to free BSD-style file locks. 815 * If the descriptor was in a message, POSIX-style locks 816 * aren't passed with the descriptor. 817 */ 818 if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) { 819 lf.l_whence = SEEK_SET; 820 lf.l_start = 0; 821 lf.l_len = 0; 822 lf.l_type = F_UNLCK; 823 vp = (struct vnode *)fp->f_data; 824 (void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX); 825 } 826 if (--fp->f_count > 0) 827 return (0); 828 if (fp->f_count < 0) 829 panic("closef: count < 0"); 830 if ((fp->f_flag & FHASLOCK) && fp->f_type == DTYPE_VNODE) { 831 lf.l_whence = SEEK_SET; 832 lf.l_start = 0; 833 lf.l_len = 0; 834 lf.l_type = F_UNLCK; 835 vp = (struct vnode *)fp->f_data; 836 (void) VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); 837 } 838 if (fp->f_ops) 839 error = (*fp->f_ops->fo_close)(fp, p); 840 else 841 error = 0; 842 ffree(fp); 843 return (error); 844} 845 846/* 847 * Apply an advisory lock on a file descriptor. 848 * 849 * Just attempt to get a record lock of the requested type on 850 * the entire file (l_whence = SEEK_SET, l_start = 0, l_len = 0). 851 */ 852#ifndef _SYS_SYSPROTO_H_ 853struct flock_args { 854 int fd; 855 int how; 856}; 857#endif 858/* ARGSUSED */ 859int 860flock(p, uap, retval) 861 struct proc *p; 862 register struct flock_args *uap; 863 int *retval; 864{ 865 register struct filedesc *fdp = p->p_fd; 866 register struct file *fp; 867 struct vnode *vp; 868 struct flock lf; 869 870 if ((unsigned)uap->fd >= fdp->fd_nfiles || 871 (fp = fdp->fd_ofiles[uap->fd]) == NULL) 872 return (EBADF); 873 if (fp->f_type != DTYPE_VNODE) 874 return (EOPNOTSUPP); 875 vp = (struct vnode *)fp->f_data; 876 lf.l_whence = SEEK_SET; 877 lf.l_start = 0; 878 lf.l_len = 0; 879 if (uap->how & LOCK_UN) { 880 lf.l_type = F_UNLCK; 881 fp->f_flag &= ~FHASLOCK; 882 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK)); 883 } 884 if (uap->how & LOCK_EX) 885 lf.l_type = F_WRLCK; 886 else if (uap->how & LOCK_SH) 887 lf.l_type = F_RDLCK; 888 else 889 return (EBADF); 890 fp->f_flag |= FHASLOCK; 891 if (uap->how & LOCK_NB) 892 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK)); 893 return (VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, F_FLOCK|F_WAIT)); 894} 895 896/* 897 * File Descriptor pseudo-device driver (/dev/fd/). 898 * 899 * Opening minor device N dup()s the file (if any) connected to file 900 * descriptor N belonging to the calling process. Note that this driver 901 * consists of only the ``open()'' routine, because all subsequent 902 * references to this file will be direct to the other driver. 903 */ 904/* ARGSUSED */ 905static int 906fdopen(dev, mode, type, p) 907 dev_t dev; 908 int mode, type; 909 struct proc *p; 910{ 911 912 /* 913 * XXX Kludge: set curproc->p_dupfd to contain the value of the 914 * the file descriptor being sought for duplication. The error 915 * return ensures that the vnode for this device will be released 916 * by vn_open. Open will detect this special error and take the 917 * actions in dupfdopen below. Other callers of vn_open or VOP_OPEN 918 * will simply report the error. 919 */ 920 p->p_dupfd = minor(dev); 921 return (ENODEV); 922} 923 924/* 925 * Duplicate the specified descriptor to a free descriptor. 926 */ 927int 928dupfdopen(fdp, indx, dfd, mode, error) 929 register struct filedesc *fdp; 930 register int indx, dfd; 931 int mode; 932 int error; 933{ 934 register struct file *wfp; 935 struct file *fp; 936 937 /* 938 * If the to-be-dup'd fd number is greater than the allowed number 939 * of file descriptors, or the fd to be dup'd has already been 940 * closed, reject. Note, check for new == old is necessary as 941 * falloc could allocate an already closed to-be-dup'd descriptor 942 * as the new descriptor. 943 */ 944 fp = fdp->fd_ofiles[indx]; 945 if ((u_int)dfd >= fdp->fd_nfiles || 946 (wfp = fdp->fd_ofiles[dfd]) == NULL || fp == wfp) 947 return (EBADF); 948 949 /* 950 * There are two cases of interest here. 951 * 952 * For ENODEV simply dup (dfd) to file descriptor 953 * (indx) and return. 954 * 955 * For ENXIO steal away the file structure from (dfd) and 956 * store it in (indx). (dfd) is effectively closed by 957 * this operation. 958 * 959 * Any other error code is just returned. 960 */ 961 switch (error) { 962 case ENODEV: 963 /* 964 * Check that the mode the file is being opened for is a 965 * subset of the mode of the existing descriptor. 966 */ 967 if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) 968 return (EACCES); 969 fdp->fd_ofiles[indx] = wfp; 970 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 971 wfp->f_count++; 972 if (indx > fdp->fd_lastfile) 973 fdp->fd_lastfile = indx; 974 return (0); 975 976 case ENXIO: 977 /* 978 * Steal away the file pointer from dfd, and stuff it into indx. 979 */ 980 fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd]; 981 fdp->fd_ofiles[dfd] = NULL; 982 fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; 983 fdp->fd_ofileflags[dfd] = 0; 984 /* 985 * Complete the clean up of the filedesc structure by 986 * recomputing the various hints. 987 */ 988 if (indx > fdp->fd_lastfile) 989 fdp->fd_lastfile = indx; 990 else 991 while (fdp->fd_lastfile > 0 && 992 fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 993 fdp->fd_lastfile--; 994 if (dfd < fdp->fd_freefile) 995 fdp->fd_freefile = dfd; 996 return (0); 997 998 default: 999 return (error); 1000 } 1001 /* NOTREACHED */ 1002} 1003 1004/* 1005 * Get file structures. 1006 */ 1007static int 1008sysctl_kern_file SYSCTL_HANDLER_ARGS 1009{ 1010 int error; 1011 struct file *fp; 1012 1013 if (!req->oldptr) { 1014 /* 1015 * overestimate by 10 files 1016 */ 1017 return (SYSCTL_OUT(req, 0, sizeof(filehead) + 1018 (nfiles + 10) * sizeof(struct file))); 1019 } 1020 1021 error = SYSCTL_OUT(req, (caddr_t)&filehead, sizeof(filehead)); 1022 if (error) 1023 return (error); 1024 1025 /* 1026 * followed by an array of file structures 1027 */ 1028 for (fp = filehead; fp != NULL; fp = fp->f_filef) { 1029 error = SYSCTL_OUT(req, (caddr_t)fp, sizeof (struct file)); 1030 if (error) 1031 return (error); 1032 } 1033 return (0); 1034} 1035 1036SYSCTL_PROC(_kern, KERN_FILE, file, CTLTYPE_OPAQUE|CTLFLAG_RD, 1037 0, 0, sysctl_kern_file, "S,file", ""); 1038 1039SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, 1040 CTLFLAG_RD, &maxfilesperproc, 0, ""); 1041 1042SYSCTL_INT(_kern, KERN_MAXFILES, maxfiles, CTLFLAG_RW, &maxfiles, 0, ""); 1043 1044static fildesc_devsw_installed = 0; 1045static void *devfs_token_stdin; 1046static void *devfs_token_stdout; 1047static void *devfs_token_stderr; 1048static void *devfs_token_fildesc[NUMFDESC]; 1049 1050static void fildesc_drvinit(void *unused) 1051{ 1052 dev_t dev; 1053 int i; 1054 char name[32]; 1055 1056 if( ! fildesc_devsw_installed ) { 1057 dev = makedev(CDEV_MAJOR,0); 1058 cdevsw_add(&dev,&fildesc_cdevsw,NULL); 1059 fildesc_devsw_installed = 1; 1060#ifdef DEVFS 1061 for ( i = 0 ; i < NUMFDESC ; i++ ) { 1062 sprintf(name,"%d",i); 1063 devfs_token_fildesc[i] = devfs_add_devsw("fd",name, 1064 &fildesc_cdevsw,0, 1065 DV_CHR, 0, 0, 0666); 1066 } 1067 devfs_token_stdin = 1068 dev_link("/","stdin",devfs_token_fildesc[0]); 1069 devfs_token_stdout = 1070 dev_link("/","stdout",devfs_token_fildesc[1]); 1071 devfs_token_stderr = 1072 dev_link("/","stderr",devfs_token_fildesc[2]); 1073#endif 1074 } 1075} 1076 1077SYSINIT(fildescdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, 1078 fildesc_drvinit,NULL) 1079 1080
|