2 * Copyright 2021 Collabora Ltd.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see
16 * <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
27 test_do_not_search (void)
29 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
30 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
31 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
32 gchar **envp = g_get_environ ();
38 g_test_summary ("Without G_SPAWN_SEARCH_PATH, spawn-test-helper "
39 "means ./spawn-test-helper.");
41 envp = g_environ_setenv (envp, "PATH", subdir, TRUE);
43 g_ptr_array_add (argv,
44 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
45 g_ptr_array_add (argv, g_strdup ("--"));
46 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
47 g_ptr_array_add (argv, NULL);
50 (char **) argv->pdata,
53 NULL, /* child setup */
59 g_assert_no_error (error);
61 g_test_message ("%s", out);
62 g_test_message ("%s", err);
63 g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests"));
66 g_assert_true (WIFEXITED (wait_status));
67 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0);
75 g_ptr_array_unref (argv);
79 test_search_path (void)
81 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
82 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
83 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
84 gchar **envp = g_get_environ ();
90 g_test_summary ("With G_SPAWN_SEARCH_PATH, spawn-test-helper "
91 "means $PATH/spawn-test-helper.");
93 envp = g_environ_setenv (envp, "PATH", subdir, TRUE);
95 g_ptr_array_add (argv,
96 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
97 g_ptr_array_add (argv, g_strdup ("--search-path"));
98 g_ptr_array_add (argv, g_strdup ("--"));
99 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
100 g_ptr_array_add (argv, NULL);
103 (char **) argv->pdata,
106 NULL, /* child setup */
107 NULL, /* user data */
112 g_assert_no_error (error);
114 g_test_message ("%s", out);
115 g_test_message ("%s", err);
116 g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir"));
119 g_assert_true (WIFEXITED (wait_status));
120 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5);
128 g_ptr_array_unref (argv);
132 test_search_path_from_envp (void)
134 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
135 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
136 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
137 gchar **envp = g_get_environ ();
140 GError *error = NULL;
141 int wait_status = -1;
143 g_test_summary ("With G_SPAWN_SEARCH_PATH_FROM_ENVP, spawn-test-helper "
144 "means $PATH/spawn-test-helper with $PATH from envp.");
146 envp = g_environ_setenv (envp, "PATH", here, TRUE);
148 g_ptr_array_add (argv,
149 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
150 g_ptr_array_add (argv, g_strdup ("--search-path-from-envp"));
151 g_ptr_array_add (argv, g_strdup ("--set-path-in-envp"));
152 g_ptr_array_add (argv, g_strdup (subdir));
153 g_ptr_array_add (argv, g_strdup ("--"));
154 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
155 g_ptr_array_add (argv, NULL);
158 (char **) argv->pdata,
161 NULL, /* child setup */
162 NULL, /* user data */
167 g_assert_no_error (error);
169 g_test_message ("%s", out);
170 g_test_message ("%s", err);
171 g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir"));
174 g_assert_true (WIFEXITED (wait_status));
175 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5);
183 g_ptr_array_unref (argv);
187 test_search_path_ambiguous (void)
189 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
190 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
191 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
192 gchar **envp = g_get_environ ();
195 GError *error = NULL;
196 int wait_status = -1;
198 g_test_summary ("With G_SPAWN_SEARCH_PATH and G_SPAWN_SEARCH_PATH_FROM_ENVP, "
201 envp = g_environ_setenv (envp, "PATH", here, TRUE);
203 g_ptr_array_add (argv,
204 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
205 g_ptr_array_add (argv, g_strdup ("--search-path"));
206 g_ptr_array_add (argv, g_strdup ("--search-path-from-envp"));
207 g_ptr_array_add (argv, g_strdup ("--set-path-in-envp"));
208 g_ptr_array_add (argv, g_strdup (subdir));
209 g_ptr_array_add (argv, g_strdup ("--"));
210 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
211 g_ptr_array_add (argv, NULL);
214 (char **) argv->pdata,
217 NULL, /* child setup */
218 NULL, /* user data */
223 g_assert_no_error (error);
225 g_test_message ("%s", out);
226 g_test_message ("%s", err);
227 g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir"));
230 g_assert_true (WIFEXITED (wait_status));
231 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5);
239 g_ptr_array_unref (argv);
243 test_search_path_fallback_in_environ (void)
245 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
246 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
247 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
248 gchar **envp = g_get_environ ();
251 GError *error = NULL;
252 int wait_status = -1;
254 g_test_summary ("With G_SPAWN_SEARCH_PATH but no PATH, a fallback is used.");
255 /* We can't make a meaningful assertion about what the fallback *is*,
256 * but we can assert that it *includes* the current working directory. */
258 if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) ||
259 g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE))
261 g_test_skip ("Not testing fallback with unknown spawn-test-helper "
262 "executable in /usr/bin:/bin");
266 envp = g_environ_unsetenv (envp, "PATH");
268 g_ptr_array_add (argv,
269 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
270 g_ptr_array_add (argv, g_strdup ("--search-path"));
271 g_ptr_array_add (argv, g_strdup ("--set-path-in-envp"));
272 g_ptr_array_add (argv, g_strdup (subdir));
273 g_ptr_array_add (argv, g_strdup ("--"));
274 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
275 g_ptr_array_add (argv, NULL);
278 (char **) argv->pdata,
281 NULL, /* child setup */
282 NULL, /* user data */
287 g_assert_no_error (error);
289 g_test_message ("%s", out);
290 g_test_message ("%s", err);
291 g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests"));
294 g_assert_true (WIFEXITED (wait_status));
295 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0);
303 g_ptr_array_unref (argv);
307 test_search_path_fallback_in_envp (void)
309 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
310 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
311 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
312 gchar **envp = g_get_environ ();
315 GError *error = NULL;
316 int wait_status = -1;
318 g_test_summary ("With G_SPAWN_SEARCH_PATH_FROM_ENVP but no PATH, a fallback is used.");
319 /* We can't make a meaningful assertion about what the fallback *is*,
320 * but we can assert that it *includes* the current working directory. */
322 if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) ||
323 g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE))
325 g_test_skip ("Not testing fallback with unknown spawn-test-helper "
326 "executable in /usr/bin:/bin");
330 envp = g_environ_setenv (envp, "PATH", subdir, TRUE);
332 g_ptr_array_add (argv,
333 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
334 g_ptr_array_add (argv, g_strdup ("--search-path-from-envp"));
335 g_ptr_array_add (argv, g_strdup ("--unset-path-in-envp"));
336 g_ptr_array_add (argv, g_strdup ("--"));
337 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
338 g_ptr_array_add (argv, NULL);
341 (char **) argv->pdata,
344 NULL, /* child setup */
345 NULL, /* user data */
350 g_assert_no_error (error);
352 g_test_message ("%s", out);
353 g_test_message ("%s", err);
354 g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests"));
357 g_assert_true (WIFEXITED (wait_status));
358 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0);
366 g_ptr_array_unref (argv);
370 test_search_path_heap_allocation (void)
372 GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
373 /* Must be longer than the arbitrary 4000 byte limit for stack allocation
375 char placeholder[4096];
376 gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
377 gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
378 gchar *long_dir = NULL;
379 gchar *long_path = NULL;
380 gchar **envp = g_get_environ ();
383 GError *error = NULL;
384 int wait_status = -1;
387 memset (placeholder, '_', sizeof (placeholder));
388 /* Force search_path_buffer to be heap-allocated */
389 long_dir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", placeholder, NULL);
390 long_path = g_strjoin (G_SEARCHPATH_SEPARATOR_S, subdir, long_dir, NULL);
391 envp = g_environ_setenv (envp, "PATH", long_path, TRUE);
393 g_ptr_array_add (argv,
394 g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
395 g_ptr_array_add (argv, g_strdup ("--search-path"));
396 g_ptr_array_add (argv, g_strdup ("--"));
397 g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
399 /* Add enough arguments to make argv longer than the arbitrary 4000 byte
400 * limit for stack allocation in gspawn.c.
401 * This assumes sizeof (char *) >= 4. */
402 for (i = 0; i < 1001; i++)
403 g_ptr_array_add (argv, g_strdup ("_"));
405 g_ptr_array_add (argv, NULL);
408 (char **) argv->pdata,
411 NULL, /* child setup */
412 NULL, /* user data */
417 g_assert_no_error (error);
419 g_test_message ("%s", out);
420 g_test_message ("%s", err);
421 g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir"));
424 g_assert_true (WIFEXITED (wait_status));
425 g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5);
433 g_ptr_array_unref (argv);
440 g_test_init (&argc, &argv, NULL);
442 g_test_add_func ("/spawn/do-not-search", test_do_not_search);
443 g_test_add_func ("/spawn/search-path", test_search_path);
444 g_test_add_func ("/spawn/search-path-from-envp", test_search_path_from_envp);
445 g_test_add_func ("/spawn/search-path-ambiguous", test_search_path_ambiguous);
446 g_test_add_func ("/spawn/search-path-heap-allocation",
447 test_search_path_heap_allocation);
448 g_test_add_func ("/spawn/search-path-fallback-in-environ",
449 test_search_path_fallback_in_environ);
450 g_test_add_func ("/spawn/search-path-fallback-in-envp",
451 test_search_path_fallback_in_envp);
453 return g_test_run ();