From: newsham@lava.net (Tim Newsham)
Subject: beta19 select() bug
14 Mar 1998 07:40:45 -0800
Message-ID: <m0yDFH6-00116uC.cygnus.gnu-win32@malasada.lava.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
To: gnu-win32@cygnus.com


Hi,

    The following script demonstrates a bug in the select() code
in cygwin b19 (tested against stock b19 release).  The program works
fine if 50 different file descriptors are selected on, but if 51
are selected on then the program will dump core.  I haven't looked
into the problem other than writing a test script so far.

                                   Tim N.



/*
 * selecting on 51 sockets fails (core dump) but 50 doesnt.
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>

#define SAVEERRNO(cmd)		\
	do {			\
	    int save = errno;	\
            cmd;		\
	    errno = save; 	\
	} while(0)

int
nonblock_connect(int addr, int port)
{
    struct sockaddr_in ad;
    int s, nonblock;

    s = socket(AF_INET, SOCK_STREAM, 0);
    if(s == -1)
        return -1;

    nonblock = 1;
    if(ioctl(s, FIONBIO, &nonblock) == -1) {
        SAVEERRNO(close(s));
        return -1;
    }

    memset(&ad, 0, sizeof ad);
    ad.sin_family = AF_INET;
    ad.sin_addr.s_addr = addr;
    ad.sin_port = htons(port);
    if(connect(s, (struct sockaddr *)&ad, sizeof ad) == -1 &&
       errno != EINPROGRESS && errno != EAGAIN) {
        SAVEERRNO(close(s));
        return -1;
    }
    return s;
}

main()
{
    struct timeval tv;
    fd_set wr, ex;
    int i, s, max, n, addr;

    addr = inet_addr("1.2.3.4");		/* set address here */

    FD_ZERO(&wr);
    FD_ZERO(&ex);
    max = 0;
    for(i = 1; i < 51; i++) {
        s = nonblock_connect(addr, i);
        if(s == -1) {
            perror("nonblock connect");
            exit(1);
        }
        if(s > max)
            max = s;
        FD_SET(s, &wr);
        FD_SET(s, &ex);
    }

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    n = select(max + 1, 0, &wr, &ex, &tv);
    if(n == -1) {
        perror("select");
        exit(1);
    }

    printf("selected %d\n", n);
    for(i = 0; i < max; i++) {
        if(FD_ISSET(i, &wr) || FD_ISSET(i, &ex)) {
            printf("%d: ", i);
            if(FD_ISSET(i, &wr))
                printf("writable ");
            if(FD_ISSET(i, &ex))
                printf("exception ");
            printf("\n");
        }
    }
    return 0;
}



-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request@cygnus.com" with one line of text: "help".
