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