static void pull_and_push(XferElementGlue *self) { XferElement *elt = XFER_ELEMENT(self); gboolean eof_sent = FALSE; while (!elt->cancelled) { char *buf; size_t len; /* get a buffer from upstream */ buf = xfer_element_pull_buffer(elt->upstream, &len); /* and push it downstream */ xfer_element_push_buffer(elt->downstream, buf, len); if (!buf) { eof_sent = TRUE; break; } } if (elt->cancelled && elt->expect_eof) xfer_element_drain_buffers(elt->upstream); if (!eof_sent) xfer_element_push_buffer(elt->downstream, NULL, 0); }
static gpointer pull_buffer_impl( XferElement *elt, size_t *size) { XferFilterCrc *self = (XferFilterCrc *)elt; char *buf; XMsg *msg; if (elt->cancelled) { /* drain our upstream only if we're expecting an EOF */ if (elt->expect_eof) { xfer_element_drain_buffers(XFER_ELEMENT(self)->upstream); } /* return an EOF */ *size = 0; return NULL; } /* get a buffer from upstream, crc it, and hand it back */ buf = xfer_element_pull_buffer(XFER_ELEMENT(self)->upstream, size); if (buf) { crc32_add((uint8_t *)buf, *size, &elt->crc); } else { g_debug("sending XMSG_CRC message"); g_debug("crc pull_buffer CRC: %08x", crc32_finish(&elt->crc)); msg = xmsg_new(elt, XMSG_CRC, 0); msg->crc = crc32_finish(&elt->crc); msg->size = elt->crc.size; xfer_queue_message(elt->xfer, msg); } return buf; }
static void pull_and_write(XferElementGlue *self) { XferElement *elt = XFER_ELEMENT(self); int fd = get_write_fd(self); XMsg *msg; size_t written; self->write_fdp = NULL; while (!elt->cancelled) { size_t len; char *buf; /* get a buffer from upstream */ buf = xfer_element_pull_buffer(elt->upstream, &len); if (!buf) break; /* write it */ if (!elt->downstream->drain_mode) { written = full_write(fd, buf, len); if (written < len) { if (elt->downstream->must_drain) { g_debug("Error writing to fd %d: %s", fd, strerror(errno)); } else if (elt->downstream->ignore_broken_pipe && errno == EPIPE) { } else { if (!elt->cancelled) { xfer_cancel_with_error(elt, _("Error writing to fd %d: %s"), fd, strerror(errno)); xfer_cancel(elt->xfer); wait_until_xfer_cancelled(elt->xfer); } amfree(buf); break; } elt->downstream->drain_mode = TRUE; } } crc32_add((uint8_t *)buf, len, &elt->crc); amfree(buf); } if (elt->cancelled && elt->expect_eof) xfer_element_drain_buffers(elt->upstream); g_debug("sending XMSG_CRC message %p", elt->downstream); g_debug("pull_and_write CRC: %08x size %lld", crc32_finish(&elt->crc), (long long)elt->crc.size); msg = xmsg_new(elt->downstream, XMSG_CRC, 0); msg->crc = crc32_finish(&elt->crc); msg->size = elt->crc.size; xfer_queue_message(elt->xfer, msg); /* close the fd we've been writing, as an EOF signal to downstream, and * set it to -1 to avoid accidental re-use */ close_write_fd(self); }