sys_generic.c (89695) | sys_generic.c (89969) |
---|---|
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 89695 2002-01-23 08:22:59Z alfred $ | 39 * $FreeBSD: head/sys/kern/sys_generic.c 89969 2002-01-29 22:54:19Z 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> --- 22 unchanged lines hidden (view full) --- 70 71#include <machine/limits.h> 72 73static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer"); 74static MALLOC_DEFINE(M_SELECT, "select", "select() buffer"); 75MALLOC_DEFINE(M_IOV, "iov", "large iov's"); 76 77static int pollscan __P((struct thread *, struct pollfd *, u_int)); | 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> --- 22 unchanged lines hidden (view full) --- 70 71#include <machine/limits.h> 72 73static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer"); 74static MALLOC_DEFINE(M_SELECT, "select", "select() buffer"); 75MALLOC_DEFINE(M_IOV, "iov", "large iov's"); 76 77static int pollscan __P((struct thread *, struct pollfd *, u_int)); |
78static int pollholddrop __P((struct thread *, struct pollfd *, u_int, int)); | |
79static int selscan __P((struct thread *, fd_mask **, fd_mask **, int)); | 78static 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 86/* 87 * Read system call. 88 */ --- 635 unchanged lines hidden (view full) --- 724 /* 725 * The magic 2048 here is chosen to be just enough for FD_SETSIZE 726 * infds with the new FD_SETSIZE of 1024, and more than enough for 727 * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE 728 * of 256. 729 */ 730 fd_mask s_selbits[howmany(2048, NFDBITS)]; 731 fd_mask s_heldbits[howmany(2048, NFDBITS)]; | 79static int dofileread __P((struct thread *, struct file *, int, void *, 80 size_t, off_t, int)); 81static int dofilewrite __P((struct thread *, struct file *, int, 82 const void *, size_t, off_t, int)); 83 84/* 85 * Read system call. 86 */ --- 635 unchanged lines hidden (view full) --- 722 /* 723 * The magic 2048 here is chosen to be just enough for FD_SETSIZE 724 * infds with the new FD_SETSIZE of 1024, and more than enough for 725 * FD_SETSIZE infds, outfds and exceptfds with the old FD_SETSIZE 726 * of 256. 727 */ 728 fd_mask s_selbits[howmany(2048, NFDBITS)]; 729 fd_mask s_heldbits[howmany(2048, NFDBITS)]; |
732 fd_mask *ibits[3], *obits[3], *selbits, *sbp, *heldbits, *hibits, *hobits; | 730 fd_mask *ibits[3], *obits[3], *selbits, *sbp; |
733 struct timeval atv, rtv, ttv; 734 int ncoll, error, timo, i; 735 u_int nbufbytes, ncpbytes, nfdbits; 736 737 if (uap->nd < 0) 738 return (EINVAL); 739 fdp = td->td_proc->p_fd; 740 mtx_lock(&Giant); --- 15 unchanged lines hidden (view full) --- 756 if (uap->ou != NULL) 757 nbufbytes += 2 * ncpbytes; 758 if (uap->ex != NULL) 759 nbufbytes += 2 * ncpbytes; 760 if (nbufbytes <= sizeof s_selbits) 761 selbits = &s_selbits[0]; 762 else 763 selbits = malloc(nbufbytes, M_SELECT, M_WAITOK); | 731 struct timeval atv, rtv, ttv; 732 int ncoll, error, timo, i; 733 u_int nbufbytes, ncpbytes, nfdbits; 734 735 if (uap->nd < 0) 736 return (EINVAL); 737 fdp = td->td_proc->p_fd; 738 mtx_lock(&Giant); --- 15 unchanged lines hidden (view full) --- 754 if (uap->ou != NULL) 755 nbufbytes += 2 * ncpbytes; 756 if (uap->ex != NULL) 757 nbufbytes += 2 * ncpbytes; 758 if (nbufbytes <= sizeof s_selbits) 759 selbits = &s_selbits[0]; 760 else 761 selbits = malloc(nbufbytes, M_SELECT, M_WAITOK); |
764 if (2 * ncpbytes <= sizeof s_heldbits) { 765 bzero(s_heldbits, sizeof(s_heldbits)); 766 heldbits = &s_heldbits[0]; 767 } else 768 heldbits = malloc(2 * ncpbytes, M_SELECT, M_WAITOK | M_ZERO); | |
769 770 /* 771 * Assign pointers into the bit buffers and fetch the input bits. 772 * Put the output buffers together so that they can be bzeroed 773 * together. 774 */ 775 sbp = selbits; | 762 763 /* 764 * Assign pointers into the bit buffers and fetch the input bits. 765 * Put the output buffers together so that they can be bzeroed 766 * together. 767 */ 768 sbp = selbits; |
776 hibits = heldbits + ncpbytes / sizeof *heldbits; 777 hobits = heldbits; | |
778#define getbits(name, x) \ 779 do { \ 780 if (uap->name == NULL) \ 781 ibits[x] = NULL; \ 782 else { \ 783 ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ 784 obits[x] = sbp; \ 785 sbp += ncpbytes / sizeof *sbp; \ 786 error = copyin(uap->name, ibits[x], ncpbytes); \ 787 if (error != 0) \ 788 goto done_noproclock; \ | 769#define getbits(name, x) \ 770 do { \ 771 if (uap->name == NULL) \ 772 ibits[x] = NULL; \ 773 else { \ 774 ibits[x] = sbp + nbufbytes / 2 / sizeof *sbp; \ 775 obits[x] = sbp; \ 776 sbp += ncpbytes / sizeof *sbp; \ 777 error = copyin(uap->name, ibits[x], ncpbytes); \ 778 if (error != 0) \ 779 goto done_noproclock; \ |
789 for (i = 0; \ 790 i < ncpbytes / sizeof ibits[i][0]; \ 791 i++) \ 792 hibits[i] |= ibits[x][i]; \ | |
793 } \ 794 } while (0) 795 getbits(in, 0); 796 getbits(ou, 1); 797 getbits(ex, 2); 798#undef getbits 799 if (nbufbytes != 0) 800 bzero(selbits, nbufbytes / 2); --- 8 unchanged lines hidden (view full) --- 809 goto done_noproclock; 810 } 811 getmicrouptime(&rtv); 812 timevaladd(&atv, &rtv); 813 } else { 814 atv.tv_sec = 0; 815 atv.tv_usec = 0; 816 } | 780 } \ 781 } while (0) 782 getbits(in, 0); 783 getbits(ou, 1); 784 getbits(ex, 2); 785#undef getbits 786 if (nbufbytes != 0) 787 bzero(selbits, nbufbytes / 2); --- 8 unchanged lines hidden (view full) --- 796 goto done_noproclock; 797 } 798 getmicrouptime(&rtv); 799 timevaladd(&atv, &rtv); 800 } else { 801 atv.tv_sec = 0; 802 atv.tv_usec = 0; 803 } |
817 selholddrop(td, hibits, hobits, uap->nd, 1); | |
818 timo = 0; 819 PROC_LOCK(td->td_proc); 820retry: 821 ncoll = nselcoll; 822 mtx_lock_spin(&sched_lock); 823 td->td_flags |= TDF_SELECT; 824 mtx_unlock_spin(&sched_lock); 825 PROC_UNLOCK(td->td_proc); --- 39 unchanged lines hidden (view full) --- 865 if (error == 0) 866 goto retry; 867 868done: 869 mtx_lock_spin(&sched_lock); 870 td->td_flags &= ~TDF_SELECT; 871 mtx_unlock_spin(&sched_lock); 872 PROC_UNLOCK(td->td_proc); | 804 timo = 0; 805 PROC_LOCK(td->td_proc); 806retry: 807 ncoll = nselcoll; 808 mtx_lock_spin(&sched_lock); 809 td->td_flags |= TDF_SELECT; 810 mtx_unlock_spin(&sched_lock); 811 PROC_UNLOCK(td->td_proc); --- 39 unchanged lines hidden (view full) --- 851 if (error == 0) 852 goto retry; 853 854done: 855 mtx_lock_spin(&sched_lock); 856 td->td_flags &= ~TDF_SELECT; 857 mtx_unlock_spin(&sched_lock); 858 PROC_UNLOCK(td->td_proc); |
873 selholddrop(td, hibits, hobits, uap->nd, 0); | |
874done_noproclock: 875 /* select is not restarted after signals... */ 876 if (error == ERESTART) 877 error = EINTR; 878 if (error == EWOULDBLOCK) 879 error = 0; 880#define putbits(name, x) \ 881 if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \ 882 error = error2; 883 if (error == 0) { 884 int error2; 885 886 putbits(in, 0); 887 putbits(ou, 1); 888 putbits(ex, 2); 889#undef putbits 890 } 891 if (selbits != &s_selbits[0]) 892 free(selbits, M_SELECT); | 859done_noproclock: 860 /* select is not restarted after signals... */ 861 if (error == ERESTART) 862 error = EINTR; 863 if (error == EWOULDBLOCK) 864 error = 0; 865#define putbits(name, x) \ 866 if (uap->name && (error2 = copyout(obits[x], uap->name, ncpbytes))) \ 867 error = error2; 868 if (error == 0) { 869 int error2; 870 871 putbits(in, 0); 872 putbits(ou, 1); 873 putbits(ex, 2); 874#undef putbits 875 } 876 if (selbits != &s_selbits[0]) 877 free(selbits, M_SELECT); |
893 if (heldbits != &s_heldbits[0]) 894 free(heldbits, M_SELECT); | |
895 896 mtx_unlock(&Giant); 897 return (error); 898} 899 | 878 879 mtx_unlock(&Giant); 880 return (error); 881} 882 |
900/* 901 * Used to hold then release a group of fds for select(2). 902 * Hold (hold == 1) or release (hold == 0) a group of filedescriptors. 903 * if holding then use ibits setting the bits in obits, otherwise use obits. 904 */ | |
905static int | 883static int |
906selholddrop(td, ibits, obits, nfd, hold) 907 struct thread *td; 908 fd_mask *ibits, *obits; 909 int nfd, hold; 910{ 911 struct filedesc *fdp = td->td_proc->p_fd; 912 int i, fd; 913 fd_mask bits; 914 struct file *fp; 915 916 FILEDESC_LOCK(fdp); 917 for (i = 0; i < nfd; i += NFDBITS) { 918 if (hold) 919 bits = ibits[i/NFDBITS]; 920 else 921 bits = obits[i/NFDBITS]; 922 /* ffs(int mask) not portable, fd_mask is long */ 923 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 924 if (!(bits & 1)) 925 continue; 926 fp = fdp->fd_ofiles[fd]; 927 if (fp == NULL) { 928 FILEDESC_UNLOCK(fdp); 929 return (EBADF); 930 } 931 if (hold) { 932 fhold(fp); 933 obits[(fd)/NFDBITS] |= 934 ((fd_mask)1 << ((fd) % NFDBITS)); 935 } else { 936 /* XXX: optimize by making a special 937 * version of fdrop that only unlocks 938 * the filedesc if needed? This would 939 * redcuce the number of lock/unlock 940 * pairs by quite a bit. 941 */ 942 FILEDESC_UNLOCK(fdp); 943 fdrop(fp, td); 944 FILEDESC_LOCK(fdp); 945 } 946 } 947 } 948 FILEDESC_UNLOCK(fdp); 949 return (0); 950} 951 952static int | |
953selscan(td, ibits, obits, nfd) 954 struct thread *td; 955 fd_mask **ibits, **obits; 956 int nfd; 957{ 958 int msk, i, fd; 959 fd_mask bits; 960 struct file *fp; 961 int n = 0; 962 /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ 963 static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; | 884selscan(td, ibits, obits, nfd) 885 struct thread *td; 886 fd_mask **ibits, **obits; 887 int nfd; 888{ 889 int msk, i, fd; 890 fd_mask bits; 891 struct file *fp; 892 int n = 0; 893 /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ 894 static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; |
895 struct filedesc *fdp = td->td_proc->p_fd; |
|
964 | 896 |
897 FILEDESC_LOCK(fdp); |
|
965 for (msk = 0; msk < 3; msk++) { 966 if (ibits[msk] == NULL) 967 continue; 968 for (i = 0; i < nfd; i += NFDBITS) { 969 bits = ibits[msk][i/NFDBITS]; 970 /* ffs(int mask) not portable, fd_mask is long */ 971 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 972 if (!(bits & 1)) 973 continue; | 898 for (msk = 0; msk < 3; msk++) { 899 if (ibits[msk] == NULL) 900 continue; 901 for (i = 0; i < nfd; i += NFDBITS) { 902 bits = ibits[msk][i/NFDBITS]; 903 /* ffs(int mask) not portable, fd_mask is long */ 904 for (fd = i; bits && fd < nfd; fd++, bits >>= 1) { 905 if (!(bits & 1)) 906 continue; |
974 if (fget(td, fd, &fp)) | 907 if ((fp = fget_locked(fdp, fd)) == NULL) { 908 FILEDESC_UNLOCK(fdp); |
975 return (EBADF); | 909 return (EBADF); |
910 } |
|
976 if (fo_poll(fp, flag[msk], fp->f_cred, td)) { 977 obits[msk][(fd)/NFDBITS] |= 978 ((fd_mask)1 << ((fd) % NFDBITS)); 979 n++; 980 } | 911 if (fo_poll(fp, flag[msk], fp->f_cred, td)) { 912 obits[msk][(fd)/NFDBITS] |= 913 ((fd_mask)1 << ((fd) % NFDBITS)); 914 n++; 915 } |
981 fdrop(fp, td); | |
982 } 983 } 984 } | 916 } 917 } 918 } |
919 FILEDESC_UNLOCK(fdp); |
|
985 td->td_retval[0] = n; 986 return (0); 987} 988 989/* 990 * Poll system call. 991 */ 992#ifndef _SYS_SYSPROTO_H_ --- 12 unchanged lines hidden (view full) --- 1005 struct poll_args *uap; 1006{ 1007 caddr_t bits; 1008 char smallbits[32 * sizeof(struct pollfd)]; 1009 struct timeval atv, rtv, ttv; 1010 int ncoll, error = 0, timo; 1011 u_int nfds; 1012 size_t ni; | 920 td->td_retval[0] = n; 921 return (0); 922} 923 924/* 925 * Poll system call. 926 */ 927#ifndef _SYS_SYSPROTO_H_ --- 12 unchanged lines hidden (view full) --- 940 struct poll_args *uap; 941{ 942 caddr_t bits; 943 char smallbits[32 * sizeof(struct pollfd)]; 944 struct timeval atv, rtv, ttv; 945 int ncoll, error = 0, timo; 946 u_int nfds; 947 size_t ni; |
1013 struct pollfd p_heldbits[32]; 1014 struct pollfd *heldbits; | |
1015 1016 nfds = SCARG(uap, nfds); 1017 1018 mtx_lock(&Giant); 1019 /* 1020 * This is kinda bogus. We have fd limits, but that is not 1021 * really related to the size of the pollfd array. Make sure 1022 * we let the process use at least FD_SETSIZE entries and at --- 5 unchanged lines hidden (view full) --- 1028 error = EINVAL; 1029 goto done2; 1030 } 1031 ni = nfds * sizeof(struct pollfd); 1032 if (ni > sizeof(smallbits)) 1033 bits = malloc(ni, M_TEMP, M_WAITOK); 1034 else 1035 bits = smallbits; | 948 949 nfds = SCARG(uap, nfds); 950 951 mtx_lock(&Giant); 952 /* 953 * This is kinda bogus. We have fd limits, but that is not 954 * really related to the size of the pollfd array. Make sure 955 * we let the process use at least FD_SETSIZE entries and at --- 5 unchanged lines hidden (view full) --- 961 error = EINVAL; 962 goto done2; 963 } 964 ni = nfds * sizeof(struct pollfd); 965 if (ni > sizeof(smallbits)) 966 bits = malloc(ni, M_TEMP, M_WAITOK); 967 else 968 bits = smallbits; |
1036 if (ni > sizeof(p_heldbits)) 1037 heldbits = malloc(ni, M_TEMP, M_WAITOK); 1038 else { 1039 bzero(p_heldbits, sizeof(p_heldbits)); 1040 heldbits = p_heldbits; 1041 } | |
1042 error = copyin(SCARG(uap, fds), bits, ni); 1043 if (error) 1044 goto done_noproclock; | 969 error = copyin(SCARG(uap, fds), bits, ni); 970 if (error) 971 goto done_noproclock; |
1045 bcopy(bits, heldbits, ni); | |
1046 if (SCARG(uap, timeout) != INFTIM) { 1047 atv.tv_sec = SCARG(uap, timeout) / 1000; 1048 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 1049 if (itimerfix(&atv)) { 1050 error = EINVAL; 1051 goto done_noproclock; 1052 } 1053 getmicrouptime(&rtv); 1054 timevaladd(&atv, &rtv); 1055 } else { 1056 atv.tv_sec = 0; 1057 atv.tv_usec = 0; 1058 } | 972 if (SCARG(uap, timeout) != INFTIM) { 973 atv.tv_sec = SCARG(uap, timeout) / 1000; 974 atv.tv_usec = (SCARG(uap, timeout) % 1000) * 1000; 975 if (itimerfix(&atv)) { 976 error = EINVAL; 977 goto done_noproclock; 978 } 979 getmicrouptime(&rtv); 980 timevaladd(&atv, &rtv); 981 } else { 982 atv.tv_sec = 0; 983 atv.tv_usec = 0; 984 } |
1059 pollholddrop(td, heldbits, nfds, 1); | |
1060 timo = 0; 1061 PROC_LOCK(td->td_proc); 1062retry: 1063 ncoll = nselcoll; 1064 mtx_lock_spin(&sched_lock); 1065 td->td_flags |= TDF_SELECT; 1066 mtx_unlock_spin(&sched_lock); 1067 PROC_UNLOCK(td->td_proc); --- 37 unchanged lines hidden (view full) --- 1105 if (error == 0) 1106 goto retry; 1107 1108done: 1109 mtx_lock_spin(&sched_lock); 1110 td->td_flags &= ~TDF_SELECT; 1111 mtx_unlock_spin(&sched_lock); 1112 PROC_UNLOCK(td->td_proc); | 985 timo = 0; 986 PROC_LOCK(td->td_proc); 987retry: 988 ncoll = nselcoll; 989 mtx_lock_spin(&sched_lock); 990 td->td_flags |= TDF_SELECT; 991 mtx_unlock_spin(&sched_lock); 992 PROC_UNLOCK(td->td_proc); --- 37 unchanged lines hidden (view full) --- 1030 if (error == 0) 1031 goto retry; 1032 1033done: 1034 mtx_lock_spin(&sched_lock); 1035 td->td_flags &= ~TDF_SELECT; 1036 mtx_unlock_spin(&sched_lock); 1037 PROC_UNLOCK(td->td_proc); |
1113 pollholddrop(td, heldbits, nfds, 0); | |
1114done_noproclock: 1115 /* poll is not restarted after signals... */ 1116 if (error == ERESTART) 1117 error = EINTR; 1118 if (error == EWOULDBLOCK) 1119 error = 0; 1120 if (error == 0) { 1121 error = copyout(bits, SCARG(uap, fds), ni); 1122 if (error) 1123 goto out; 1124 } 1125out: 1126 if (ni > sizeof(smallbits)) 1127 free(bits, M_TEMP); | 1038done_noproclock: 1039 /* poll is not restarted after signals... */ 1040 if (error == ERESTART) 1041 error = EINTR; 1042 if (error == EWOULDBLOCK) 1043 error = 0; 1044 if (error == 0) { 1045 error = copyout(bits, SCARG(uap, fds), ni); 1046 if (error) 1047 goto out; 1048 } 1049out: 1050 if (ni > sizeof(smallbits)) 1051 free(bits, M_TEMP); |
1128 if (ni > sizeof(p_heldbits)) 1129 free(heldbits, M_TEMP); | |
1130done2: 1131 mtx_unlock(&Giant); 1132 return (error); 1133} 1134 1135static int | 1052done2: 1053 mtx_unlock(&Giant); 1054 return (error); 1055} 1056 1057static int |
1136pollholddrop(td, fds, nfd, hold) 1137 struct thread *td; 1138 struct pollfd *fds; 1139 u_int nfd; 1140 int hold; 1141{ 1142 register struct filedesc *fdp = td->td_proc->p_fd; 1143 int i; 1144 struct file *fp; 1145 1146 FILEDESC_LOCK(fdp); 1147 for (i = 0; i < nfd; i++, fds++) { 1148 if (0 <= fds->fd && fds->fd < fdp->fd_nfiles) { 1149 fp = fdp->fd_ofiles[fds->fd]; 1150 if (hold) { 1151 if (fp != NULL) { 1152 fhold(fp); 1153 fds->revents = 1; 1154 } else 1155 fds->revents = 0; 1156 } else if(fp != NULL && fds->revents) { 1157 FILE_LOCK(fp); 1158 FILEDESC_UNLOCK(fdp); 1159 fdrop_locked(fp, td); 1160 FILEDESC_LOCK(fdp); 1161 } 1162 } 1163 } 1164 FILEDESC_UNLOCK(fdp); 1165 return (0); 1166} 1167 1168static int | |
1169pollscan(td, fds, nfd) 1170 struct thread *td; 1171 struct pollfd *fds; 1172 u_int nfd; 1173{ 1174 register struct filedesc *fdp = td->td_proc->p_fd; 1175 int i; 1176 struct file *fp; 1177 int n = 0; 1178 | 1058pollscan(td, fds, nfd) 1059 struct thread *td; 1060 struct pollfd *fds; 1061 u_int nfd; 1062{ 1063 register struct filedesc *fdp = td->td_proc->p_fd; 1064 int i; 1065 struct file *fp; 1066 int n = 0; 1067 |
1068 FILEDESC_LOCK(fdp); |
|
1179 for (i = 0; i < nfd; i++, fds++) { | 1069 for (i = 0; i < nfd; i++, fds++) { |
1180 FILEDESC_LOCK(fdp); | |
1181 if (fds->fd >= fdp->fd_nfiles) { 1182 fds->revents = POLLNVAL; 1183 n++; | 1070 if (fds->fd >= fdp->fd_nfiles) { 1071 fds->revents = POLLNVAL; 1072 n++; |
1184 FILEDESC_UNLOCK(fdp); | |
1185 } else if (fds->fd < 0) { 1186 fds->revents = 0; | 1073 } else if (fds->fd < 0) { 1074 fds->revents = 0; |
1187 FILEDESC_UNLOCK(fdp); | |
1188 } else { 1189 fp = fdp->fd_ofiles[fds->fd]; | 1075 } else { 1076 fp = fdp->fd_ofiles[fds->fd]; |
1190 FILEDESC_UNLOCK(fdp); | |
1191 if (fp == NULL) { 1192 fds->revents = POLLNVAL; 1193 n++; 1194 } else { 1195 /* 1196 * Note: backend also returns POLLHUP and 1197 * POLLERR if appropriate. 1198 */ 1199 fds->revents = fo_poll(fp, fds->events, 1200 fp->f_cred, td); 1201 if (fds->revents != 0) 1202 n++; 1203 } 1204 } 1205 } | 1077 if (fp == NULL) { 1078 fds->revents = POLLNVAL; 1079 n++; 1080 } else { 1081 /* 1082 * Note: backend also returns POLLHUP and 1083 * POLLERR if appropriate. 1084 */ 1085 fds->revents = fo_poll(fp, fds->events, 1086 fp->f_cred, td); 1087 if (fds->revents != 0) 1088 n++; 1089 } 1090 } 1091 } |
1092 FILEDESC_UNLOCK(fdp); |
|
1206 td->td_retval[0] = n; 1207 return (0); 1208} 1209 1210/* 1211 * OpenBSD poll system call. 1212 * XXX this isn't quite a true representation.. OpenBSD uses select ops. 1213 */ --- 122 unchanged lines hidden --- | 1093 td->td_retval[0] = n; 1094 return (0); 1095} 1096 1097/* 1098 * OpenBSD poll system call. 1099 * XXX this isn't quite a true representation.. OpenBSD uses select ops. 1100 */ --- 122 unchanged lines hidden --- |