Deleted Added
full compact
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 ---