On Wed, Jul 10, 2019 at 10:12 PM Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> wrote: > > Implement virCommandSetSendBuffer() that allows the caller to pass a > file descriptor and buffer to virCommand. virCommand will write the > buffer into the file descriptor. That file descriptor could be the > write end of a pipe or one of the file descriptors of a socketpair. > The other file descriptor should be passed to the launched process to > read the data from. > > Only implement the function to allocate memory for send buffers > and to free them later on. > > Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxx> that looks fine, Reviewed-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx> > --- > src/libvirt_private.syms | 1 + > src/util/vircommand.c | 62 ++++++++++++++++++++++++++++++++++++++++ > src/util/vircommand.h | 5 ++++ > 3 files changed, 68 insertions(+) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index d2045895a1..3feb862fb4 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -1734,6 +1734,7 @@ virCommandSetOutputBuffer; > virCommandSetOutputFD; > virCommandSetPidFile; > virCommandSetPreExecHook; > +virCommandSetSendBuffer; > virCommandSetSELinuxLabel; > virCommandSetUID; > virCommandSetUmask; > diff --git a/src/util/vircommand.c b/src/util/vircommand.c > index 8695c98d1b..e32377497b 100644 > --- a/src/util/vircommand.c > +++ b/src/util/vircommand.c > @@ -77,6 +77,16 @@ struct _virCommandFD { > unsigned int flags; > }; > > +typedef struct _virCommandSendBuffer virCommandSendBuffer; > +typedef virCommandSendBuffer *virCommandSendBufferPtr; > + > +struct _virCommandSendBuffer { > + int fd; > + unsigned char *buffer; > + size_t buflen; > + off_t offset; > +}; > + > struct _virCommand { > int has_error; /* ENOMEM on allocation failure, -1 for anything else. */ > > @@ -136,6 +146,9 @@ struct _virCommand { > char *appArmorProfile; > #endif > int mask; > + > + virCommandSendBufferPtr sendBuffers; > + size_t numSendBuffers; > }; > > /* See virCommandSetDryRun for description for this variable */ > @@ -1741,6 +1754,53 @@ virCommandSetWorkingDirectory(virCommandPtr cmd, const char *pwd) > } > > > +static void > +virCommandFreeSendBuffers(virCommandPtr cmd) > +{ > + size_t i; > + > + for (i = 0; i < cmd->numSendBuffers; i++) { > + VIR_FORCE_CLOSE(cmd->sendBuffers[i].fd); > + VIR_FREE(cmd->sendBuffers[i].buffer); > + } > + VIR_FREE(cmd->sendBuffers); > +} > + > + > +/** > + * virCommandSetSendBuffer > + * @cmd: the command to modify > + * > + * Pass a buffer to virCommand that will be written into the > + * given file descriptor. The buffer will be freed automatically > + * and the file descriptor closed. > + */ > +int > +virCommandSetSendBuffer(virCommandPtr cmd, > + int fd, > + unsigned char *buffer, size_t buflen) > +{ > + size_t i = cmd->numSendBuffers; > + > + if (!cmd || cmd->has_error) > + return -1; > + > + if (VIR_REALLOC_N(cmd->sendBuffers, i + 1) < 0) { > + cmd->has_error = ENOMEM; > + return -1; > + } > + > + cmd->sendBuffers[i].fd = fd; > + cmd->sendBuffers[i].buffer = buffer; > + cmd->sendBuffers[i].buflen = buflen; > + cmd->sendBuffers[i].offset = 0; > + > + cmd->numSendBuffers++; > + > + return 0; > +} > + > + > /** > * virCommandSetInputBuffer: > * @cmd: the command to modify > @@ -2880,6 +2940,8 @@ virCommandFree(virCommandPtr cmd) > VIR_FREE(cmd->appArmorProfile); > #endif > > + virCommandFreeSendBuffers(cmd); > + > VIR_FREE(cmd); > } > > diff --git a/src/util/vircommand.h b/src/util/vircommand.h > index c9a8d3c41c..716e84af3d 100644 > --- a/src/util/vircommand.h > +++ b/src/util/vircommand.h > @@ -148,6 +148,11 @@ void virCommandAddArgList(virCommandPtr cmd, > void virCommandSetWorkingDirectory(virCommandPtr cmd, > const char *pwd) ATTRIBUTE_NONNULL(2); > > +int virCommandSetSendBuffer(virCommandPtr cmd, > + int fd, > + unsigned char *buffer, size_t buflen) > + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3); > + > void virCommandSetInputBuffer(virCommandPtr cmd, > const char *inbuf) ATTRIBUTE_NONNULL(2); > > -- > 2.20.1 > -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list