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