File: command.html

package info (click to toggle)
libvirt 1.2.9-9%2Bdeb8u5
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 174,832 kB
  • sloc: ansic: 463,173; xml: 68,283; sh: 16,393; makefile: 4,580; python: 3,705; perl: 3,675; ml: 470; sed: 16
file content (739 lines) | stat: -rw-r--r-- 30,730 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
        This file is autogenerated from internals/command.html.in
        Do not edit this file. Changes will be lost.
      -->
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" href="../main.css" />
    <link rel="SHORTCUT ICON" href="../32favicon.png" />
    <title>libvirt: Spawning processes / commands from libvirt drivers</title>
    <meta name="description" content="libvirt, virtualization, virtualization API" />
  </head>
  <body>
    <div id="header">
      <div id="headerLogo"></div>
      <div id="headerSearch">
        <form action="../search.php" enctype="application/x-www-form-urlencoded" method="get"><div>
            <input id="query" name="query" type="text" size="12" value="" />
            <input id="submit" name="submit" type="submit" value="Search" />
          </div></form>
      </div>
    </div>
    <div id="body">
      <div id="menu">
        <ul class="l0"><li>
            <div>
              <a title="Front page of the libvirt website" class="inactive" href="../index.html">Home</a>
            </div>
          </li><li>
            <div>
              <a title="Details of new features and bugs fixed in each release" class="inactive" href="../news.html">News</a>
            </div>
          </li><li>
            <div>
              <a title="Applications known to use libvirt" class="inactive" href="../apps.html">Applications</a>
            </div>
          </li><li>
            <div>
              <a title="Get the latest source releases, binary builds and get access to the source repository" class="inactive" href="../downloads.html">Downloads</a>
            </div>
          </li><li>
            <div>
              <a title="Information for users, administrators and developers" class="active" href="../docs.html">Documentation</a>
              <ul class="l1"><li>
                  <div>
                    <a title="How to compile libvirt" class="inactive" href="../compiling.html">Compiling</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Information about deploying and using libvirt" class="inactive" href="../deployment.html">Deployment</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Overview of the logical subsystems in the libvirt API" class="inactive" href="../intro.html">Architecture</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Description of the XML formats used in libvirt" class="inactive" href="../format.html">XML format</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Hypervisor specific driver information" class="inactive" href="../drivers.html">Drivers</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Reference manual for the C public API" class="inactive" href="../html/index.html">API reference</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Bindings of the libvirt API for other languages" class="inactive" href="../bindings.html">Language bindings</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Working on the internals of libvirt API, driver and daemon code" class="active" href="../internals.html">Internals</a>
                    <ul class="l2"><li>
                        <div>
                          <a title="General hacking guidelines for contributors" class="inactive" href="../hacking.html">Contributor guidelines</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="Adding new public libvirt APIs" class="inactive" href="../api_extension.html">API extensions</a>
                        </div>
                      </li><li>
                        <div>
                          <span class="active">Spawning commands</span>
                        </div>
                      </li><li>
                        <div>
                          <a title="RPC protocol information and API / dispatch guide" class="inactive" href="../internals/rpc.html">RPC protocol &amp; APIs</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="Use lock managers to protect disk content" class="inactive" href="../internals/locking.html">Lock managers</a>
                        </div>
                      </li><li>
                        <div>
                          <a title="Simulating OOM conditions in the test suite" class="inactive" href="../internals/oomtesting.html">Out of memory testing</a>
                        </div>
                      </li></ul>
                  </div>
                </li><li>
                  <div>
                    <a title="A guide and reference for developing with libvirt" class="inactive" href="../devguide.html">Development Guide</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Command reference for virsh" class="inactive" href="../virshcmdref.html">Virsh Commands</a>
                  </div>
                </li><li>
                  <div>
                    <a title="Project governance and code of conduct" class="inactive" href="../governance.html">Governance</a>
                  </div>
                </li></ul>
            </div>
          </li><li>
            <div>
              <a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a>
            </div>
          </li><li>
            <div>
              <a title="Frequently asked questions" class="inactive" href="http://wiki.libvirt.org/page/FAQ">FAQ</a>
            </div>
          </li><li>
            <div>
              <a title="How and where to report bugs and request features" class="inactive" href="../bugs.html">Bug reports</a>
            </div>
          </li><li>
            <div>
              <a title="How to contact the developers via email and IRC" class="inactive" href="../contact.html">Contact</a>
            </div>
          </li><li>
            <div>
              <a title="Available test suites for libvirt" class="inactive" href="../testsuites.html">Test suites</a>
            </div>
          </li><li>
            <div>
              <a title="Miscellaneous links of interest related to libvirt" class="inactive" href="../relatedlinks.html">Related Links</a>
            </div>
          </li><li>
            <div>
              <a title="Overview of all content on the website" class="inactive" href="../sitemap.html">Sitemap</a>
            </div>
          </li></ul>
      </div>
      <div id="content">
        <h1>Spawning processes / commands from libvirt drivers</h1>
        <ul><li>
            <a href="#posix">Problems with standard POSIX APIs</a>
          </li><li>
            <a href="#api">The libvirt command execution API</a>
            <ul><li>
                <a href="#initial">Defining commands in libvirt</a>
              </li><li>
                <a href="#args">Adding arguments to the command</a>
              </li><li>
                <a href="#env">Setting up the environment</a>
              </li><li>
                <a href="#misc">Miscellaneous other options</a>
              </li><li>
                <a href="#privs">Reducing command privileges</a>
              </li><li>
                <a href="#fds">Managing file handles</a>
              </li><li>
                <a href="#buffers">Feeding &amp; capturing strings to/from the child</a>
              </li><li>
                <a href="#directory">Setting working directory</a>
              </li><li>
                <a href="#hooks">Any additional hooks</a>
              </li><li>
                <a href="#logging">Logging commands</a>
              </li><li>
                <a href="#sync">Running commands synchronously</a>
              </li><li>
                <a href="#async">Running commands asynchronously</a>
              </li><li>
                <a href="#release">Releasing resources</a>
              </li></ul>
          </li><li>
            <a href="#example">Complete examples</a>
          </li></ul>
        <p>
      This page describes the usage of libvirt APIs for
      spawning processes / commands from libvirt drivers.
      All code is required to use these APIs
    </p>
        <h2>
          <a name="posix" shape="rect" id="posix">Problems with standard POSIX APIs</a>
          <a class="headerlink" href="#posix" title="Permalink to this headline">¶</a>
        </h2>
        <p>
      The POSIX specification includes a number of APIs for
      spawning processes / commands, but they suffer from
      a number of flaws
    </p>
        <ul><li><code>fork+exec</code>: The lowest &amp; most flexible
        level, but very hard to use correctly / safely. It
        is easy to leak file descriptors, have unexpected
        signal handler behaviour and not handle edge cases.
        Furthermore, it is not portable to mingw.
        </li><li><code>system</code>: Convenient if you don't care
        about capturing command output, but has the serious
        downside that the command string is interpreted by
        the shell. This makes it very dangerous to use, because
        improperly validated user input can lead to exploits
        via shell meta characters.
      </li><li><code>popen</code>: Inherits the flaws of
        <code>system</code>, and has no option for bi-directional
        communication.
      </li><li><code>posix_spawn</code>: A half-way house between
        simplicity of system() and the flexibility of fork+exec.
        It does not allow for a couple of important features
        though, such as running a hook between the fork+exec
        stage, or closing all open file descriptors.</li></ul>
        <p>
      Due to the problems mentioned with each of these,
      libvirt driver code <strong>must not use</strong> any
      of the above APIs. Historically libvirt provided a
      higher level API known as virExec. This was wrapper
      around fork+exec, in a similar style to posix_spawn,
      but with a few more features.
    </p>
        <p>
      This wrapper still suffered from a number of problems.
      Handling command cleanup via waitpid() is overly
      complex &amp; error prone for most usage. Building up the
      argv[] + env[] string arrays is quite cumbersome and
      error prone, particularly wrt memory leak / OOM handling.
    </p>
        <h2>
          <a name="api" shape="rect" id="api">The libvirt command execution API</a>
          <a class="headerlink" href="#api" title="Permalink to this headline">¶</a>
        </h2>
        <p>
      There is now a high level API that provides a safe and
      flexible way to spawn commands, which prevents the most
      common errors &amp; is easy to code against.  This
      code is provided in the <code>src/util/command.h</code>
      header which can be imported using <code>#include "command.h"</code>
    </p>
        <h3>
          <a name="initial" shape="rect" id="initial">Defining commands in libvirt</a>
          <a class="headerlink" href="#initial" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      The first step is to declare what command is to be
      executed. The command name can be either a fully
      qualified path, or a bare command name. In the latter
      case it will be resolved wrt the <code>$PATH</code>
      environment variable.
    </p>
        <pre xml:space="preserve">
  virCommandPtr cmd = virCommandNew("/usr/bin/dnsmasq");
</pre>
        <p>
      There is no need to check for allocation failure after
      <code>virCommandNew</code>. This will be detected and
      reported at a later time.
    </p>
        <h3>
          <a name="args" shape="rect" id="args">Adding arguments to the command</a>
          <a class="headerlink" href="#args" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      There are a number of APIs for adding arguments to a
      command. To add a direct string arg
    </p>
        <pre xml:space="preserve">
  virCommandAddArg(cmd, "-strict-order");
</pre>
        <p>
      If an argument takes an attached value of the form
      <code>-arg=val</code>, then this can be done using
    </p>
        <pre xml:space="preserve">
  virCommandAddArgPair(cmd, "--conf-file", "/etc/dnsmasq.conf");
</pre>
        <p>
      If an argument needs to be formatted as if by
      <code>printf</code>:
    </p>
        <pre xml:space="preserve">
  virCommandAddArgFormat(cmd, "%d", count);
</pre>
        <p>
      To add a entire NULL terminated array of arguments in one go,
      there are two options.
    </p>
        <pre xml:space="preserve">
  const char *const args[] = {
      "--strict-order", "--except-interface", "lo", NULL
  };
  virCommandAddArgSet(cmd, args);
  virCommandAddArgList(cmd, "--domain", "localdomain", NULL);
</pre>
        <p>
      This can also be done at the time of initial construction of
      the <code>virCommandPtr</code> object:
    </p>
        <pre xml:space="preserve">
  const char *const args[] = {
      "/usr/bin/dnsmasq",
      "--strict-order", "--except-interface",
      "lo", "--domain", "localdomain", NULL
  };
  virCommandPtr cmd1 = virCommandNewArgs(cmd, args);
  virCommandPtr cmd2 = virCommandNewArgList("/usr/bin/dnsmasq",
                                            "--domain", "localdomain", NULL);
</pre>
        <h3>
          <a name="env" shape="rect" id="env">Setting up the environment</a>
          <a class="headerlink" href="#env" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      By default a command will inherit all environment variables
      from the current process. Generally this is not desirable
      and a customized environment will be more suitable. Any
      customization done via the following APIs will prevent
      inheritance of any existing environment variables unless
      explicitly allowed. The first step is usually to pass through
      a small number of variables from the current process.
    </p>
        <pre xml:space="preserve">
  virCommandAddEnvPassCommon(cmd);
</pre>
        <p>
      This has now set up a clean environment for the child, passing
      through <code>PATH</code>, <code>LD_PRELOAD</code>,
      <code>LD_LIBRARY_PATH</code>, <code>HOME</code>,
      <code>USER</code>, <code>LOGNAME</code> and <code>TMPDIR</code>.
      Furthermore it will explicitly set <code>LC_ALL=C</code> to
      avoid unexpected localization of command output. Further
      variables can be passed through from parent explicitly:
    </p>
        <pre xml:space="preserve">
  virCommandAddEnvPass(cmd, "DISPLAY");
  virCommandAddEnvPass(cmd, "XAUTHORITY");
</pre>
        <p>
      To define an environment variable in the child with an
      separate key / value:
    </p>
        <pre xml:space="preserve">
  virCommandAddEnvPair(cmd, "TERM", "xterm");
</pre>
        <p>
      If the key/value pair is pre-formatted in the right
      format, it can be set directly
    </p>
        <pre xml:space="preserve">
  virCommandAddEnvString(cmd, "TERM=xterm");
</pre>
        <h3>
          <a name="misc" shape="rect" id="misc">Miscellaneous other options</a>
          <a class="headerlink" href="#misc" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Normally the spawned command will retain the current
      process and process group as its parent. If the current
      process dies, the child will then (usually) be terminated
      too. If this cleanup is not desired, then the command
      should be marked as daemonized:
    </p>
        <pre xml:space="preserve">
  virCommandDaemonize(cmd);
</pre>
        <p>
      When daemonizing a command, the PID visible from the
      caller will be that of the intermediate process, not
      the actual damonized command. If the PID of the real
      command is required then a pidfile can be requested
    </p>
        <pre xml:space="preserve">
  virCommandSetPidFile(cmd, "/var/run/dnsmasq.pid");
</pre>
        <p>
      This PID file is guaranteed to be written before
      the intermediate process exits.
    </p>
        <h3>
          <a name="privs" shape="rect" id="privs">Reducing command privileges</a>
          <a class="headerlink" href="#privs" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Normally a command will inherit all privileges of
      the current process. To restrict what a command can
      do, it is possible to request that all its capabilities
      are cleared. With this done it will only be able to
      access resources for which it has explicit DAC permissions
    </p>
        <pre xml:space="preserve">
  virCommandClearCaps(cmd);
</pre>
        <h3>
          <a name="fds" shape="rect" id="fds">Managing file handles</a>
          <a class="headerlink" href="#fds" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      To prevent unintended resource leaks to child processes, the
      child defaults to closing all open file handles, and setting
      stdin/out/err to <code>/dev/null</code>.  It is possible to
      allow an open file handle to be passed into the child, while
      controlling whether that handle remains open in the parent or
      guaranteeing that the handle will be closed in the parent after
      virCommandRun, virCommandRunAsync, or virCommandFree.
    </p>
        <pre xml:space="preserve">
  int sharedfd = open("cmd.log", "w+");
  int childfd = open("conf.txt", "r");
  virCommandPassFD(cmd, sharedfd, 0);
  virCommandPassFD(cmd, childfd,
                   VIR_COMMAND_PASS_FD_CLOSE_PARENT);
  if (VIR_CLOSE(sharedfd) &lt; 0)
      goto cleanup;
</pre>
        <p>
      With this, both file descriptors sharedfd and childfd in the
      current process remain open as the same file descriptors in the
      child. Meanwhile, after the child is spawned, sharedfd remains
      open in the parent, while childfd is closed.
    </p>
        <p>
      For stdin/out/err it is sometimes necessary to map a file
      handle.  If a mapped file handle is a pipe fed or consumed by
      the caller, then the caller should use virCommandDaemonize or
      virCommandRunAsync rather than virCommandRun to avoid deadlock
      (mapping a regular file is okay with virCommandRun).  To attach
      file descriptor 7 in the current process to stdin in the child:
    </p>
        <pre xml:space="preserve">
  virCommandSetInputFD(cmd, 7);
</pre>
        <p>
      Equivalently to redirect stdout or stderr in the child,
      pass in a pointer to the desired handle
    </p>
        <pre xml:space="preserve">
  int outfd = open("out.log", "w+");
  int errfd = open("err.log", "w+");
  virCommandSetOutputFD(cmd, &amp;outfd);
  virCommandSetErrorFD(cmd, &amp;errfd);
</pre>
        <p>
      Alternatively it is possible to request that a pipe be
      created to fetch stdout/err in the parent, by initializing
      the FD to -1.
    </p>
        <pre xml:space="preserve">
  int outfd = -1;
  int errfd = -1
  virCommandSetOutputFD(cmd, &amp;outfd);
  virCommandSetErrorFD(cmd, &amp;errfd);
</pre>
        <p>
      Once the command is running, <code>outfd</code>
      and <code>errfd</code> will be initialized with
      valid file handles that can be read from.  It is
      permissible to pass the same pointer for both outfd
      and errfd, in which case both standard streams in
      the child will share the same fd in the parent.
    </p>
        <p>
      Normally, file descriptors opened to collect output from a child
      process perform blocking I/O, but the parent process can request
      non-blocking mode:
    </p>
        <pre xml:space="preserve">
  virCommandNonblockingFDs(cmd);
</pre>
        <h3>
          <a name="buffers" shape="rect" id="buffers">Feeding &amp; capturing strings to/from the child</a>
          <a class="headerlink" href="#buffers" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Often dealing with file handles for stdin/out/err is
      unnecessarily complex; an alternative is to let virCommandRun
      perform the I/O and interact via string buffers. Use of a buffer
      only works with virCommandRun, and cannot be mixed with pipe
      file descriptors.  That is, the choice is generally between
      managing all I/O in the caller (any fds not specified are tied
      to /dev/null), or letting virCommandRun manage all I/O via
      strings (unspecified stdin is tied to /dev/null, and unspecified
      output streams get logged but are otherwise discarded).
    </p>
        <p>
      It is possible to specify a string buffer to act as the data
      source for the child's stdin, if there are no embedded NUL
      bytes, and if the command will be run with virCommandRun:
    </p>
        <pre xml:space="preserve">
  const char *input = "Hello World\n";
  virCommandSetInputBuffer(cmd, input);
</pre>
        <p>
      Similarly it is possible to request that the child's
      stdout/err be redirected into a string buffer, if the
      output is not expected to contain NUL bytes, and if
      the command will be run with virCommandRun:
    </p>
        <pre xml:space="preserve">
  char *output = NULL, *errors = NULL;
  virCommandSetOutputBuffer(cmd, &amp;output);
  virCommandSetErrorBuffer(cmd, &amp;errors);
</pre>
        <p>
      Once the command has finished executing, these buffers will
      contain the output.  Allocation is guaranteed if virCommandRun
      or virCommandWait succeed (if there was no output, then the
      buffer will contain an allocated empty string); if the command
      failed, then the buffers usually contain a best-effort
      allocation of collected information (however, on an
      out-of-memory condition, the buffer may still be NULL).  The
      caller is responsible for freeing registered buffers, since the
      buffers are designed to persist beyond virCommandFree.  It
      is possible to pass the same pointer to both
      virCommandSetOutputBuffer and virCommandSetErrorBuffer, in which
      case the child process interleaves output into a single string.
    </p>
        <h3>
          <a name="directory" shape="rect" id="directory">Setting working directory</a>
          <a class="headerlink" href="#directory" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Daemonized commands are always run with "/" as the current
      working directory.  All other commands default to running in the
      same working directory as the parent process, but an alternate
      directory can be specified:
    </p>
        <pre xml:space="preserve">
  virCommandSetWorkingDirectory(cmd, LOCALSTATEDIR);
</pre>
        <h3>
          <a name="hooks" shape="rect" id="hooks">Any additional hooks</a>
          <a class="headerlink" href="#hooks" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      If anything else is needed, it is possible to request a hook
      function that is called in the child after the fork, as the
      last thing before changing directories, dropping capabilities,
      and executing the new process.  If hook(opaque) returns
      non-zero, then the child process will not be run.
    </p>
        <pre xml:space="preserve">
  virCommandSetPreExecHook(cmd, hook, opaque);
</pre>
        <h3>
          <a name="logging" shape="rect" id="logging">Logging commands</a>
          <a class="headerlink" href="#logging" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Sometimes, it is desirable to log what command will be run, or
      even to use virCommand solely for creation of a single
      consolidated string without running anything.
    </p>
        <pre xml:space="preserve">
  int logfd = ...;
  char *timestamp = virTimestamp();
  char *string = NULL;

  dprintf(logfd, "%s: ", timestamp);
  VIR_FREE(timestamp);
  virCommandWriteArgLog(cmd, logfd);

  string = virCommandToString(cmd);
  if (string)
      VIR_DEBUG("about to run %s", string);
  VIR_FREE(string);
  if (virCommandRun(cmd, NULL) &lt; 0)
      return -1;
</pre>
        <h3>
          <a name="sync" shape="rect" id="sync">Running commands synchronously</a>
          <a class="headerlink" href="#sync" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      For most commands, the desired behaviour is to spawn
      the command, wait for it to complete &amp; exit and then
      check that its exit status is zero
    </p>
        <pre xml:space="preserve">
  if (virCommandRun(cmd, NULL) &lt; 0)
     return -1;
</pre>
        <p>
      <strong>Note:</strong> if the command has been daemonized
      this will only block &amp; wait for the intermediate process,
      not the real command. <code>virCommandRun</code> will
      report on any errors that have occurred upon this point
      with all previous API calls. If the command fails to
      run, or exits with non-zero status an error will be
      reported via normal libvirt error infrastructure. If a
      non-zero exit status can represent a success condition,
      it is possible to request the exit status and perform
      that check manually instead of letting <code>virCommandRun</code>
      raise the error.  By default, the captured status is only
      for a normal exit (death from a signal is treated as an error),
      but a caller can use <code>virCommandRawStatus</code> to get
      encoded status that includes any terminating signals.
    </p>
        <pre xml:space="preserve">
  int status;
  if (virCommandRun(cmd, &amp;status) &lt; 0)
      return -1;
  if (status == 1) {
    ...do stuff...
  }

  virCommandRawStatus(cmd2);
  if (virCommandRun(cmd2, &amp;status) &lt; 0)
      return -1;
  if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status) == 1) {
    ...do stuff...
  }
</pre>
        <h3>
          <a name="async" shape="rect" id="async">Running commands asynchronously</a>
          <a class="headerlink" href="#async" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      In certain complex scenarios, particularly special
      I/O handling is required for the child's stdin/err/out
      it will be necessary to run the command asynchronously
      and wait for completion separately.
    </p>
        <pre xml:space="preserve">
  pid_t pid;
  if (virCommandRunAsync(cmd, &amp;pid) &lt; 0)
     return -1;

  ... do something while pid is running ...

  int status;
  if (virCommandWait(cmd, &amp;status) &lt; 0)
     return -1;

  if (WEXITSTATUS(status)...) {
     ..do stuff..
  }
</pre>
        <p>
      As with <code>virCommandRun</code>, the <code>status</code>
      arg for <code>virCommandWait</code> can be omitted, in which
      case it will validate that exit status is zero and raise an
      error if not.
    </p>
        <p>
      There are two approaches to child process cleanup, determined by
      how long you want to keep the virCommand object in scope.
    </p>
        <p>1. If the virCommand object will outlast the child process,
      then pass NULL for the pid argument, and the child process will
      automatically be reaped at virCommandFree, unless you reap it
      sooner via virCommandWait or virCommandAbort.
    </p>
        <p>2. If the child process must exist on at least one code path
      after virCommandFree, then pass a pointer for the pid argument.
      Later, to clean up the child, call virPidWait or virPidAbort.
      Before virCommandFree, you can still use virCommandWait or
      virCommandAbort to reap the process.
    </p>
        <h3>
          <a name="release" shape="rect" id="release">Releasing resources</a>
          <a class="headerlink" href="#release" title="Permalink to this headline">¶</a>
        </h3>
        <p>
      Once the command has been executed, or if execution
      has been abandoned, it is necessary to release
      resources associated with the <code>virCommandPtr</code>
      object. This is done with:
    </p>
        <pre xml:space="preserve">
  virCommandFree(cmd);
</pre>
        <p>
      There is no need to check if <code>cmd</code> is NULL
      before calling <code>virCommandFree</code>. This scenario
      is handled automatically. If the command is still running,
      it will be forcibly killed and cleaned up (via waitpid).
    </p>
        <h2>
          <a name="example" shape="rect" id="example">Complete examples</a>
          <a class="headerlink" href="#example" title="Permalink to this headline">¶</a>
        </h2>
        <p>
      This shows a complete example usage of the APIs roughly
      using the libvirt source src/util/hooks.c
    </p>
        <pre xml:space="preserve">
int runhook(const char *drvstr, const char *id,
            const char *opstr, const char *subopstr,
            const char *extra)
{
  int ret;
  char *path;
  virCommandPtr cmd;

  ret = virBuildPath(&amp;path, LIBVIRT_HOOK_DIR, drvstr);
  if ((ret &lt; 0) || (path == NULL)) {
      virHookReportError(VIR_ERR_INTERNAL_ERROR,
                         _("Failed to build path for %s hook"),
                         drvstr);
      return -1;
  }

  cmd = virCommandNew(path);
  VIR_FREE(path);

  virCommandAddEnvPassCommon(cmd);

  virCommandAddArgList(cmd, id, opstr, subopstr, extra, NULL);

  virCommandSetInputBuffer(cmd, input);

  ret = virCommandRun(cmd, NULL);

  virCommandFree(cmd);

  return ret;
}
</pre>
        <p>
      In this example, the command is being run synchronously.
      A pre-formatted string is being fed to the command as
      its stdin. The command takes four arguments, and has a
      minimal set of environment variables passed down. In
      this example, the code does not require any error checking.
      All errors are reported by the <code>virCommandRun</code>
      method, and the exit status from this is returned to
      the caller to handle as desired.
    </p>
      </div>
    </div>
    <div id="footer">
      <p id="sponsor">
	    Sponsored by:<br /><a href="http://et.redhat.com/"><img src="../et.png" alt="Project sponsored by Red Hat Emerging Technology" /></a></p>
    </div>
  </body>
</html>