Re: [PATCHv2 3/8] Introduce new APIs for spawning processes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Dec 01, 2010 at 10:42:40PM +0100, Matthias Bolte wrote:
> 2010/11/24 Eric Blake <eblake@xxxxxxxxxx>:
> > +/*
> > + * Manage input and output to the child process.
> > + */
> > +static int
> > +virCommandProcessIO(virCommandPtr cmd)
> > +{
> > + Â Âint infd = -1, outfd = -1, errfd = -1;
> > + Â Âsize_t inlen = 0, outlen = 0, errlen = 0;
> > + Â Âsize_t inoff = 0;
> > +
> > + Â Â/* With an input buffer, feed data to child
> > + Â Â * via pipe */
> > + Â Âif (cmd->inbuf) {
> > + Â Â Â Âinlen = strlen(cmd->inbuf);
> > + Â Â Â Âinfd = cmd->inpipe;
> > + Â Â}
> > +
> > + Â Â/* With out/err buffer, the outfd/errfd
> > + Â Â * have been filled with an FD for us */
> > + Â Âif (cmd->outbuf)
> > + Â Â Â Âoutfd = cmd->outfd;
> > + Â Âif (cmd->errbuf)
> > + Â Â Â Âerrfd = cmd->errfd;
> > +
> 
> > +/*
> > + * Run the command and wait for completion.
> > + * Returns -1 on any error executing the
> > + * command. Returns 0 if the command executed,
> > + * with the exit status set
> > + */
> > +int
> > +virCommandRun(virCommandPtr cmd, int *exitstatus)
> > +{
> > + Â Âint ret = 0;
> > + Â Âchar *outbuf = NULL;
> > + Â Âchar *errbuf = NULL;
> > + Â Âint infd[2];
> > +
> > + Â Âif (!cmd || cmd->has_error == -1) {
> > + Â Â Â ÂvirCommandError(VIR_ERR_INTERNAL_ERROR, "%s",
> > + Â Â Â Â Â Â Â Â Â Â Â Â_("invalid use of command API"));
> > + Â Â Â Âreturn -1;
> > + Â Â}
> > + Â Âif (cmd->has_error == ENOMEM) {
> > + Â Â Â ÂvirReportOOMError();
> > + Â Â Â Âreturn -1;
> > + Â Â}
> > +
> > + Â Â/* If we have an input buffer, we need
> > + Â Â * a pipe to feed the data to the child */
> > + Â Âif (cmd->inbuf) {
> > + Â Â Â Âif (pipe(infd) < 0) {
> > + Â Â Â Â Â ÂvirReportSystemError(errno, "%s",
> > + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â _("unable to open pipe"));
> > + Â Â Â Â Â Âreturn -1;
> > + Â Â Â Â}
> > + Â Â Â Âcmd->infd = infd[0];
> > + Â Â Â Âcmd->inpipe = infd[1];
> > + Â Â}
> > +
> > + Â Âif (virCommandRunAsync(cmd, NULL) < 0) {
> > + Â Â Â Âif (cmd->inbuf) {
> > + Â Â Â Â Â Âint tmpfd = infd[0];
> > + Â Â Â Â Â Âif (VIR_CLOSE(infd[0]) < 0)
> > + Â Â Â Â Â Â Â ÂVIR_DEBUG("ignoring failed close on fd %d", tmpfd);
> > + Â Â Â Â Â Âtmpfd = infd[1];
> > + Â Â Â Â Â Âif (VIR_CLOSE(infd[1]) < 0)
> > + Â Â Â Â Â Â Â ÂVIR_DEBUG("ignoring failed close on fd %d", tmpfd);
> > + Â Â Â Â}
> > + Â Â Â Âreturn -1;
> > + Â Â}
> > +
> > + Â Â/* If caller hasn't requested capture of
> > + Â Â * stdout/err, then capture it ourselves
> > + Â Â * so we can log it
> > + Â Â */
> > + Â Âif (!cmd->outbuf &&
> > + Â Â Â Â!cmd->outfdptr) {
> > + Â Â Â Âcmd->outfd = -1;
> > + Â Â Â Âcmd->outfdptr = &cmd->outfd;
> > + Â Â Â Âcmd->outbuf = &outbuf;
> > + Â Â}
> > + Â Âif (!cmd->errbuf &&
> > + Â Â Â Â!cmd->errfdptr) {
> > + Â Â Â Âcmd->errfd = -1;
> > + Â Â Â Âcmd->errfdptr = &cmd->errfd;
> > + Â Â Â Âcmd->errbuf = &errbuf;
> > + Â Â}
> > +
> > + Â Âif (cmd->inbuf || cmd->outbuf || cmd->errbuf)
> > + Â Â Â Âret = virCommandProcessIO(cmd);
> 
> In virCommandProcessIO you say that cmd->{out|err}fd is a valid FD
> (created in virExecWithHook called by virCommandRunAsync) when
> cmd->{out|err}buf is not NULL. As far as I can tell from the code that
> is true when the caller had requested to capture stdout and stderr.
> But in case that caller didn't do this then you setup buffers to
> capture stdout and stderr for logging. In that case
> virCommandProcessIO will be called with cmd->{out|err}buf being
> non-NULL but cmd->{out|err}fd being invalid as you explicitly set them
> to -1 in the two if blocks before the call to virCommandProcessIO.

Those two blocks setting errfd/outfd to -1 are not executed
when outbuf/errbuf are non-NULL, so errfd/outfd are still
pointing to the pipe() FDs when virCommandProcesIO is run.

> > diff --git a/tests/commandtest.c b/tests/commandtest.c
> > new file mode 100644
> > index 0000000..46d6ae5
> > --- /dev/null
> > +++ b/tests/commandtest.c
> 
> > +
> > +#ifndef __linux__
> 
> What's Linux specific in this test? Shouldn't the command API and this
> test be working on all systems that support fork/exec?

It should have been #ifndef WIN32 actually.

Daniel

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]