On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> wrote: > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> Could you include a test? > --- > src/util/vircommand.c | 70 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 69 insertions(+), 1 deletion(-) > > diff --git a/src/util/vircommand.c b/src/util/vircommand.c > index 0e367eeeab..357a9888a1 100644 > --- a/src/util/vircommand.c > +++ b/src/util/vircommand.c > @@ -1803,6 +1803,69 @@ virCommandSetSendBuffer(virCommandPtr cmd, > } > > > +static int > +virCommandGetNumSendBuffers(virCommandPtr cmd) > +{ > + return cmd->numSendBuffers; > +} > + That getter doesn't seem very useful, or at least you don't use it consistently. looks good otherwise > + > +static int > +virCommandAddSendBuffersFillPollfd(virCommandPtr cmd, > + struct pollfd *fds, > + int startidx) > +{ > + size_t i, j; > + > + for (i = 0, j = 0; i < cmd->numSendBuffers; i++) { > + if (cmd->sendBuffers[i].fd >= 0) { > + fds[startidx + j].fd = cmd->sendBuffers[i].fd; > + fds[startidx + j].events = POLLOUT; > + fds[startidx + j].revents = 0; > + j++; > + } > + } > + > + return j; > +} > + > + > +static int > +virCommandSendBuffersHandlePoll(virCommandPtr cmd, > + struct pollfd *fds) > +{ > + size_t i; > + int done; > + > + for (i = 0; i < cmd->numSendBuffers; i++) { > + if (fds->fd == cmd->sendBuffers[i].fd) > + break; > + } > + if (i == cmd->numSendBuffers) > + return 0; > + > + done = write(fds->fd, > + cmd->sendBuffers[i].buffer + cmd->sendBuffers[i].offset, > + MIN(cmd->sendBuffers[i].buflen - cmd->sendBuffers[i].offset, > + MAX_PIPE_FEED_BYTES)); > + if (done < 0) { > + if (errno == EPIPE) { > + VIR_DEBUG("child closed PIPE early, ignoring EPIPE " > + "on fd %d", cmd->sendBuffers[i].fd); > + VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd); > + } else if (errno != EINTR && errno != EAGAIN) { > + virReportSystemError(errno, "%s", > + _("unable to write to child input")); > + return -1; > + } > + } else { > + cmd->sendBuffers[i].offset += done; > + if (cmd->sendBuffers[i].offset == cmd->sendBuffers[i].buflen) > + VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd); > + } > + return 0; > +} > + > /** > * virCommandSetInputBuffer: > * @cmd: the command to modify > @@ -2157,7 +2220,7 @@ virCommandProcessIO(virCommandPtr cmd) > goto cleanup; > ret = -1; > > - if (VIR_ALLOC_N(fds, 3) < 0) > + if (VIR_ALLOC_N(fds, 3 + virCommandGetNumSendBuffers(cmd)) < 0) > goto cleanup; > > for (;;) { > @@ -2183,6 +2246,8 @@ virCommandProcessIO(virCommandPtr cmd) > nfds++; > } > > + nfds += virCommandAddSendBuffersFillPollfd(cmd, fds, nfds); > + > if (nfds == 0) > break; > > @@ -2255,6 +2320,9 @@ virCommandProcessIO(virCommandPtr cmd) > if (inoff == inlen) > VIR_FORCE_CLOSE(cmd->inpipe); > } > + } else if (fds[i].revents & (POLLOUT | POLLHUP | POLLERR)) { > + if (virCommandSendBuffersHandlePoll(cmd, &fds[i]) < 0) > + goto cleanup; > } > } > } > -- > 2.20.1 > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list