sys_generic.c (86341) | sys_generic.c (89306) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 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. --- 22 unchanged lines hidden (view full) --- 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 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 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. --- 22 unchanged lines hidden (view full) --- 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 * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 |
39 * $FreeBSD: head/sys/kern/sys_generic.c 86341 2001-11-14 06:30:36Z dillon $ | 39 * $FreeBSD: head/sys/kern/sys_generic.c 89306 2002-01-13 11:58:06Z alfred $ |
40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 30 unchanged lines hidden (view full) --- 78static int pollholddrop __P((struct thread *, struct pollfd *, u_int, int)); 79static int selscan __P((struct thread *, fd_mask **, fd_mask **, int)); 80static int selholddrop __P((struct thread *, fd_mask *, fd_mask *, int, int)); 81static int dofileread __P((struct thread *, struct file *, int, void *, 82 size_t, off_t, int)); 83static int dofilewrite __P((struct thread *, struct file *, int, 84 const void *, size_t, off_t, int)); 85 | 40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 30 unchanged lines hidden (view full) --- 78static int pollholddrop __P((struct thread *, struct pollfd *, u_int, int)); 79static int selscan __P((struct thread *, fd_mask **, fd_mask **, int)); 80static int selholddrop __P((struct thread *, fd_mask *, fd_mask *, int, int)); 81static int dofileread __P((struct thread *, struct file *, int, void *, 82 size_t, off_t, int)); 83static int dofilewrite __P((struct thread *, struct file *, int, 84 const void *, size_t, off_t, int)); 85 |
86struct file* 87holdfp(fdp, fd, flag) 88 struct filedesc* fdp; 89 int fd, flag; 90{ 91 struct file* fp; 92 93 FILEDESC_LOCK(fdp); 94 if (((u_int)fd) >= fdp->fd_nfiles || 95 (fp = fdp->fd_ofiles[fd]) == NULL) { 96 FILEDESC_UNLOCK(fdp); 97 return (NULL); 98 } 99 FILE_LOCK(fp); 100 FILEDESC_UNLOCK(fdp); 101 if ((fp->f_flag & flag) == 0) { 102 FILE_UNLOCK(fp); 103 return (NULL); 104 } 105 fp->f_count++; 106 FILE_UNLOCK(fp); 107 return (fp); 108} 109 |
|
86/* 87 * Read system call. 88 */ 89#ifndef _SYS_SYSPROTO_H_ 90struct read_args { 91 int fd; 92 void *buf; 93 size_t nbyte; --- 38 unchanged lines hidden (view full) --- 132int 133pread(td, uap) 134 struct thread *td; 135 struct pread_args *uap; 136{ 137 struct file *fp; 138 int error; 139 | 110/* 111 * Read system call. 112 */ 113#ifndef _SYS_SYSPROTO_H_ 114struct read_args { 115 int fd; 116 void *buf; 117 size_t nbyte; --- 38 unchanged lines hidden (view full) --- 156int 157pread(td, uap) 158 struct thread *td; 159 struct pread_args *uap; 160{ 161 struct file *fp; 162 int error; 163 |
140 mtx_lock(&Giant); 141 if ((error = fget_read(td, uap->fd, &fp)) == 0) { 142 if (fp->f_type == DTYPE_VNODE) { 143 error = dofileread(td, fp, uap->fd, uap->buf, 144 uap->nbyte, uap->offset, FOF_OFFSET); 145 } else { 146 error = ESPIPE; 147 } 148 fdrop(fp, td); | 164 fp = holdfp(td->td_proc->p_fd, uap->fd, FREAD); 165 if (fp == NULL) 166 return (EBADF); 167 if (fp->f_type != DTYPE_VNODE) { 168 error = ESPIPE; 169 } else { 170 mtx_lock(&Giant); 171 error = dofileread(td, fp, uap->fd, uap->buf, uap->nbyte, 172 uap->offset, FOF_OFFSET); 173 mtx_unlock(&Giant); |
149 } | 174 } |
150 mtx_unlock(&Giant); | 175 fdrop(fp, td); |
151 return(error); 152} 153 154/* 155 * Code common for read and pread 156 */ 157int 158dofileread(td, fp, fd, buf, nbyte, offset, flags) --- 217 unchanged lines hidden (view full) --- 376 uap->nbyte, uap->offset, FOF_OFFSET); 377 } else { 378 error = ESPIPE; 379 } 380 fdrop(fp, td); 381 } else { 382 error = EBADF; /* this can't be right */ 383 } | 176 return(error); 177} 178 179/* 180 * Code common for read and pread 181 */ 182int 183dofileread(td, fp, fd, buf, nbyte, offset, flags) --- 217 unchanged lines hidden (view full) --- 401 uap->nbyte, uap->offset, FOF_OFFSET); 402 } else { 403 error = ESPIPE; 404 } 405 fdrop(fp, td); 406 } else { 407 error = EBADF; /* this can't be right */ 408 } |
384 mtx_unlock(&Giant); | |
385 return(error); 386} 387 388static int 389dofilewrite(td, fp, fd, buf, nbyte, offset, flags) 390 struct thread *td; 391 struct file *fp; 392 int fd, flags; --- 194 unchanged lines hidden (view full) --- 587 caddr_t data, memp; 588 int tmp; 589#define STK_PARAMS 128 590 union { 591 char stkbuf[STK_PARAMS]; 592 long align; 593 } ubuf; 594 | 409 return(error); 410} 411 412static int 413dofilewrite(td, fp, fd, buf, nbyte, offset, flags) 414 struct thread *td; 415 struct file *fp; 416 int fd, flags; --- 194 unchanged lines hidden (view full) --- 611 caddr_t data, memp; 612 int tmp; 613#define STK_PARAMS 128 614 union { 615 char stkbuf[STK_PARAMS]; 616 long align; 617 } ubuf; 618 |
595 mtx_lock(&Giant); 596 fdp = td->td_proc->p_fd; 597 if ((u_int)uap->fd >= fdp->fd_nfiles || 598 (fp = fdp->fd_ofiles[uap->fd]) == NULL) { 599 error = EBADF; 600 goto done2; 601 } 602 | 619 fp = ffind_hold(td, uap->fd); 620 if (fp == NULL) 621 return (EBADF); |
603 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { | 622 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { |
604 error = EBADF; 605 goto done2; | 623 fdrop(fp, td); 624 return (EBADF); |
606 } | 625 } |
607 | 626 fdp = td->td_proc->p_fd; |
608 switch (com = uap->com) { 609 case FIONCLEX: | 627 switch (com = uap->com) { 628 case FIONCLEX: |
629 FILEDESC_LOCK(fdp); |
|
610 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; | 630 fdp->fd_ofileflags[uap->fd] &= ~UF_EXCLOSE; |
611 goto done2; | 631 FILEDESC_UNLOCK(fdp); 632 fdrop(fp, td); 633 return (0); |
612 case FIOCLEX: | 634 case FIOCLEX: |
635 FILEDESC_LOCK(fdp); |
|
613 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; | 636 fdp->fd_ofileflags[uap->fd] |= UF_EXCLOSE; |
614 goto done2; | 637 FILEDESC_UNLOCK(fdp); 638 fdrop(fp, td); 639 return (0); |
615 } 616 617 /* 618 * Interpret high order word to find amount of data to be 619 * copied to/from the user's address space. 620 */ 621 size = IOCPARM_LEN(com); 622 if (size > IOCPARM_MAX) { | 640 } 641 642 /* 643 * Interpret high order word to find amount of data to be 644 * copied to/from the user's address space. 645 */ 646 size = IOCPARM_LEN(com); 647 if (size > IOCPARM_MAX) { |
623 error = ENOTTY; 624 goto done2; | 648 fdrop(fp, td); 649 return (ENOTTY); |
625 } 626 | 650 } 651 |
627 fhold(fp); 628 | 652 mtx_lock(&Giant); |
629 memp = NULL; 630 if (size > sizeof (ubuf.stkbuf)) { 631 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 632 data = memp; 633 } else { 634 data = ubuf.stkbuf; 635 } 636 if (com&IOC_IN) { 637 if (size) { 638 error = copyin(uap->data, data, (u_int)size); 639 if (error) { 640 if (memp) 641 free(memp, M_IOCTLOPS); 642 fdrop(fp, td); | 653 memp = NULL; 654 if (size > sizeof (ubuf.stkbuf)) { 655 memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK); 656 data = memp; 657 } else { 658 data = ubuf.stkbuf; 659 } 660 if (com&IOC_IN) { 661 if (size) { 662 error = copyin(uap->data, data, (u_int)size); 663 if (error) { 664 if (memp) 665 free(memp, M_IOCTLOPS); 666 fdrop(fp, td); |
643 goto done2; | 667 goto done; |
644 } 645 } else { 646 *(caddr_t *)data = uap->data; 647 } 648 } else if ((com&IOC_OUT) && size) { 649 /* 650 * Zero the buffer so the user always 651 * gets back something deterministic. 652 */ 653 bzero(data, size); 654 } else if (com&IOC_VOID) { 655 *(caddr_t *)data = uap->data; 656 } 657 658 switch (com) { 659 660 case FIONBIO: | 668 } 669 } else { 670 *(caddr_t *)data = uap->data; 671 } 672 } else if ((com&IOC_OUT) && size) { 673 /* 674 * Zero the buffer so the user always 675 * gets back something deterministic. 676 */ 677 bzero(data, size); 678 } else if (com&IOC_VOID) { 679 *(caddr_t *)data = uap->data; 680 } 681 682 switch (com) { 683 684 case FIONBIO: |
685 FILE_LOCK(fp); |
|
661 if ((tmp = *(int *)data)) 662 fp->f_flag |= FNONBLOCK; 663 else 664 fp->f_flag &= ~FNONBLOCK; | 686 if ((tmp = *(int *)data)) 687 fp->f_flag |= FNONBLOCK; 688 else 689 fp->f_flag &= ~FNONBLOCK; |
690 FILE_UNLOCK(fp); |
|
665 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 666 break; 667 668 case FIOASYNC: | 691 error = fo_ioctl(fp, FIONBIO, (caddr_t)&tmp, td); 692 break; 693 694 case FIOASYNC: |
695 FILE_LOCK(fp); |
|
669 if ((tmp = *(int *)data)) 670 fp->f_flag |= FASYNC; 671 else 672 fp->f_flag &= ~FASYNC; | 696 if ((tmp = *(int *)data)) 697 fp->f_flag |= FASYNC; 698 else 699 fp->f_flag &= ~FASYNC; |
700 FILE_UNLOCK(fp); |
|
673 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, td); 674 break; 675 676 default: 677 error = fo_ioctl(fp, com, data, td); 678 /* 679 * Copy any data to user, size was 680 * already set and checked above. 681 */ 682 if (error == 0 && (com&IOC_OUT) && size) 683 error = copyout(data, uap->data, (u_int)size); 684 break; 685 } 686 if (memp) 687 free(memp, M_IOCTLOPS); 688 fdrop(fp, td); | 701 error = fo_ioctl(fp, FIOASYNC, (caddr_t)&tmp, td); 702 break; 703 704 default: 705 error = fo_ioctl(fp, com, data, td); 706 /* 707 * Copy any data to user, size was 708 * already set and checked above. 709 */ 710 if (error == 0 && (com&IOC_OUT) && size) 711 error = copyout(data, uap->data, (u_int)size); 712 break; 713 } 714 if (memp) 715 free(memp, M_IOCTLOPS); 716 fdrop(fp, td); |
689done2: | 717done: |
690 mtx_unlock(&Giant); 691 return (error); 692} 693 694static int nselcoll; /* Select collisions since boot */ 695struct cv selwait; 696SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); 697 --- 10 unchanged lines hidden (view full) --- 708/* 709 * MPSAFE 710 */ 711int 712select(td, uap) 713 register struct thread *td; 714 register struct select_args *uap; 715{ | 718 mtx_unlock(&Giant); 719 return (error); 720} 721 722static int nselcoll; /* Select collisions since boot */ 723struct cv selwait; 724SYSCTL_INT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); 725 --- 10 unchanged lines hidden (view full) --- 736/* 737 * MPSAFE 738 */ 739int 740select(td, uap) 741 register struct thread *td; 742 register struct select_args *uap; 743{ |
744 struct filedesc *fdp; |
|
716 /* 717 * The magic 2048 here is chosen to be just enough for FD_SETSIZE 718 * infds with the new FD_SETSIZE of 1024, and more than enough for 719 * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE 720 * of 256. 721 */ 722 fd_mask s_selbits[howmany(2048, NFDBITS)]; 723 fd_mask s_heldbits[howmany(2048, NFDBITS)]; 724 fd_mask *ibits[3], *obits[3], *selbits, *sbp, *heldbits, *hibits, *hobits; 725 struct timeval atv, rtv, ttv; 726 int ncoll, error, timo, i; 727 u_int nbufbytes, ncpbytes, nfdbits; 728 729 if (uap->nd < 0) 730 return (EINVAL); | 745 /* 746 * The magic 2048 here is chosen to be just enough for FD_SETSIZE 747 * infds with the new FD_SETSIZE of 1024, and more than enough for 748 * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE 749 * of 256. 750 */ 751 fd_mask s_selbits[howmany(2048, NFDBITS)]; 752 fd_mask s_heldbits[howmany(2048, NFDBITS)]; 753 fd_mask *ibits[3], *obits[3], *selbits, *sbp, *heldbits, *hibits, *hobits; 754 struct timeval atv, rtv, ttv; 755 int ncoll, error, timo, i; 756 u_int nbufbytes, ncpbytes, nfdbits; 757 758 if (uap->nd < 0) 759 return (EINVAL); |
731 | 760 fdp = td->td_proc->p_fd; |
732 mtx_lock(&Giant); | 761 mtx_lock(&Giant); |
762 FILEDESC_LOCK(fdp); |
|
733 734 if (uap->nd > td->td_proc->p_fd->fd_nfiles) 735 uap->nd = td->td_proc->p_fd->fd_nfiles; /* forgiving; slightly wrong */ | 763 764 if (uap->nd > td->td_proc->p_fd->fd_nfiles) 765 uap->nd = td->td_proc->p_fd->fd_nfiles; /* forgiving; slightly wrong */ |
766 FILEDESC_UNLOCK(fdp); |
|
736 737 /* 738 * Allocate just enough bits for the non-null fd_sets. Use the 739 * preallocated auto buffer if possible. 740 */ 741 nfdbits = roundup(uap->nd, NFDBITS); 742 ncpbytes = nfdbits / NBBY; 743 nbufbytes = 0; --- 138 unchanged lines hidden (view full) --- 882 free(selbits, M_SELECT); 883 if (heldbits != &s_heldbits[0]) 884 free(heldbits, M_SELECT); 885 886 mtx_unlock(&Giant); 887 return (error); 888} 889 | 767 768 /* 769 * Allocate just enough bits for the non-null fd_sets. Use the 770 * preallocated auto buffer if possible. 771 */ 772 nfdbits = roundup(uap->nd, NFDBITS); 773 ncpbytes = nfdbits / NBBY; 774 nbufbytes = 0; --- 138 unchanged lines hidden (view full) --- 913 free(selbits, M_SELECT); 914 if (heldbits != &s_heldbits[0]) 915 free(heldbits, M_SELECT); 916 917 mtx_unlock(&Giant); 918 return (error); 919} 920 |
921/* 922 * Used to hold then release a group of fds for select(2). 923 * Hold (hold == 1) or release (hold == 0) a group of filedescriptors. 924 * if holding then use ibits setting the bits in obits, otherwise use obits. 925 */ |
|
890static int 891selholddrop(td, ibits, obits, nfd, hold) 892 struct thread *td; 893 fd_mask *ibits, *obits; 894 int nfd, hold; 895{ 896 struct filedesc *fdp = td->td_proc->p_fd; 897 int i, fd; 898 fd_mask bits; 899 struct file *fp; 900 | 926static int 927selholddrop(td, ibits, obits, nfd, hold) 928 struct thread *td; 929 fd_mask *ibits, *obits; 930 int nfd, hold; 931{ 932 struct filedesc *fdp = td->td_proc->p_fd; 933 int i, fd; 934 fd_mask bits; 935 struct file *fp; 936 |
937 FILEDESC_LOCK(fdp); |
|
901 for (i = 0; i < nfd; i += NFDBITS) { 902 if (hold) 903 bits = ibits[i/NFDBITS]; 904 else 905 bits = obits[i/NFDBITS]; 906 /* ffs(int mask) not portable, fd_mask is long */ 907 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 908 if (!(bits & 1)) 909 continue; 910 fp = fdp->fd_ofiles[fd]; | 938 for (i = 0; i < nfd; i += NFDBITS) { 939 if (hold) 940 bits = ibits[i/NFDBITS]; 941 else 942 bits = obits[i/NFDBITS]; 943 /* ffs(int mask) not portable, fd_mask is long */ 944 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 945 if (!(bits & 1)) 946 continue; 947 fp = fdp->fd_ofiles[fd]; |
911 if (fp == NULL) | 948 if (fp == NULL) { 949 FILEDESC_UNLOCK(fdp); |
912 return (EBADF); | 950 return (EBADF); |
951 } |
|
913 if (hold) { 914 fhold(fp); 915 obits[(fd)/NFDBITS] |= 916 ((fd_mask)1 << ((fd) % NFDBITS)); | 952 if (hold) { 953 fhold(fp); 954 obits[(fd)/NFDBITS] |= 955 ((fd_mask)1 << ((fd) % NFDBITS)); |
917 } else | 956 } else { 957 /* XXX: optimize by making a special 958 * version of fdrop that only unlocks 959 * the filedesc if needed? This would 960 * redcuce the number of lock/unlock 961 * pairs by quite a bit. 962 */ 963 FILEDESC_UNLOCK(fdp); |
918 fdrop(fp, td); | 964 fdrop(fp, td); |
965 FILEDESC_LOCK(fdp); 966 } |
|
919 } 920 } | 967 } 968 } |
969 FILEDESC_UNLOCK(fdp); |
|
921 return (0); 922} 923 924static int 925selscan(td, ibits, obits, nfd) 926 struct thread *td; 927 fd_mask **ibits, **obits; 928 int nfd; 929{ | 970 return (0); 971} 972 973static int 974selscan(td, ibits, obits, nfd) 975 struct thread *td; 976 fd_mask **ibits, **obits; 977 int nfd; 978{ |
930 struct filedesc *fdp = td->td_proc->p_fd; | |
931 int msk, i, fd; 932 fd_mask bits; 933 struct file *fp; 934 int n = 0; 935 /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ 936 static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; 937 938 for (msk = 0; msk < 3; msk++) { 939 if (ibits[msk] == NULL) 940 continue; 941 for (i = 0; i < nfd; i += NFDBITS) { 942 bits = ibits[msk][i/NFDBITS]; 943 /* ffs(int mask) not portable, fd_mask is long */ 944 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 945 if (!(bits & 1)) 946 continue; | 979 int msk, i, fd; 980 fd_mask bits; 981 struct file *fp; 982 int n = 0; 983 /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ 984 static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; 985 986 for (msk = 0; msk < 3; msk++) { 987 if (ibits[msk] == NULL) 988 continue; 989 for (i = 0; i < nfd; i += NFDBITS) { 990 bits = ibits[msk][i/NFDBITS]; 991 /* ffs(int mask) not portable, fd_mask is long */ 992 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 993 if (!(bits & 1)) 994 continue; |
947 fp = fdp->fd_ofiles[fd]; | 995 fp = ffind_hold(td, fd); |
948 if (fp == NULL) 949 return (EBADF); 950 if (fo_poll(fp, flag[msk], fp->f_cred, td)) { 951 obits[msk][(fd)/NFDBITS] |= 952 ((fd_mask)1 << ((fd) % NFDBITS)); 953 n++; 954 } | 996 if (fp == NULL) 997 return (EBADF); 998 if (fo_poll(fp, flag[msk], fp->f_cred, td)) { 999 obits[msk][(fd)/NFDBITS] |= 1000 ((fd_mask)1 << ((fd) % NFDBITS)); 1001 n++; 1002 } |
1003 fdrop(fp, td); |
|
955 } 956 } 957 } 958 td->td_retval[0] = n; 959 return (0); 960} 961 962/* --- 148 unchanged lines hidden (view full) --- 1111 struct pollfd *fds; 1112 u_int nfd; 1113 int hold; 1114{ 1115 register struct filedesc *fdp = td->td_proc->p_fd; 1116 int i; 1117 struct file *fp; 1118 | 1004 } 1005 } 1006 } 1007 td->td_retval[0] = n; 1008 return (0); 1009} 1010 1011/* --- 148 unchanged lines hidden (view full) --- 1160 struct pollfd *fds; 1161 u_int nfd; 1162 int hold; 1163{ 1164 register struct filedesc *fdp = td->td_proc->p_fd; 1165 int i; 1166 struct file *fp; 1167 |
1168 FILEDESC_LOCK(fdp); |
|
1119 for (i = 0; i < nfd; i++, fds++) { 1120 if (0 <= fds->fd && fds->fd < fdp->fd_nfiles) { 1121 fp = fdp->fd_ofiles[fds->fd]; 1122 if (hold) { 1123 if (fp != NULL) { 1124 fhold(fp); 1125 fds->revents = 1; 1126 } else 1127 fds->revents = 0; | 1169 for (i = 0; i < nfd; i++, fds++) { 1170 if (0 <= fds->fd && fds->fd < fdp->fd_nfiles) { 1171 fp = fdp->fd_ofiles[fds->fd]; 1172 if (hold) { 1173 if (fp != NULL) { 1174 fhold(fp); 1175 fds->revents = 1; 1176 } else 1177 fds->revents = 0; |
1128 } else if(fp != NULL && fds->revents) 1129 fdrop(fp, td); | 1178 } else if(fp != NULL && fds->revents) { 1179 FILE_LOCK(fp); 1180 FILEDESC_UNLOCK(fdp); 1181 fdrop_locked(fp, td); 1182 FILEDESC_LOCK(fdp); 1183 } |
1130 } 1131 } | 1184 } 1185 } |
1186 FILEDESC_UNLOCK(fdp); |
|
1132 return (0); 1133} 1134 1135static int 1136pollscan(td, fds, nfd) 1137 struct thread *td; 1138 struct pollfd *fds; 1139 u_int nfd; 1140{ 1141 register struct filedesc *fdp = td->td_proc->p_fd; 1142 int i; 1143 struct file *fp; 1144 int n = 0; 1145 1146 for (i = 0; i < nfd; i++, fds++) { | 1187 return (0); 1188} 1189 1190static int 1191pollscan(td, fds, nfd) 1192 struct thread *td; 1193 struct pollfd *fds; 1194 u_int nfd; 1195{ 1196 register struct filedesc *fdp = td->td_proc->p_fd; 1197 int i; 1198 struct file *fp; 1199 int n = 0; 1200 1201 for (i = 0; i < nfd; i++, fds++) { |
1202 FILEDESC_LOCK(fdp); |
|
1147 if (fds->fd >= fdp->fd_nfiles) { 1148 fds->revents = POLLNVAL; 1149 n++; | 1203 if (fds->fd >= fdp->fd_nfiles) { 1204 fds->revents = POLLNVAL; 1205 n++; |
1206 FILEDESC_UNLOCK(fdp); |
|
1150 } else if (fds->fd < 0) { 1151 fds->revents = 0; | 1207 } else if (fds->fd < 0) { 1208 fds->revents = 0; |
1209 FILEDESC_UNLOCK(fdp); |
|
1152 } else { 1153 fp = fdp->fd_ofiles[fds->fd]; | 1210 } else { 1211 fp = fdp->fd_ofiles[fds->fd]; |
1212 FILEDESC_UNLOCK(fdp); |
|
1154 if (fp == NULL) { 1155 fds->revents = POLLNVAL; 1156 n++; 1157 } else { 1158 /* 1159 * Note: backend also returns POLLHUP and 1160 * POLLERR if appropriate. 1161 */ --- 137 unchanged lines hidden --- | 1213 if (fp == NULL) { 1214 fds->revents = POLLNVAL; 1215 n++; 1216 } else { 1217 /* 1218 * Note: backend also returns POLLHUP and 1219 * POLLERR if appropriate. 1220 */ --- 137 unchanged lines hidden --- |