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