[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
ia64/91421: FD_ISSET returns long, not int.
>Number: 91421
>Category: ia64
>Synopsis: FD_ISSET returns long, not int.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-ia64
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Jan 06 21:10:02 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Tanaka Akira
>Release: 6.0-RELEASE
>Organization:
AIST
>Environment:
FreeBSD td150.testdrive.hp.com 6.0-RELEASE FreeBSD 6.0-RELEASE #0: Wed Nov 2 10:01:27 UTC 2005 root@xxxxxxxxxxxxxxxxxx:/usr/obj/usr/src/sys/GENERIC ia64
>Description:
On IA64 (and other LP64 environments),
(int)FD_ISSET(32, &fds) is evaluated to 0, even if 32 is set in fds.
Since SUSv3 defines FD_ISSET defines as follows, cast to int should be safe.
int FD_ISSET(int fd, fd_set *fdset);
This problem is caused because FD_ISSET() returns single unsigned long bitmap.
(__fds_bits is an array of unsigned long)
td150.testdrive.hp.com> grep FD_ISSET /usr/include/sys/select.h
#define FD_ISSET(n, p) ((p)->__fds_bits[(n)/_NFDBITS] & __fdset_mask(n))
Since unsigned long is longer than int on LP64,
(int)FD_ISSET() discards upper 32bits.
>How-To-Repeat:
td150.testdrive.hp.com> cat tst.c
#include <stdio.h>
#include <sys/select.h>
int main()
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(32, &fds);
printf("%d\n", (int)FD_ISSET(32, &fds));
printf("%lx\n", (long)FD_ISSET(32, &fds));
return 0;
}
td150.testdrive.hp.com> gcc tst.c
td150.testdrive.hp.com> ./a.out
0
100000000
>Fix:
add "!= 0".
#define FD_ISSET(n, p) (((p)->__fds_bits[(n)/_NFDBITS] & __fdset_mask(n)) != 0)
>Release-Note:
>Audit-Trail:
>Unformatted: