Пример #1
0
I compare_arith(V l, V r) {
#define D_L(type, op) case type##_t: c=op(get##type(l), get##type(r)); break
#define CMP_(l,r) (((l)>(r))-((l)<(r)))
  I c; switch (max(T(l),T(r))) { D_L(Z,CMP_); D_L(R,CMP_); }
  del(l); del(r); return c;
#undef CMP_
#undef D_L
}
Пример #2
0
static void signal_handler(int sig)
{
    switch (sig) {
        case SIGTERM:
            closing = 1;
            break;
        case SIGINT:
            closing  = 1;
            break;
        case SIGQUIT:
            closing = 1;
            break;
        case SIGURG:  //out of band data handler
            printf("IGURG received\n");
            break;
        default:
            D_L("ERROR: never come here!");
            break;
    }
}
Пример #3
0
int main(int argc, char *argv[])
{
    int echo_port = PORT;
    if(argc > 1) {
        LOG("IN %d OUT %d RDHUP %d HUP %d ERR %d", EPOLLIN, EPOLLOUT, EPOLLRDHUP, EPOLLHUP, EPOLLERR);
        char *endptr = NULL;
        echo_port = strtol(argv[1], &endptr, 10);
        if (echo_port <= 0 || echo_port >= LONG_MAX) {
            LOG("LONG_MIN %ld LONG_MAX %ld, echo port %d", LONG_MIN, LONG_MAX, echo_port);
            exit(-1);
        }
    }
    LOG("listen to localhost:%d\n", echo_port);

    // 处理信号
    register_sig(SIGTERM, signal_handler);
    register_sig(SIGINT, signal_handler);
    register_sig(SIGQUIT, signal_handler);
    register_sig(SIGPIPE, SIG_IGN);
    /* 设置SIGURG 的处理函数 sig_urg */
    //if(fcntl(ss_fd, F_SETOWN, getpid()) < 0) {
        //perror("can not set OOB own");
    //}
    //register_sig(SIGURG, signal_handler);

    int ss_fd = -1;
    struct sockaddr_in server_addr = {0};
    struct sockaddr_in client_addr = {0};
    socklen_t addr_in_len = sizeof(struct sockaddr_in);
    int yes = 1;
    ss_fd = socket( AF_INET, SOCK_STREAM, 0);
    if(ss_fd == -1){
        perror("create server socket error");
        return EXIT_FAILURE;
    }

    if (setsockopt(ss_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        return EXIT_FAILURE;
    }

    memset(&server_addr, 0, sizeof(struct sockaddr_in));
    memset(&client_addr, 0, sizeof(struct sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(echo_port);
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);

    if (bind(ss_fd, (struct sockaddr *)&server_addr, addr_in_len) == -1) {
        perror("bind server socket error");
        return EXIT_FAILURE;
    } else {
        printf("bind successfully \n");
    }

    if (listen(ss_fd, BACKLOG) == -1) {
        perror("listen server socket error");
        return EXIT_FAILURE;
    } else {
        printf("listen successfully \n");
    }

    printf("listen port %d\n", echo_port);

    struct epoll_event ev = {0};
    struct epoll_event  events[MAXEVENTS] = {{0}};

    int epfd = epoll_create(MAXCLIENTS);
    //add server socket to epoll
    ev.events = EPOLLIN ; //| EPOLLET;
    ev.data.fd = ss_fd;
    if(setnonblocking(ss_fd) != 0) {
        perror("css_fd an not nonblocking");
        return EXIT_FAILURE;
    }
    epoll_ctl(epfd, EPOLL_CTL_ADD, ss_fd, &ev);
    if(epfd == -1){
        perror("epoll listen socket");
        return EXIT_FAILURE;
    }

#define     E_TIMEOUT       10
    /***********************************  main loop  **************************************/
    while(!closing) {
        int ready_fds = epoll_wait(epfd, events, MAXEVENTS, E_TIMEOUT);
        if(ready_fds == -1){
            perror("epoll_wait");
            break;
        }

        for(int n = 0; n < ready_fds; ++n) {
            if (events[n].events & EPOLLERR || events[n].events & EPOLLRDHUP || events[n].events & EPOLLHUP) {
                D_L("ERROR or HUP\n");
                if (events[n].data.fd != ss_fd) {
                    closeclient(epfd, events[n].data.fd);
                }
                continue;
            }
            if (events[n].events & EPOLLIN) {
                if(events[n].data.fd == ss_fd) { //listening socket
                    while(true) {
                        int c_fd = accept(ss_fd, (struct sockaddr *) &client_addr, &addr_in_len);
                        if(c_fd < 0){
                            if(errno == EAGAIN){
                                break;
                            } else if(errno == EINTR){
                                continue;
                            } else {
                                D_L("accept error %s", strerror(errno));
                                close(ss_fd);
                                break;
                            }
                        } 
                        setnonblocking(c_fd);
                        setkeepalive(c_fd);

                        ev.events = EPOLLET | EPOLLIN | EPOLLOUT | EPOLLRDHUP;
                        ev.data.fd = c_fd;

                        //add to epoll events queue
                        if (STAT.conn_amount < MAXCLIENTS) {
                            D_L("total [%d] client, new fd %d Addr: %s:%d", STAT.conn_amount, c_fd,\
                                    inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

                            if (epoll_ctl(epfd, EPOLL_CTL_ADD, c_fd, &ev) < 0) {
                                fprintf(stderr, "epoll set insertion error: fd=%d", c_fd);
                                break;
                            }

                            conn_add(c_fd);
                        } else {
                            const char *refuse_str = "max connections, refuse and close, bye";
                            D_L("%s\n", refuse_str);
                            send(c_fd, refuse_str, strlen(refuse_str), 0);
                            close(c_fd);
                        }
                    }
                } else { //common client
                    int fd = events[n].data.fd;
                    conn_list_iter it = conn_list.find(fd);
                    if (it != conn_list.end()) {
                        int left_sz = MAX_BUFSZ - it->second.rsize;
                        int rsz = recv(fd, it->second.rbuf + it->second.rsize, left_sz, 0);
                        if (rsz <= 0) {
                            D_L("get from fd %d err: %s, close it", fd, strerror(errno));
                            closeclient(epfd, fd);
                            continue;
                        } else if (rsz < left_sz) {
                            //D_L("get from fd %d len: %d", fd, rsz);
                            it->second.rsize += rsz;
                        } else {
                            D_L("recv buf size is to small for bufsz %d fd %d len %d", MAX_BUFSZ, fd, rsz);
                            closeclient(epfd, fd);
                            continue;
                        }
                    } else {
                        D_L("get unknown fd %d EPOLLIN", fd);
                    }
                }
            }
            if (events[n].events & EPOLLOUT) {
                int fd = events[n].data.fd;
                conn_list_iter it = conn_list.find(fd);
                if (it != conn_list.end()) {
                    if (it->second.wsize == 0 && it->second.rsize == 0) {
                        continue;
                    }
                    int nop_sz = it->second.rsize;
                    int left_sz = MAX_BUFSZ - it->second.wsize;
                    if (nop_sz > left_sz) { //buffer too small, send first
                        int wsz = send(fd, it->second.wbuf, it->second.wsize, 0);
                        if (wsz < 0) {
                            D_L("send to fd %d err: %s", fd, strerror(errno));
                            if (errno == EINTR || errno == EAGAIN) {
                                continue;
                            } 
                            closeclient(epfd, fd);
                            continue;
                        }
                        if (wsz != it->second.wsize) {
                            memmove(it->second.wbuf, it->second.wbuf + wsz, it->second.wsize - wsz);
                        }
                        it->second.wsize -= wsz;
                    }
                    left_sz = MAX_BUFSZ - it->second.wsize;
                    if (nop_sz > left_sz) {
                        D_L("send buf size to small for fd %d nop_size %d left_size %d", fd, nop_sz, left_sz);
                        closeclient(epfd, fd);
                        continue;
                    }
                    memcpy(it->second.wbuf + it->second.wsize, it->second.rbuf, nop_sz);
                    it->second.wsize += nop_sz;
                    it->second.rsize -= nop_sz;
                    char *buf = it->second.wbuf;
                    int wsz = send(fd, buf, it->second.wsize, 0);
                    if (wsz < 0) {
                        if (errno == EINTR || errno == EAGAIN) {
                            continue;
                        } 
                        D_L("send to fd %d err: %s, close it", fd, strerror(errno));
                        closeclient(epfd, fd);
                        continue;
                    }
                    it->second.wsize -= wsz;
                } else {
                    D_L("get unknown fd %d EPOLLOUT", fd);
                    closeclient(epfd, fd);
                }
            } 
            //D_L("unkown events get fd %d:%x", events[n].data.fd, events[n].events);
        }
    }
    close(epfd);
    return 0;
}