Example #1
0
ssize_t
buffer_recv(struct Buffer *buffer, int sockfd, int flags) {
    ssize_t bytes;
    struct iovec iov[2];
    struct msghdr msg;

    /* coalesce when reading into an empty buffer */
    if (buffer->len == 0)
        buffer->head = 0;

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = iov;
    msg.msg_iovlen = setup_write_iov(buffer, iov, 0);
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;

    bytes = recvmsg(sockfd, &msg, flags);

    buffer->last_recv = ev_now(EV_DEFAULT);

    if (bytes > 0)
        advance_write_position(buffer, bytes);

    return bytes;
}
Example #2
0
/*
 * Read data from file into buffer
 */
ssize_t
buffer_read(struct Buffer *buffer, int fd) {
    ssize_t bytes;
    struct iovec iov[2];

    /* coalesce when reading into an empty buffer */
    if (buffer->len == 0)
        buffer->head = 0;

    bytes = readv(fd, iov, setup_write_iov(buffer, iov, 0));

    if (bytes > 0)
        advance_write_position(buffer, bytes);

    return bytes;
}
Example #3
0
size_t
buffer_push(struct Buffer *dst, const void *src, size_t len) {
    struct iovec iov[2];
    size_t bytes_appended = 0;

    /* coalesce when reading into an empty buffer */
    if (dst->len == 0)
        dst->head = 0;

    if (dst->size - dst->len < len)
        return -1; /* insufficient room */

    size_t iov_len = setup_write_iov(dst, iov, len);

    for (size_t i = 0; i < iov_len; i++) {
        memcpy(iov[i].iov_base, (char *)src + bytes_appended, iov[i].iov_len);
        bytes_appended += iov[i].iov_len;
    }

    if (bytes_appended > 0)
        advance_write_position(dst, bytes_appended);

    return bytes_appended;
}
Example #4
0
struct Buffer *
new_buffer(int size) {
    struct Buffer *buf;

    buf = malloc(sizeof(struct Buffer));
    if (buf == NULL)
        return NULL;

    buf->size = size;
    buf->len = 0;
    buf->head = 0;
    buf->tx_bytes = 0;
    buf->rx_bytes = 0;
    buf->last_recv = (struct timespec){.tv_sec = 0, .tv_nsec = 0};
    buf->last_send = (struct timespec){.tv_sec = 0, .tv_nsec = 0};
    buf->buffer = malloc(buf->size);
    if (buf->buffer == NULL) {
        free(buf);
        buf = NULL;
    }

    return buf;
}

ssize_t
buffer_resize(struct Buffer *buf, size_t new_size) {
    char *new_buffer;

    if (new_size < buf->len)
        return -1; /* new_size too small to hold existing data */

    new_buffer = malloc(new_size);
    if (new_buffer == NULL)
        return -2;

    if (buffer_peek(buf, new_buffer, new_size) != buf->len) {
        err("failed to copy existing buffer contents into new buffer");
        free(new_buffer);
        return -3;
    }

    free(buf->buffer);
    buf->buffer = new_buffer;
    buf->head = 0;

    return buf->len;
}

void
free_buffer(struct Buffer *buf) {
    if (buf == NULL)
        return;

    free(buf->buffer);
    free(buf);
}

ssize_t
buffer_recv(struct Buffer *buffer, int sockfd, int flags) {
    ssize_t bytes;
    struct iovec iov[2];
    struct msghdr msg;

    /* coalesce when reading into an empty buffer */
    if (buffer->len == 0)
        buffer->head = 0;

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = iov;
    msg.msg_iovlen = setup_write_iov(buffer, iov, 0);
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    msg.msg_flags = 0;

    bytes = recvmsg(sockfd, &msg, flags);

    if (clock_gettime(CLOCK_MONOTONIC, &buffer->last_recv) < 0)
        err("clock_gettime() failed: %s", strerror(errno));

    if (bytes > 0)
        advance_write_position(buffer, bytes);

    return bytes;
}