summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_generic.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2000-02-20 13:36:26 +0000
committerpeter <peter@FreeBSD.org>2000-02-20 13:36:26 +0000
commit21e6913264b1b666cc015d6e9e730f75dddbd3d1 (patch)
tree3cb81db53d20a24a9b3e5b67edad405c49a4a972 /sys/kern/sys_generic.c
parentc4d21ca2295695a9c0be375a61a88fd61a40bab0 (diff)
downloadFreeBSD-src-21e6913264b1b666cc015d6e9e730f75dddbd3d1.zip
FreeBSD-src-21e6913264b1b666cc015d6e9e730f75dddbd3d1.tar.gz
Fix select(2) for the Alpha. (!!) It was never returning true for
fd's in the range of 32-63, 96-127 etc. The first problem was the FD_*() macros were shifting a 32 bit integer "1" left by more than 32 bits. The same problem happened in selscan(). ffs() also takes an int argument and causes failure. For cases where int == long (ie: the usual case for x86, but not always as gcc can have long being a 64 bit quantity) ffs() could be used. Reported by: Marian Stagarescu <marian@bile.skycache.com> Reviewed by: dfr, gallatin (sys/types.h only) Approved by: jkh
Diffstat (limited to 'sys/kern/sys_generic.c')
-rw-r--r--sys/kern/sys_generic.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 5962811..5ef9059 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -730,9 +730,9 @@ selscan(p, ibits, obits, nfd)
fd_mask **ibits, **obits;
int nfd;
{
- register struct filedesc *fdp = p->p_fd;
- register int msk, i, j, fd;
- register fd_mask bits;
+ struct filedesc *fdp = p->p_fd;
+ int msk, i, fd;
+ fd_mask bits;
struct file *fp;
int n = 0;
/* Note: backend also returns POLLHUP/POLLERR if appropriate. */
@@ -743,14 +743,16 @@ selscan(p, ibits, obits, nfd)
continue;
for (i = 0; i < nfd; i += NFDBITS) {
bits = ibits[msk][i/NFDBITS];
- while ((j = ffs(bits)) && (fd = i + --j) < nfd) {
- bits &= ~(1 << j);
+ /* ffs(int mask) not portable, fd_mask is long */
+ for (fd = i; bits && fd < nfd; fd++, bits >>= 1) {
+ if (!(bits & 1))
+ continue;
fp = fdp->fd_ofiles[fd];
if (fp == NULL)
return (EBADF);
if (fo_poll(fp, flag[msk], fp->f_cred, p)) {
obits[msk][(fd)/NFDBITS] |=
- (1 << ((fd) % NFDBITS));
+ ((fd_mask)1 << ((fd) % NFDBITS));
n++;
}
}
OpenPOWER on IntegriCloud