On Monday 27 January 2014 13:29:54 Richard W.M. Jones wrote:
+/* Execute a command, sending output to a file. */
+static int
+exec_command (char **argv, const char *file, int stderr_to_file)
+{
+ pid_t pid;
+ int status, fd;
+ FILE *fp;
+ char line[256];
+
+ pid = fork ();
+ if (pid == -1) {
+ perror ("fork");
+ return -1;
+ }
+ if (pid > 0) {
+ if (waitpid (pid, &status, 0) == -1) {
+ perror ("waitpid");
+ return -1;
+ }
+ if (!WIFEXITED (status) || WEXITSTATUS (status) != 0) {
+ /* If the command failed, dump out the contents of tmpfile
which + * contains the exact error messages from qemu-img.
+ */
+ fprintf (stderr, _("%s: %s command failed\n"), program_name,
argv[0]); +
+ if (stderr_to_file) {
+ fp = fopen (tmpfile, "r");
+ if (fp != NULL) {
+ while (fgets (line, sizeof line, fp) != NULL)
+ fprintf (stderr, "%s", line);
+ fclose (fp);
+ }
+ }
+
+ return -1;
+ }
+ return 0;
+ }
+
+ /* Child process. */
+ fd = open (tmpfile, O_WRONLY|O_NOCTTY);
+ if (fd == -1) {
+ perror (tmpfile);
+ _exit (EXIT_FAILURE);
+ }
+ dup2 (fd, 1);
+ if (stderr_to_file)
+ dup2 (fd, 2);
+ close (fd);
+
+ execvp (argv[0], argv);
+ perror ("execvp");
+ _exit (EXIT_FAILURE);
+}
+
+/* Execute a command in the background, sending output to a pipe. */
+static int
+bg_command (char **argv, char **pipef)
+{
Reading this and other similar implementations, for example:
- fish/events.c, do_event_handler
- fish/fish.c, execute_and_inline and issue_command (which has a comment
regarding pipe commands)
- src/command.c, run_command
- src/launch-direct.c, launch_direct
- src/launch-uml.c, launch_uml
- daemon/guestfsd.c, commandrf (maybe, since it is in the appliance);
other popen usages in daemon/*
what about using libpipeline [1] to handle them? While it adds the
overhead of a new shared library (although using just libc, and ~55kb in
my f19/x86_64 installation), should help a bit in spawning commands and
handling piping of them if needed.
Given you are starting a new tool in C [2], what about making use of it
to check how it works?
[1]
http://libpipeline.nongnu.org/
[2] as in, was not in C before
--
Pino Toscano