INTERPOSE (close, int, int fd) { CHECK_INTERPOSE (close); unregister_fd (fd); return orig_close (fd); }
int win32_close(void *x, int fd) { unregister_fd(x, fd); if (fd >= 0) { return _close(fd); } else { return 0; } }
ssize_t tcp_recv(struct tcp_sock *m, void *data, int size) { ssize_t ret = 0; socklen_t sin_size = sizeof(struct sockaddr_in); /* we are not connected, skip. */ if (m->state != TCP_SERVER_CONNECTED) return 0; ret = recvfrom(m->client_fd, data, size, 0, (struct sockaddr *)&m->addr, &sin_size); if (ret == -1) { /* the other peer has disconnected... */ if (errno == ENOTCONN) { unregister_fd(m->client_fd, STATE(fds)); close(m->client_fd); m->client_fd = -1; m->state = TCP_SERVER_ACCEPTING; tcp_accept(m); } else if (errno != EAGAIN) { m->stats.error++; } } else if (ret == 0) { /* the other peer has closed the connection... */ unregister_fd(m->client_fd, STATE(fds)); close(m->client_fd); m->client_fd = -1; m->state = TCP_SERVER_ACCEPTING; tcp_accept(m); } if (ret >= 0) { m->stats.bytes += ret; m->stats.messages++; } return ret; }
int tcp_accept(struct tcp_sock *m) { int ret; /* we got an attempt to connect but we already have a client? */ if (m->state != TCP_SERVER_ACCEPTING) { /* clear the session and restart ... */ unregister_fd(m->client_fd, STATE(fds)); close(m->client_fd); m->client_fd = -1; m->state = TCP_SERVER_ACCEPTING; } /* the other peer wants to connect ... */ ret = accept(m->fd, NULL, NULL); if (ret == -1) { if (errno != EAGAIN) { /* unexpected error. Give us another try. */ m->state = TCP_SERVER_ACCEPTING; } else { /* waiting for new connections. */ m->state = TCP_SERVER_ACCEPTING; } } else { /* the peer finally got connected. */ if (fcntl(ret, F_SETFL, O_NONBLOCK) == -1) { /* close the connection and give us another chance. */ close(ret); return -1; } m->client_fd = ret; m->state = TCP_SERVER_CONNECTED; register_fd(m->client_fd, STATE(fds)); } return m->client_fd; }