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