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