Example #1
0
File: init.c Project: DashYang/sim
VALUE
rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
{
    int fd2;

    rb_secure(3);
    rb_io_set_nonblock(fptr);
    fd2 = cloexec_accept(fptr->fd, (struct sockaddr*)sockaddr, len);
    if (fd2 < 0) {
	switch (errno) {
	  case EAGAIN:
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
	  case EWOULDBLOCK:
#endif
	  case ECONNABORTED:
#if defined EPROTO
	  case EPROTO:
#endif
            rb_readwrite_sys_fail(RB_IO_WAIT_READABLE, "accept(2) would block");
	}
        rb_sys_fail("accept(2)");
    }
    rb_update_max_fd(fd2);
    make_fd_nonblock(fd2);
    return rsock_init_sock(rb_obj_alloc(klass), fd2);
}
Example #2
0
int main(int argc, char *argv[])
{
	int listenfd;
	struct sockaddr_in sin;

	if (argc < 2) {
		fprintf(stderr, "usage: %s <port>\n", argv[0]);	
		exit(1);
	}

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1)
		handle_error("socket");

	make_fd_nonblock(listenfd);

	int one = 1;
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));

	sin.sin_family = AF_INET;
	sin.sin_port = htons(atoi(argv[1]));
	sin.sin_addr.s_addr = 0;
	if (bind(listenfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
		handle_error("bind");

	if (listen(listenfd, 16) == -1)
		handle_error("listen");

	int i, r, maxfd;
	fd_set fds;
	fd_set readset;

	FD_ZERO(&fds);

	for ( ;; ) {
		FD_ZERO(&readset);
		maxfd = listenfd;
		FD_SET(listenfd, &readset);

		for (i = 0; i < FD_SETSIZE; i++) {
			if (!FD_ISSET(i, &fds))
				continue;
			FD_SET(i, &readset);
			if (maxfd < i)
				maxfd = i;
		}

		int result = select(maxfd+1, &readset, NULL, NULL, NULL);
		if (result == -1)
			continue;

		if (FD_ISSET(listenfd, &readset)) {
			struct sockaddr_storage ss;
			socklen_t slen = sizeof(ss);
			int connfd = accept(listenfd, (struct sockaddr *)&ss, &slen);
			if (connfd != -1) {
				make_fd_nonblock(connfd);
				if (connfd > FD_SETSIZE) close(connfd);
				FD_SET(connfd, &fds);
			}
			FD_CLR(listenfd, &readset);
		}

		for (i = 0; i <= maxfd; i++) {
			r = -1;
			if (FD_ISSET(i, &readset)) {
				r = do_read(i);
			}
			if (r == 0)
				FD_CLR(i, &fds);
		}
	}
}
Example #3
0
int main(int argc, char *argv[])
{
    struct epoll_event ev;
    struct epoll_event *evs;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: epoll port\n");
        exit(1);
    }

    int socketfd = create_socket_and_bind_port(argv[1]);
    if (socketfd == -1)
    {
        exit(EXIT_FAILURE);
    }

    if (make_fd_nonblock(socketfd) == -1)
    {
        exit(EXIT_FAILURE);
    }

    if (listen_socket(socketfd, MAXLISTEN) == -1)
    {
        exit(EXIT_FAILURE);
    }

    int epollfd;
    if ((epollfd = epoll_create1(0)) == -1)
    {
        perror("epoll_create1");
        exit(EXIT_FAILURE);
    }

    ev.events    = EPOLLIN | EPOLLET;
    ev.data.fd   = socketfd;
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, socketfd, &ev) == -1)
    {
        perror("epoll_ctl"); 
        exit(EXIT_FAILURE);
    }

    evs= calloc(sizeof (struct epoll_event), MAXEVENTS);
    if (!evs)
    {
        perror("calloc");
        exit(EXIT_FAILURE);
    }
    
    for ( ; ;)
    {
        int nret; 
        nret = epoll_wait(epollfd, evs, MAXEVENTS, -1);
        int i;
        for (i = 0; i < nret; ++i)
        {
            ev = evs[i];
            if ((ev.events & EPOLLERR) || 
                 (ev.events & EPOLLHUP) || 
                (!(ev.events & EPOLLIN)))
            {
                fprintf(stderr, "epoll error: %u\n", ev.events); 
                epoll_ctl(epollfd, EPOLL_CTL_DEL, ev.data.fd, NULL);
                close(ev.data.fd); 
                continue;
            }

            if (ev.data.fd == socketfd)
            {  
                for (; ;)
                {
                    int newfd;
                    struct sockaddr sa;
                    socklen_t sa_len = sizeof(struct sockaddr);
                    newfd = accept(socketfd, &sa, &sa_len);
                    if (newfd == -1)
                    {
                        if ( errno == EAGAIN || errno == EWOULDBLOCK)
                        {
                            break;
                        }
                        perror("accept");
                        break;
                    }

                    char ip[INET6_ADDRSTRLEN];
                    void *addr = get_in_addr(&sa);
                    inet_ntop(sa.sa_family, addr, ip, sizeof(ip));
                    printf("Accept connection %s on descriptor %d\n", ip, newfd);
                    
                    if (make_fd_nonblock(newfd) == -1)
                    {
                        exit(EXIT_FAILURE);
                    }

                    struct epoll_event newev;
                    newev.data.fd = newfd;
                    newev.events = EPOLLIN | EPOLLET;
                    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, newfd, &newev) == -1)
                    {
                        perror("epoll_ctl");
                        exit(EXIT_FAILURE);
                    }
                } // END FOR
            } // END IF
            else
            {
                int done = 0;
                for ( ; ;)
                {
                    ssize_t count;
                    char buf[BUFSIZ];

                    count = read(ev.data.fd, buf, BUFSIZ);
                    if (count == -1)
                    {
                        if (errno != EAGAIN)
                        {
                            perror("read");
                            done = 1;        
                        }
                        break;
                    } 
                    else if (count == 0)
                    {
                        done = 1;
                        break;
                    }

                    int nw = write(STDOUT_FILENO, buf, count); // write buf to standard output
                    if (nw == -1)
                    {
                        perror("write");
                        exit(EXIT_FAILURE);
                    }
                } // END FOR

                if (done == 1)
                {
                    printf("Closed connection on descriptor %d\n", ev.data.fd);
                    del_and_close_fd_from_epoll(epollfd, ev.data.fd);
                    continue;
                }
            } // END ELSE
        }
    }
}