-static int transfer_data_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- struct connection *c = (struct connection *) userdata;
- int r = 0;
- ssize_t len;
-
- assert(revents & (EPOLLIN | EPOLLOUT));
- assert(fd == c->fd);
- assert(s == c->w);
-
- log_debug("Got event revents=%d from fd=%d (conn %p).", revents, fd, c);
-
- if (revents & EPOLLIN) {
- log_debug("About to recv up to %lu bytes from fd=%d (%lu/BUFFER_SIZE).", BUFFER_SIZE - c->buffer_filled_len, fd, c->buffer_filled_len);
-
- /* Receive until the buffer's full, there's no more data,
- * or the client/server disconnects. */
- while (c->buffer_filled_len < BUFFER_SIZE) {
- len = recv(fd, c->buffer + c->buffer_filled_len, BUFFER_SIZE - c->buffer_filled_len, 0);
- log_debug("recv(%d, ...)=%ld", fd, len);
- if (len < 0) {
- if (errno != EWOULDBLOCK && errno != EAGAIN) {
- log_error("Error %d in recv from fd=%d: %m", errno, fd);
- return -errno;
- }
- else {
- /* recv() is in a blocking state. */
- break;
- }
- }
- else if (len == 0) {
- log_debug("Clean disconnection from fd=%d", fd);
- total_clients--;
- free_connection(c->c_destination);
- free_connection(c);
- return 0;
- }