/* * 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); }
static int zio_writer_flush_all (zio_t *zio) { int n = 0; zio_debug (zio, "zio_writer_flush_all: used=%d\n", zio_buffer_used (zio)); while (zio_buffer_used (zio) > 0) { int rc = cbuf_read_to_fd (zio->buf, zio->dstfd, -1); zio_debug (zio, "zio_writer_flush_all: rc=%d\n", rc); if (rc < 0) return (rc); n += rc; } zio_debug (zio, "zio_writer_flush_all: n=%d\n", n); if (zio_buffer_used (zio) == 0 && zio_eof_pending (zio)) zio_close (zio); return (n); }
static int zio_close (zio_t *zio) { if (zio->flags & ZIO_CLOSED) { /* Already closed */ errno = EINVAL; return (-1); } zio_debug (zio, "zio_close\n"); if (zio_reader (zio)) { close (zio->srcfd); zio->srcfd = -1; } else if (zio_writer (zio)) { close (zio->dstfd); zio->dstfd = -1; /* For writer zio object, consider close(dstfd) * as "EOF sent" */ zio->flags |= ZIO_EOF_SENT; } zio->flags |= ZIO_CLOSED; if (zio->close) return (*zio->close) (zio, zio->arg); return (0); }
int zio_read (zio_t *zio) { int n; assert ((zio != NULL) && (zio->magic == ZIO_MAGIC)); if ((n = cbuf_write_from_fd (zio->buf, zio->srcfd, -1, NULL)) < 0) return (-1); zio_debug (zio, "zio_read: read = %d\n", n); if (n == 0) { zio_set_eof (zio); zio_debug (zio, "zio_read_cb: Got eof\n"); } zio_flush (zio); return (n); }
static char *zio_json_str_create (zio_t *zio, void *data, size_t len) { bool eof = false; if (zio_eof_pending (zio)) { eof = true; zio_debug (zio, "Setting EOF sent\n"); zio->flags |= ZIO_EOF_SENT; } return zio_json_encode (data, len, eof); }
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); }
int zio_close_dst_fd (zio_t *zio) { if (zio->dstfd >= 0) { if (close (zio->dstfd) < 0) { zio_debug (zio, "close srcfd: %s", strerror (errno)); return -1; } zio->dstfd = -1; } return 0; }
static int zio_flux_read_cb (flux_t f, int fd, short revents, zio_t *zio) { int rc; zio_handler_start (zio); rc = zio_read_cb_common (zio); if (rc >= 0 && zio_eof_sent (zio)) { zio_debug (zio, "reader detaching from flux reactor\n"); flux_fdhandler_remove (f, fd, ZMQ_POLLIN|ZMQ_POLLERR); rc = zio_close (zio); } zio_handler_end (zio); return (rc); }
static int zio_zloop_read_cb (zloop_t *zl, zmq_pollitem_t *zp, zio_t *zio) { int rc; zio_handler_start (zio); rc = zio_read_cb_common (zio); if (rc >= 0 && zio_eof_sent (zio)) { zio_debug (zio, "reader detaching from zloop\n"); zloop_poller_end (zl, zp); rc = zio_close (zio); } zio_handler_end (zio); return (rc); }
/* * Callback when zio->dstfd is writeable. Write buffered data to * file descriptor. */ static int zio_writer_cb (zio_t *zio) { int rc = 0; if (cbuf_used (zio->buf)) rc = cbuf_read_to_fd (zio->buf, zio->dstfd, -1); if (rc < 0) { if (errno == EAGAIN) return (0); zio_debug (zio, "cbuf_read_to_fd: %s\n", strerror (errno)); return (-1); } if ((rc == 0) && zio_eof_pending (zio)) rc = zio_close (zio); return (rc); }
static void zio_flux_read_cb (flux_reactor_t *r, flux_watcher_t *w, int revents, void *arg) { zio_t *zio = arg; int rc; zio_handler_start (zio); rc = zio_read_cb_common (zio); if (rc >= 0 && zio_eof_sent (zio)) { zio_debug (zio, "reader detaching from flux reactor\n"); flux_watcher_stop (w); rc = zio_close (zio); } zio_handler_end (zio); if (rc < 0) flux_reactor_stop_error (r); }
static int zio_send (zio_t *zio, char *p, size_t len) { int rc = -1; char *json_str = NULL; zio_debug (zio, "zio_send (len=%d)\n", len); if (!(zio->flags & ZIO_RAW_OUTPUT)) { if (!(json_str = zio_json_str_create (zio, p, len))) goto done; p = json_str; } rc = zio_sendmsg (zio, p, len); if (rc >= 0 && len == 0) zio->flags |= ZIO_EOF_SENT; done: if (json_str) free (json_str); return rc; }
static int zio_sendmsg (zio_t *zio, const char *s, int len) { zio_debug (zio, "sendmsg: %s\n", s); return (*zio->send) (zio, s, len, zio->arg); }