[glib: 1/2] gsubprocess: Add G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP




commit 9bd47300086e549d7f3927d05311690a532e063c
Author: Hristo Venev <hristo venev name>
Date:   Wed Nov 17 12:27:46 2021 +0000

    gsubprocess: Add G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP

 gio/gioenums.h                    |  6 +++++-
 gio/gsubprocess.c                 |  7 +++++--
 gio/gsubprocesslauncher-private.h |  1 -
 gio/tests/gsubprocess.c           | 43 +++++++++++++++++++++++++++++++--------
 4 files changed, 45 insertions(+), 12 deletions(-)
---
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 47ca06bed..4c595803d 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -1983,6 +1983,9 @@ typedef enum /*< flags >*/ {
  *   file descriptors of their parent, unless those descriptors have
  *   been explicitly marked as close-on-exec.  This flag has no effect
  *   over the "standard" file descriptors (stdin, stdout, stderr).
+ * @G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP: if path searching is
+ *   needed when spawning the subprocess, use the `PATH` in the launcher
+ *   environment. (Since: 2.72)
  *
  * Flags to define the behaviour of a #GSubprocess.
  *
@@ -2005,7 +2008,8 @@ typedef enum {
   G_SUBPROCESS_FLAGS_STDERR_PIPE           = (1u << 4),
   G_SUBPROCESS_FLAGS_STDERR_SILENCE        = (1u << 5),
   G_SUBPROCESS_FLAGS_STDERR_MERGE          = (1u << 6),
-  G_SUBPROCESS_FLAGS_INHERIT_FDS           = (1u << 7)
+  G_SUBPROCESS_FLAGS_INHERIT_FDS           = (1u << 7),
+  G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP = (1u << 8)
 } GSubprocessFlags;
 
 /**
diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c
index c0f4f8db6..523c80bfc 100644
--- a/gio/gsubprocess.c
+++ b/gio/gsubprocess.c
@@ -61,7 +61,10 @@
  * As a matter of principle, #GSubprocess has no API that accepts
  * shell-style space-separated strings.  It will, however, match the
  * typical shell behaviour of searching the PATH for executables that do
- * not contain a directory separator in their name.
+ * not contain a directory separator in their name. By default, the `PATH`
+ * of the current process is used.  You can specify
+ * %G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP to use the `PATH` of the
+ * launcher environment instead.
  *
  * #GSubprocess attempts to have a very simple API for most uses (ie:
  * spawning a subprocess with arguments and support for most typical
@@ -380,7 +383,7 @@ initable_init (GInitable     *initable,
   /* argv0 has no '/' in it?  We better do a PATH lookup. */
   if (strchr (self->argv[0], G_DIR_SEPARATOR) == NULL)
     {
-      if (self->launcher && self->launcher->path_from_envp)
+      if (self->launcher && self->launcher->flags & G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP)
         spawn_flags |= G_SPAWN_SEARCH_PATH_FROM_ENVP;
       else
         spawn_flags |= G_SPAWN_SEARCH_PATH;
diff --git a/gio/gsubprocesslauncher-private.h b/gio/gsubprocesslauncher-private.h
index d6fe0d784..8bd1b2844 100644
--- a/gio/gsubprocesslauncher-private.h
+++ b/gio/gsubprocesslauncher-private.h
@@ -28,7 +28,6 @@ struct _GSubprocessLauncher
   GObject parent;
 
   GSubprocessFlags flags;
-  gboolean path_from_envp;
   char **envp;
   char *cwd;
 
diff --git a/gio/tests/gsubprocess.c b/gio/tests/gsubprocess.c
index 084b77df3..95ee3ac77 100644
--- a/gio/tests/gsubprocess.c
+++ b/gio/tests/gsubprocess.c
@@ -26,6 +26,14 @@
 #define SPLICELEN (TOTAL_HELLOS * strlen (HELLO_WORLD))
 #endif
 
+
+
+#ifdef G_OS_WIN32
+#define TESTPROG "gsubprocess-testprog.exe"
+#else
+#define TESTPROG "gsubprocess-testprog"
+#endif
+
 static GPtrArray *
 get_test_subprocess_args (const char *mode,
                           ...) G_GNUC_NULL_TERMINATED;
@@ -36,19 +44,12 @@ get_test_subprocess_args (const char *mode,
 {
   GPtrArray *ret;
   char *path;
-  const char *binname;
   va_list args;
   gpointer arg;
 
   ret = g_ptr_array_new_with_free_func (g_free);
 
-#ifdef G_OS_WIN32
-  binname = "gsubprocess-testprog.exe";
-#else
-  binname = "gsubprocess-testprog";
-#endif
-
-  path = g_test_build_filename (G_TEST_BUILT, binname, NULL);
+  path = g_test_build_filename (G_TEST_BUILT, TESTPROG, NULL);
   g_ptr_array_add (ret, path);
   g_ptr_array_add (ret, g_strdup (mode));
 
@@ -167,6 +168,31 @@ test_search_path (void)
 
   g_object_unref (proc);
 }
+
+static void
+test_search_path_from_envp (void)
+{
+  GError *local_error = NULL;
+  GError **error = &local_error;
+  GSubprocessLauncher *launcher;
+  GSubprocess *proc;
+  const char *path;
+
+  path = g_test_get_dir (G_TEST_BUILT);
+
+  launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP);
+  g_subprocess_launcher_setenv (launcher, "PATH", path, TRUE);
+
+  proc = g_subprocess_launcher_spawn (launcher, error, TESTPROG, "exit1", NULL);
+  g_assert_no_error (local_error);
+  g_object_unref (launcher);
+
+  g_subprocess_wait_check (proc, NULL, error);
+  g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
+  g_clear_error (error);
+
+  g_object_unref (proc);
+}
 #endif
 
 static void
@@ -1819,6 +1845,7 @@ main (int argc, char **argv)
   g_test_add_func ("/gsubprocess/noop-stdin-inherit", test_noop_stdin_inherit);
 #ifdef G_OS_UNIX
   g_test_add_func ("/gsubprocess/search-path", test_search_path);
+  g_test_add_func ("/gsubprocess/search-path-from-envp", test_search_path_from_envp);
   g_test_add_func ("/gsubprocess/signal", test_signal);
 #endif
   g_test_add_func ("/gsubprocess/exit1", test_exit1);


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