Question

After many tries I couldn't get my select() work. I'm so lost! I'm gettin -1 as a result. I'm following this guide.

listen(sock, MAXQUEUE);
build_select_list(sock, connectlist, highsock, socks);

readsocks = select(FD_SETSIZE, &socks, (fd_set *) 0, (fd_set *) 0,
        NULL );

These are the functions I'm using:

void build_select_list(int sock, int connectlist[], int highsock, fd_set socks) {
int listnum;

FD_ZERO(&socks);

FD_SET(sock, &socks);

/* Loops through all the possible connections and adds
 those sockets to the fd_set */

for (listnum = 0; listnum < MAXQUEUE; listnum++) {
    if (connectlist[listnum] != 0) {
        FD_SET(connectlist[listnum], &socks);
        if (connectlist[listnum] > highsock)
            highsock = connectlist[listnum];
    }
}}

And this is how I get my listener's file descriptor:

int socketServer(char* portNumber) {

    int sockfd; // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sigaction sa;
    int yes = 1;
    int rv;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP
    if ((rv = getaddrinfo(NULL, portNumber, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }
    // loop through all the results and bind to the first we can
    for (p = servinfo; p != NULL ; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol))
                == -1) {
            perror("server: socket");
            continue;
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))
                == -1) {
            perror("setsockopt");
            exit(1);
        }
        if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
            close(sockfd);
            perror("server: bind");
            continue;
        }
        break;
    }
    if (p == NULL ) {
        fprintf(stderr, "server: failed to bind\n");
        return 2;
    }
    freeaddrinfo(servinfo); // all done with this structure
    if (listen(sockfd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }
    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, &sa, NULL ) == -1) {
        perror("sigaction");
        exit(1);
    }
    return sockfd;

}

Was it helpful?

Solution

Your build_select_list function takes a copy of the set, and modifies only that local copy. Pass it "by reference", just like you do to the select function.

And of course you have to call this function every time you before you call select, as the select function modifies the set.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top