Index: sys/kern/sys_generic.c =================================================================== --- sys/kern/sys_generic.c (wersja 239974) +++ sys/kern/sys_generic.c (kopia robocza) @@ -703,28 +703,39 @@ { struct file *fp; struct filedesc *fdp; - int error; - int tmp; + int error, tmp, locked; AUDIT_ARG_FD(fd); AUDIT_ARG_CMD(com); - if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0) - return (error); + + fdp = td->td_proc->p_fd; + + switch (com) { + case FIONCLEX: + case FIOCLEX: + FILEDESC_XLOCK(fdp); + locked = 1; + break; + default: + locked = 0; + break; + } + + if ((error = fget(td, fd, CAP_IOCTL, &fp)) != 0) { + fp = NULL; + goto out; + } if ((fp->f_flag & (FREAD | FWRITE)) == 0) { - fdrop(fp, td); - return (EBADF); + error = EBADF; + goto out; } - fdp = td->td_proc->p_fd; + switch (com) { case FIONCLEX: - FILEDESC_XLOCK(fdp); fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE; - FILEDESC_XUNLOCK(fdp); goto out; case FIOCLEX: - FILEDESC_XLOCK(fdp); fdp->fd_ofileflags[fd] |= UF_EXCLOSE; - FILEDESC_XUNLOCK(fdp); goto out; case FIONBIO: if ((tmp = *(int *)data)) @@ -744,7 +755,10 @@ error = fo_ioctl(fp, com, data, td->td_ucred, td); out: - fdrop(fp, td); + if (locked) + FILEDESC_XUNLOCK(fdp); + if (fp != NULL) + fdrop(fp, td); return (error); }