[Libguestfs] [PATCH INCOMPLETE] Rewrite virt-make-fs in C (originally Perl).

Pino Toscano ptoscano at redhat.com
Mon Jan 27 14:09:03 UTC 2014


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




More information about the Libguestfs mailing list