[Libguestfs] [PATCH 2/6] cmd: add a child-setup callback

Pino Toscano ptoscano at redhat.com
Mon Jan 26 16:04:07 UTC 2015


Easy way to do pre-exec setup in the child process.
---
 src/command.c          | 22 ++++++++++++++++++++++
 src/guestfs-internal.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/src/command.c b/src/command.c
index e26573d..563d0af 100644
--- a/src/command.c
+++ b/src/command.c
@@ -134,6 +134,10 @@ struct command
 
   /* PID of subprocess (if > 0). */
   pid_t pid;
+
+  /* Optional child setup callback. */
+  cmd_child_callback child_callback;
+  void *child_callback_data;
 };
 
 /* Create a new command handle. */
@@ -308,6 +312,19 @@ guestfs___cmd_clear_close_files (struct command *cmd)
   cmd->close_files = false;
 }
 
+/* Set a function to be executed in the child, right before the
+ * execution.  Can be used to setup the child, for example changing
+ * its current directory.
+ */
+void
+guestfs___cmd_set_child_callback (struct command *cmd,
+                                  cmd_child_callback child_callback,
+                                  void *data)
+{
+  cmd->child_callback = child_callback;
+  cmd->child_callback_data = data;
+}
+
 /* Finish off the command by either NULL-terminating the argv array or
  * adding a terminating \0 to the string, or die with an internal
  * error if no command has been added.
@@ -461,6 +478,11 @@ run_command (struct command *cmd, bool get_stdout_fd, bool get_stderr_fd)
   /* Set the umask for all subcommands to something sensible (RHBZ#610880). */
   umask (022);
 
+  if (cmd->child_callback) {
+    if (cmd->child_callback (cmd->g, cmd->child_callback_data) == -1)
+      _exit (EXIT_FAILURE);
+  }
+
   /* Run the command. */
   switch (cmd->style) {
   case COMMAND_STYLE_EXECV:
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index bd5f675..91e3065 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -857,6 +857,7 @@ extern int guestfs___osinfo_map (guestfs_h *g, const struct guestfs_isoinfo *iso
 /* command.c */
 struct command;
 typedef void (*cmd_stdout_callback) (guestfs_h *g, void *data, const char *line, size_t len);
+typedef int (*cmd_child_callback) (guestfs_h *g, void *data);
 extern struct command *guestfs___new_command (guestfs_h *g);
 extern void guestfs___cmd_add_arg (struct command *, const char *arg);
 extern void guestfs___cmd_add_arg_format (struct command *, const char *fs, ...)
@@ -870,6 +871,7 @@ extern void guestfs___cmd_set_stdout_callback (struct command *, cmd_stdout_call
 extern void guestfs___cmd_set_stderr_to_stdout (struct command *);
 extern void guestfs___cmd_clear_capture_errors (struct command *);
 extern void guestfs___cmd_clear_close_files (struct command *);
+extern void guestfs___cmd_set_child_callback (struct command *, cmd_child_callback child_callback, void *data);
 extern int guestfs___cmd_run (struct command *);
 extern int guestfs___cmd_run_async (struct command *, pid_t *pid, int *stdout_fd, int *stderr_fd);
 extern int guestfs___cmd_wait (struct command *);
-- 
1.9.3




More information about the Libguestfs mailing list