Call to select() function with more than 247 socket descript

Call to select() function with more than 247 socket descriptors added to read descriptor set results in error

See the attached code example (also added to ‘How to reproduce’) whereby variable NR_RFDS set to an value higher than 247 results in an error “Bad file descriptor”.

This limit seems not to exist for, for example, pipes and open files.
What is the reason for this limit? How can this limit be removed?
How to Reproduce Code example:

[code]#ifdef FD_SETSIZE
#undef FD_SETSIZE
#endif
#define FD_SETSIZE 1000

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/socket.h>

#define NR_RFDS 248

int main( void )
{
int fd_array[NR_RFDS];
struct timeval tv;
fd_set rfd;
int n, rfd_max = 0;

for( n = 0; n < NR_RFDS; n++ )
{
fd_array[n] = socket(AF_INET, SOCK_STREAM, 0);
if (fd_array[n] < 0)
{
perror( “open” );
return EXIT_FAILURE;
}
}

FD_ZERO( &rfd );
for( n = 0; n < NR_RFDS; n++ )
{
FD_SET( fd_array[n], &rfd );
if( fd_array[n] > rfd_max )
{
rfd_max = fd_array[n];
}
}

tv.tv_sec = 1;
tv.tv_usec = 0;

switch ( n = select( 1 + rfd_max, &rfd, 0, 0, &tv ) )
{
case -1:
perror( “select” );
return EXIT_FAILURE;
case 0:
puts( “select timed out” );
break;
default:
printf( “%d descriptors ready …\n”, n );

for( n = 0; n < NR_RFDS; n++ )
{
if( FD_ISSET( fd_array[n], &rfd ) )
{
printf( " – %d descriptor has data pending", fd_array[n] );
}
}
}
return EXIT_SUCCESS;
}
[/code]

Run:

./example

select: Bad file descriptor

That make sense to me.

fd_setsize is defined to be 256. You’ve probably exceeded it at 247 (the missing other fd’s are used by stderr, stdout, other open files etc).

You can change the size if fd_setsize and then recompile. It’s mentioned here:

qnx.com/developers/docs/6.3. … ml?lang=kr

Tim

Thanks so much for your reply. Very useful info. I will update you about the result. :laughing:

FD_SETSIZE is (re)defined to 1000 in the given example.
Could there be another reason for the “Bad file descriptor” error?

Not that I’m aware of

This line from the link I sent you concerns me:
Note: The global recompile should include all application code, as well as library code that would be referencing fd_set or structures containing fd_set. If you don’t recompile, you may see random corruption and crashes.

Not sure what library code you have to recompile. Whether it just means any library code you created or the C/C++ library code that normally comes with the O/S (for example the select() code itself). If it’s the latter, I am not sure how you’d do that without the source code.

Since you have a QNX license you might want to go over to foundry27 and ask there where the developers hang our more often and you might get some more info on this.

Tim

Hi Guy, As promised, here is the update from QNX technical support channel.

They reproduced the issue. They recognized as the bug.

“I found an existing JIRA bug report (ID xxxxx) for your case. Unfortunately, we will only release fixes for QNX 7.0 and later. I’d suggest you contact your sales rep to discuss options.”