delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/1998/03/14/07:40:45

From: newsham AT lava DOT 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
To: gnu-win32 AT cygnus DOT 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 AT cygnus DOT com" with one line of text: "help".

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019