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

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

Discussion about the QNX6 OS.

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

Postby luan0ma » Fri Mar 23, 2018 5:17 pm

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: Select all
#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;
}


Run:
# ./example
select: Bad file descriptor
luan0ma
Active Member
 
Posts: 10
Joined: Wed Jan 13, 2016 3:30 pm

Re: Call to select() function with more than 247 socket desc

Postby Tim » Fri Mar 23, 2018 10:26 pm

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:

http://www.qnx.com/developers/docs/6.3. ... ml?lang=kr

FD_SETSIZE
The value of FD_SETSIZE has changed from 32 to 256. This affects the size of the fd_set objects that you pass to select().

This means that by default the highest allowable fd number for FD_SET(fd, &set) is 255.

Any use of fd_set within data structures will therefore cause a change in structure size, so you should do a global recompile.

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.
To make the value higher, #define FD_SETSIZE before including <sys/select.h>. But make sure this is done consistently throughout your modules.

If you don't want to cause a global compile, you can #define FD_SETSIZE 32 before including <sys/select.h> (or -DFD_SETSIZE=32 on the command line) to set it back to the old size, but make sure this setting is consistently applied to all your code.


Tim
Tim
Senior Member
 
Posts: 1431
Joined: Wed Mar 10, 2004 12:28 am

Re: Call to select() function with more than 247 socket desc

Postby luan0ma » Mon Mar 26, 2018 8:40 am

Thanks so much for your reply. Very useful info. I will update you about the result. :lol:
luan0ma
Active Member
 
Posts: 10
Joined: Wed Jan 13, 2016 3:30 pm

Re: Call to select() function with more than 247 socket desc

Postby eijsjjj » Tue Apr 03, 2018 11:48 am

FD_SETSIZE is (re)defined to 1000 in the given example.
Could there be another reason for the "Bad file descriptor" error?
eijsjjj
New Member
 
Posts: 1
Joined: Wed Mar 28, 2018 10:32 am

Re: Call to select() function with more than 247 socket desc

Postby Tim » Tue Apr 03, 2018 4:38 pm

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
Tim
Senior Member
 
Posts: 1431
Joined: Wed Mar 10, 2004 12:28 am

Re: Call to select() function with more than 247 socket desc

Postby luan0ma » Wed Apr 04, 2018 11:30 am

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."
luan0ma
Active Member
 
Posts: 10
Joined: Wed Jan 13, 2016 3:30 pm


Return to QNX6 - OS

Who is online

Users browsing this forum: No registered users and 3 guests

cron