ssize_t pipe_send()

in src/channel/cc_pipe.c [271:315]


ssize_t pipe_send(struct pipe_conn *c, void *buf, size_t nbyte)
{
    ssize_t n;

    ASSERT(c != NULL);
    ASSERT(buf != NULL);
    ASSERT(nbyte > 0);

    log_verb("send on pipe fd %d, total %zu bytes", c->fd[1], nbyte);

    for (;;) {
        n = write(c->fd[1], buf, nbyte);
        INCR(pipe_metrics, pipe_send);

        if (n > 0) {
            log_verb("%zu bytes sent on pipe fd %d", n, c->fd[1]);
            c->send_nbyte += (size_t)n;
            INCR_N(pipe_metrics, pipe_send_byte, n);
            return n;
        }

        if (n == 0) {
            log_warn("sendv on pipe fd %d returned zero", c->fd[1]);
            return 0;
        }

        /* n < 0 */
        INCR(pipe_metrics, pipe_send_ex);
        if (errno == EINTR) {
            log_debug("send on pipe fd %d not ready - EINTR", c->fd[1]);
            continue;
        } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
            log_debug("send on pipe fd %d not ready - EAGAIN", c->fd[1]);
            return CC_EAGAIN;
        } else {
            c->err = errno;
            log_error("sendv on pipe fd %d failed: %s", c->fd[1], strerror(errno));
            return CC_ERROR;
        }
    }

    NOT_REACHED();

    return CC_ERROR;
}