Пример #1
0
/*
 *   Flush any buffered output and EOF from zio READER object
 *    to destination.
 */
int zio_flush (zio_t *zio)
{
    int len;
    int rc = 0;

    if ((zio == NULL) || (zio->magic != ZIO_MAGIC))
        return (-1);
    if (zio_reader (zio) && !zio->send)
       return (-1);

    zio_debug (zio, "zio_flush\n");

    /*
     *  Nothing to flush if EOF already sent to consumer:
     */
    if (zio_eof_sent (zio))
        return (0);

    if (zio_writer (zio))
        return zio_writer_flush_all (zio);

    /* else zio reader:
    */

    while (((len = zio_data_to_flush (zio)) > 0) || zio_eof (zio)) {
        char * buf = NULL;
        int n = 0;
        zio_debug (zio, "zio_flush: len = %d, eof = %d\n", len, zio_eof (zio));
        if (len > 0) {
            buf = xzmalloc (len + 1);
            if ((n = zio_fd_read (zio, buf, len + 1)) <= 0) {
                if (n < 0) {
                    zio_debug (zio, "zio_read: %s", strerror (errno));
                    rc = -1;
                }
                /*
                 *  We may not be able to read any data from the buffer
                 *   because we are line buffering and there is not yet
                 *   a full line in the buffer. In this case just exit
                 *   so we can buffer more data.
                 */
                free (buf);
                return (rc);

            }
        }
        zio_debug (zio, "zio_data_to_flush = %d\n", zio_data_to_flush (zio));
        zio_debug (zio, "zio_flush: Sending %d (%s) [eof=%d]\n", n, buf, zio_eof(zio));
        rc = zio_send (zio, buf, n);
        if (buf)
            free (buf);
        if (zio_eof_sent (zio))
            break;
    }
    return (rc);
}
Пример #2
0
/*
 *  write data into zio buffer
 */
static int zio_write_data (zio_t *zio, void *buf, size_t len)
{
    int n = 0;
    int ndropped = 0;

    /*
     *  If buffer is empty, first try writing directly to dstfd
     *   to avoid double-copy:
     */
    if (zio_buffer_empty (zio)) {
        n = write (zio->dstfd, buf, len);
        if (n < 0) {
            if (errno == EAGAIN)
                n = 0;
            else
                return (-1);
        }
        /*
         *  If we wrote everything, return early
         */
        if (n == len) {
            if (zio_eof (zio))
                zio_close (zio);
            return (len);
        }
    }

    /*
     *  Otherwise, buffer any remaining data
     */
    if ((len - n) && cbuf_write (zio->buf, buf+n, len-n, &ndropped) < 0)
        return (-1);

    return (0);
}
Пример #3
0
static int zio_write_pending (zio_t *zio)
{
    if (zio_closed (zio))
        return (0);

    if ((zio_buffer_used (zio) > 0) || zio_eof (zio))
        return (1);

    return (0);
}
Пример #4
0
static int zio_fd_read (zio_t *zio, void *dst, int len)
{
    assert (zio != NULL);
    assert (zio->magic == ZIO_MAGIC);
    assert (zio->buf);

    if (zio_line_buffered (zio) && !zio_eof (zio))
        return cbuf_read_line (zio->buf, dst, len, -1);
    else
        return cbuf_read (zio->buf, dst, len);
}
Пример #5
0
static int zio_eof_pending (zio_t *zio)
{
    /* Already closed? Then EOF can't be pending */
    if (zio_closed (zio))
      return (0);
    /*
     *   zio object has EOF pending if EOF flag is set and either the
     *    io is unbuffered or the buffer for IO is empty.
     */
    return (zio_eof (zio) && (!cbuf_used (zio->buf)));
}
Пример #6
0
static int zio_write_internal (zio_t *zio, void *data, size_t len)
{
    int rc;

    rc = zio_write_data (zio, data, len);
    zio_debug (zio, "zio_write: %d bytes, eof=%d\n", len, zio_eof (zio));

    if (zio_write_pending (zio))
        zio_writer_schedule (zio);
    return (rc);
}
Пример #7
0
static int zio_data_to_flush (zio_t *zio)
{
    int size;

    if ((size = zio_buffer_used (zio)) <= 0)
        return (0);

    /*
     *   For unbuffered IO we will flush all data. For line buffered
     *    IO we will read all available lines. In both cases, return
     *    the amount of data currently waiting in the buffer.
     */
    if (!zio_buffered (zio) || zio_line_buffered (zio))
        return (size);

    /*  For normal buffered IO, we will only flush data when availble
     *   bytes are greater than the current buffer size, unless there
     *   is a pending EOF
     */
    if (zio_eof (zio) || (size <= zio->buffersize))
        return (size);

    return (0);
}