Merge branch 'g-clear-pointer-no-side-effects' into 'master'
[glib.git] / gio / tests / gsubprocess.c
blobac7051d6d9752b7fd5ccb218a751fab1927a2b85
1 #include <gio/gio.h>
2 #include <string.h>
4 #ifdef G_OS_UNIX
5 #include <sys/wait.h>
6 #include <glib-unix.h>
7 #include <gio/gunixinputstream.h>
8 #include <gio/gfiledescriptorbased.h>
9 #endif
11 #ifdef G_OS_WIN32
12 #define LINEEND "\r\n"
13 #define EXEEXT ".exe"
14 #else
15 #define LINEEND "\n"
16 #define EXEEXT
17 #endif
19 static GPtrArray *
20 get_test_subprocess_args (const char *mode,
21 ...) G_GNUC_NULL_TERMINATED;
23 static GPtrArray *
24 get_test_subprocess_args (const char *mode,
25 ...)
27 GPtrArray *ret;
28 char *path;
29 const char *binname;
30 va_list args;
31 gpointer arg;
33 ret = g_ptr_array_new_with_free_func (g_free);
35 #ifdef G_OS_WIN32
36 binname = "gsubprocess-testprog.exe";
37 #else
38 binname = "gsubprocess-testprog";
39 #endif
41 path = g_test_build_filename (G_TEST_BUILT, binname, NULL);
42 g_ptr_array_add (ret, path);
43 g_ptr_array_add (ret, g_strdup (mode));
45 va_start (args, mode);
46 while ((arg = va_arg (args, gpointer)) != NULL)
47 g_ptr_array_add (ret, g_strdup (arg));
48 va_end (args);
50 g_ptr_array_add (ret, NULL);
51 return ret;
54 static void
55 test_noop (void)
57 GError *local_error = NULL;
58 GError **error = &local_error;
59 GPtrArray *args;
60 GSubprocess *proc;
61 const gchar *id;
63 args = get_test_subprocess_args ("noop", NULL);
64 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
65 g_ptr_array_free (args, TRUE);
66 g_assert_no_error (local_error);
67 id = g_subprocess_get_identifier (proc);
68 g_assert (id != NULL);
70 g_subprocess_wait_check (proc, NULL, error);
71 g_assert_no_error (local_error);
72 g_assert (g_subprocess_get_successful (proc));
74 g_object_unref (proc);
77 static void
78 check_ready (GObject *source,
79 GAsyncResult *res,
80 gpointer user_data)
82 gboolean ret;
83 GError *error = NULL;
85 ret = g_subprocess_wait_check_finish (G_SUBPROCESS (source),
86 res,
87 &error);
88 g_assert (ret);
89 g_assert_no_error (error);
91 g_object_unref (source);
94 static void
95 test_noop_all_to_null (void)
97 GError *local_error = NULL;
98 GError **error = &local_error;
99 GPtrArray *args;
100 GSubprocess *proc;
102 args = get_test_subprocess_args ("noop", NULL);
103 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
104 G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE,
105 error);
106 g_ptr_array_free (args, TRUE);
107 g_assert_no_error (local_error);
109 g_subprocess_wait_check_async (proc, NULL, check_ready, NULL);
112 static void
113 test_noop_no_wait (void)
115 GError *local_error = NULL;
116 GError **error = &local_error;
117 GPtrArray *args;
118 GSubprocess *proc;
120 args = get_test_subprocess_args ("noop", NULL);
121 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
122 g_ptr_array_free (args, TRUE);
123 g_assert_no_error (local_error);
125 g_object_unref (proc);
128 static void
129 test_noop_stdin_inherit (void)
131 GError *local_error = NULL;
132 GError **error = &local_error;
133 GPtrArray *args;
134 GSubprocess *proc;
136 args = get_test_subprocess_args ("noop", NULL);
137 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDIN_INHERIT, error);
138 g_ptr_array_free (args, TRUE);
139 g_assert_no_error (local_error);
141 g_subprocess_wait_check (proc, NULL, error);
142 g_assert_no_error (local_error);
144 g_object_unref (proc);
147 #ifdef G_OS_UNIX
148 static void
149 test_search_path (void)
151 GError *local_error = NULL;
152 GError **error = &local_error;
153 GSubprocess *proc;
155 proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, error, "true", NULL);
156 g_assert_no_error (local_error);
158 g_subprocess_wait_check (proc, NULL, error);
159 g_assert_no_error (local_error);
161 g_object_unref (proc);
163 #endif
165 static void
166 test_exit1 (void)
168 GError *local_error = NULL;
169 GError **error = &local_error;
170 GPtrArray *args;
171 GSubprocess *proc;
173 args = get_test_subprocess_args ("exit1", NULL);
174 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
175 g_ptr_array_free (args, TRUE);
176 g_assert_no_error (local_error);
178 g_subprocess_wait_check (proc, NULL, error);
179 g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
180 g_clear_error (error);
182 g_object_unref (proc);
185 typedef struct {
186 GMainLoop *loop;
187 GCancellable *cancellable;
188 gboolean cb_called;
189 } TestExit1CancelData;
191 static gboolean
192 test_exit1_cancel_idle_quit_cb (gpointer user_data)
194 GMainLoop *loop = user_data;
195 g_main_loop_quit (loop);
196 return G_SOURCE_REMOVE;
199 static void
200 test_exit1_cancel_wait_check_cb (GObject *source,
201 GAsyncResult *result,
202 gpointer user_data)
204 GSubprocess *subprocess = G_SUBPROCESS (source);
205 TestExit1CancelData *data = user_data;
206 gboolean ret;
207 GError *error = NULL;
209 g_assert_false (data->cb_called);
210 data->cb_called = TRUE;
212 ret = g_subprocess_wait_check_finish (subprocess, result, &error);
213 g_assert (!ret);
214 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
215 g_clear_error (&error);
217 g_idle_add (test_exit1_cancel_idle_quit_cb, data->loop);
220 static void
221 test_exit1_cancel (void)
223 GError *local_error = NULL;
224 GError **error = &local_error;
225 GPtrArray *args;
226 GSubprocess *proc;
227 TestExit1CancelData data = { 0 };
229 g_test_bug ("786456");
231 args = get_test_subprocess_args ("exit1", NULL);
232 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
233 g_ptr_array_free (args, TRUE);
234 g_assert_no_error (local_error);
236 data.loop = g_main_loop_new (NULL, FALSE);
237 data.cancellable = g_cancellable_new ();
238 g_subprocess_wait_check_async (proc, data.cancellable, test_exit1_cancel_wait_check_cb, &data);
240 g_subprocess_wait_check (proc, NULL, error);
241 g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
242 g_clear_error (error);
244 g_cancellable_cancel (data.cancellable);
245 g_main_loop_run (data.loop);
247 g_object_unref (proc);
248 g_main_loop_unref (data.loop);
249 g_clear_object (&data.cancellable);
252 static void
253 test_exit1_cancel_in_cb_wait_check_cb (GObject *source,
254 GAsyncResult *result,
255 gpointer user_data)
257 GSubprocess *subprocess = G_SUBPROCESS (source);
258 TestExit1CancelData *data = user_data;
259 gboolean ret;
260 GError *error = NULL;
262 g_assert_false (data->cb_called);
263 data->cb_called = TRUE;
265 ret = g_subprocess_wait_check_finish (subprocess, result, &error);
266 g_assert (!ret);
267 g_assert_error (error, G_SPAWN_EXIT_ERROR, 1);
268 g_clear_error (&error);
270 g_cancellable_cancel (data->cancellable);
272 g_idle_add (test_exit1_cancel_idle_quit_cb, data->loop);
275 static void
276 test_exit1_cancel_in_cb (void)
278 GError *local_error = NULL;
279 GError **error = &local_error;
280 GPtrArray *args;
281 GSubprocess *proc;
282 TestExit1CancelData data = { 0 };
284 g_test_bug ("786456");
286 args = get_test_subprocess_args ("exit1", NULL);
287 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
288 g_ptr_array_free (args, TRUE);
289 g_assert_no_error (local_error);
291 data.loop = g_main_loop_new (NULL, FALSE);
292 data.cancellable = g_cancellable_new ();
293 g_subprocess_wait_check_async (proc, data.cancellable, test_exit1_cancel_in_cb_wait_check_cb, &data);
295 g_subprocess_wait_check (proc, NULL, error);
296 g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
297 g_clear_error (error);
299 g_main_loop_run (data.loop);
301 g_object_unref (proc);
302 g_main_loop_unref (data.loop);
303 g_clear_object (&data.cancellable);
306 static gchar *
307 splice_to_string (GInputStream *stream,
308 GError **error)
310 GMemoryOutputStream *buffer = NULL;
311 char *ret = NULL;
313 buffer = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
314 if (g_output_stream_splice ((GOutputStream*)buffer, stream, 0, NULL, error) < 0)
315 goto out;
317 if (!g_output_stream_write ((GOutputStream*)buffer, "\0", 1, NULL, error))
318 goto out;
320 if (!g_output_stream_close ((GOutputStream*)buffer, NULL, error))
321 goto out;
323 ret = g_memory_output_stream_steal_data (buffer);
324 out:
325 g_clear_object (&buffer);
326 return ret;
329 static void
330 test_echo1 (void)
332 GError *local_error = NULL;
333 GError **error = &local_error;
334 GSubprocess *proc;
335 GPtrArray *args;
336 GInputStream *stdout_stream;
337 gchar *result;
339 args = get_test_subprocess_args ("echo", "hello", "world!", NULL);
340 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, error);
341 g_ptr_array_free (args, TRUE);
342 g_assert_no_error (local_error);
344 stdout_stream = g_subprocess_get_stdout_pipe (proc);
346 result = splice_to_string (stdout_stream, error);
347 g_assert_no_error (local_error);
349 g_assert_cmpstr (result, ==, "hello" LINEEND "world!" LINEEND);
351 g_free (result);
352 g_object_unref (proc);
355 #ifdef G_OS_UNIX
356 static void
357 test_echo_merged (void)
359 GError *local_error = NULL;
360 GError **error = &local_error;
361 GSubprocess *proc;
362 GPtrArray *args;
363 GInputStream *stdout_stream;
364 gchar *result;
366 args = get_test_subprocess_args ("echo-stdout-and-stderr", "merge", "this", NULL);
367 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
368 G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE,
369 error);
370 g_ptr_array_free (args, TRUE);
371 g_assert_no_error (local_error);
373 stdout_stream = g_subprocess_get_stdout_pipe (proc);
374 result = splice_to_string (stdout_stream, error);
375 g_assert_no_error (local_error);
377 g_assert_cmpstr (result, ==, "merge\nmerge\nthis\nthis\n");
379 g_free (result);
380 g_object_unref (proc);
382 #endif
384 typedef struct {
385 guint events_pending;
386 GMainLoop *loop;
387 } TestCatData;
389 static void
390 test_cat_on_input_splice_complete (GObject *object,
391 GAsyncResult *result,
392 gpointer user_data)
394 TestCatData *data = user_data;
395 GError *error = NULL;
397 (void)g_output_stream_splice_finish ((GOutputStream*)object, result, &error);
398 g_assert_no_error (error);
400 data->events_pending--;
401 if (data->events_pending == 0)
402 g_main_loop_quit (data->loop);
405 static void
406 test_cat_utf8 (void)
408 GError *local_error = NULL;
409 GError **error = &local_error;
410 GSubprocess *proc;
411 GPtrArray *args;
412 GBytes *input_buf;
413 GBytes *output_buf;
414 GInputStream *input_buf_stream = NULL;
415 GOutputStream *output_buf_stream = NULL;
416 GOutputStream *stdin_stream = NULL;
417 GInputStream *stdout_stream = NULL;
418 TestCatData data;
420 memset (&data, 0, sizeof (data));
421 data.loop = g_main_loop_new (NULL, TRUE);
423 args = get_test_subprocess_args ("cat", NULL);
424 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
425 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
426 error);
427 g_ptr_array_free (args, TRUE);
428 g_assert_no_error (local_error);
430 stdin_stream = g_subprocess_get_stdin_pipe (proc);
431 stdout_stream = g_subprocess_get_stdout_pipe (proc);
433 input_buf = g_bytes_new_static ("hello, world!", strlen ("hello, world!"));
434 input_buf_stream = g_memory_input_stream_new_from_bytes (input_buf);
435 g_bytes_unref (input_buf);
437 output_buf_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
439 g_output_stream_splice_async (stdin_stream, input_buf_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
440 G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete,
441 &data);
442 data.events_pending++;
443 g_output_stream_splice_async (output_buf_stream, stdout_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
444 G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete,
445 &data);
446 data.events_pending++;
448 g_main_loop_run (data.loop);
450 g_subprocess_wait_check (proc, NULL, error);
451 g_assert_no_error (local_error);
453 output_buf = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)output_buf_stream);
455 g_assert_cmpmem (g_bytes_get_data (output_buf, NULL),
456 g_bytes_get_size (output_buf),
457 "hello, world!", 13);
459 g_bytes_unref (output_buf);
460 g_main_loop_unref (data.loop);
461 g_object_unref (input_buf_stream);
462 g_object_unref (output_buf_stream);
463 g_object_unref (proc);
466 static gpointer
467 cancel_soon (gpointer user_data)
469 GCancellable *cancellable = user_data;
471 g_usleep (G_TIME_SPAN_SECOND);
472 g_cancellable_cancel (cancellable);
473 g_object_unref (cancellable);
475 return NULL;
478 static void
479 test_cat_eof (void)
481 GCancellable *cancellable;
482 GError *error = NULL;
483 GSubprocess *cat;
484 gboolean result;
485 gchar buffer;
486 gssize s;
488 #ifdef G_OS_WIN32
489 g_test_skip ("This test has not been ported to Win32");
490 return;
491 #endif
493 /* Spawn 'cat' */
494 cat = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "cat", NULL);
495 g_assert_no_error (error);
496 g_assert (cat);
498 /* Make sure that reading stdout blocks (until we cancel) */
499 cancellable = g_cancellable_new ();
500 g_thread_unref (g_thread_new ("cancel thread", cancel_soon, g_object_ref (cancellable)));
501 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, cancellable, &error);
502 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
503 g_assert_cmpint (s, ==, -1);
504 g_object_unref (cancellable);
505 g_clear_error (&error);
507 /* Close the stream (EOF on cat's stdin) */
508 result = g_output_stream_close (g_subprocess_get_stdin_pipe (cat), NULL, &error);
509 g_assert_no_error (error);
510 g_assert (result);
512 /* Now check that reading cat's stdout gets us an EOF (since it quit) */
513 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, NULL, &error);
514 g_assert_no_error (error);
515 g_assert (!s);
517 /* Check that the process has exited as a result of the EOF */
518 result = g_subprocess_wait (cat, NULL, &error);
519 g_assert_no_error (error);
520 g_assert (g_subprocess_get_if_exited (cat));
521 g_assert_cmpint (g_subprocess_get_exit_status (cat), ==, 0);
522 g_assert (result);
524 g_object_unref (cat);
527 typedef struct {
528 guint events_pending;
529 gboolean caught_error;
530 GError *error;
531 GMainLoop *loop;
533 gint counter;
534 GOutputStream *first_stdin;
535 } TestMultiSpliceData;
537 static void
538 on_one_multi_splice_done (GObject *obj,
539 GAsyncResult *res,
540 gpointer user_data)
542 TestMultiSpliceData *data = user_data;
544 if (!data->caught_error)
546 if (g_output_stream_splice_finish ((GOutputStream*)obj, res, &data->error) < 0)
547 data->caught_error = TRUE;
550 data->events_pending--;
551 if (data->events_pending == 0)
552 g_main_loop_quit (data->loop);
555 static gboolean
556 on_idle_multisplice (gpointer user_data)
558 TestMultiSpliceData *data = user_data;
560 /* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n"
561 * ultimately
563 if (data->counter >= 2047 || data->caught_error)
565 if (!g_output_stream_close (data->first_stdin, NULL, &data->error))
566 data->caught_error = TRUE;
567 data->events_pending--;
568 if (data->events_pending == 0)
570 g_main_loop_quit (data->loop);
572 return FALSE;
574 else
576 int i;
577 for (i = 0; i < data->counter; i++)
579 gsize bytes_written;
580 if (!g_output_stream_write_all (data->first_stdin, "hello world!\n",
581 strlen ("hello world!\n"), &bytes_written,
582 NULL, &data->error))
584 data->caught_error = TRUE;
585 return FALSE;
588 data->counter *= 2;
589 return TRUE;
593 static void
594 on_subprocess_exited (GObject *object,
595 GAsyncResult *result,
596 gpointer user_data)
598 GSubprocess *subprocess = G_SUBPROCESS (object);
599 TestMultiSpliceData *data = user_data;
600 GError *error = NULL;
602 if (!g_subprocess_wait_finish (subprocess, result, &error))
604 if (!data->caught_error)
606 data->caught_error = TRUE;
607 g_propagate_error (&data->error, error);
610 g_spawn_check_exit_status (g_subprocess_get_exit_status (subprocess), &error);
611 g_assert_no_error (error);
612 data->events_pending--;
613 if (data->events_pending == 0)
614 g_main_loop_quit (data->loop);
617 static void
618 test_multi_1 (void)
620 GError *local_error = NULL;
621 GError **error = &local_error;
622 GPtrArray *args;
623 GSubprocessLauncher *launcher;
624 GSubprocess *first;
625 GSubprocess *second;
626 GSubprocess *third;
627 GOutputStream *first_stdin;
628 GInputStream *first_stdout;
629 GOutputStream *second_stdin;
630 GInputStream *second_stdout;
631 GOutputStream *third_stdin;
632 GInputStream *third_stdout;
633 GOutputStream *membuf;
634 TestMultiSpliceData data;
635 int splice_flags = G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET;
637 args = get_test_subprocess_args ("cat", NULL);
638 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE);
639 first = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
640 g_assert_no_error (local_error);
641 second = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
642 g_assert_no_error (local_error);
643 third = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
644 g_assert_no_error (local_error);
646 g_ptr_array_free (args, TRUE);
648 membuf = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
650 first_stdin = g_subprocess_get_stdin_pipe (first);
651 first_stdout = g_subprocess_get_stdout_pipe (first);
652 second_stdin = g_subprocess_get_stdin_pipe (second);
653 second_stdout = g_subprocess_get_stdout_pipe (second);
654 third_stdin = g_subprocess_get_stdin_pipe (third);
655 third_stdout = g_subprocess_get_stdout_pipe (third);
657 memset (&data, 0, sizeof (data));
658 data.loop = g_main_loop_new (NULL, TRUE);
659 data.counter = 1;
660 data.first_stdin = first_stdin;
662 data.events_pending++;
663 g_output_stream_splice_async (second_stdin, first_stdout, splice_flags, G_PRIORITY_DEFAULT,
664 NULL, on_one_multi_splice_done, &data);
665 data.events_pending++;
666 g_output_stream_splice_async (third_stdin, second_stdout, splice_flags, G_PRIORITY_DEFAULT,
667 NULL, on_one_multi_splice_done, &data);
668 data.events_pending++;
669 g_output_stream_splice_async (membuf, third_stdout, splice_flags, G_PRIORITY_DEFAULT,
670 NULL, on_one_multi_splice_done, &data);
672 data.events_pending++;
673 g_timeout_add (250, on_idle_multisplice, &data);
675 data.events_pending++;
676 g_subprocess_wait_async (first, NULL, on_subprocess_exited, &data);
677 data.events_pending++;
678 g_subprocess_wait_async (second, NULL, on_subprocess_exited, &data);
679 data.events_pending++;
680 g_subprocess_wait_async (third, NULL, on_subprocess_exited, &data);
682 g_main_loop_run (data.loop);
684 g_assert (!data.caught_error);
685 g_assert_no_error (data.error);
687 g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, 26611);
689 g_main_loop_unref (data.loop);
690 g_object_unref (membuf);
691 g_object_unref (launcher);
692 g_object_unref (first);
693 g_object_unref (second);
694 g_object_unref (third);
697 typedef struct {
698 GSubprocessFlags flags;
699 gboolean is_utf8;
700 gboolean running;
701 GError *error;
702 } TestAsyncCommunicateData;
704 static void
705 on_communicate_complete (GObject *proc,
706 GAsyncResult *result,
707 gpointer user_data)
709 TestAsyncCommunicateData *data = user_data;
710 GBytes *stdout_bytes = NULL, *stderr_bytes = NULL;
711 char *stdout_str = NULL, *stderr_str = NULL;
712 const guint8 *stdout_data;
713 gsize stdout_len;
715 data->running = FALSE;
716 if (data->is_utf8)
717 (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result,
718 &stdout_str, &stderr_str, &data->error);
719 else
720 (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result,
721 &stdout_bytes, &stderr_bytes, &data->error);
722 if (data->error)
723 return;
725 if (data->flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE)
727 if (data->is_utf8)
729 stdout_data = (guint8*)stdout_str;
730 stdout_len = strlen (stdout_str);
732 else
733 stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len);
735 g_assert_cmpmem (stdout_data, stdout_len, "# hello world\n", 14);
737 else
739 g_assert_null (stdout_str);
740 g_assert_null (stdout_bytes);
743 if (data->flags & G_SUBPROCESS_FLAGS_STDERR_PIPE)
745 if (data->is_utf8)
746 g_assert_nonnull (stderr_str);
747 else
748 g_assert_nonnull (stderr_bytes);
750 else
752 g_assert_null (stderr_str);
753 g_assert_null (stderr_bytes);
756 g_clear_pointer (&stdout_bytes, g_bytes_unref);
757 g_clear_pointer (&stderr_bytes, g_bytes_unref);
758 g_free (stdout_str);
759 g_free (stderr_str);
762 /* Test g_subprocess_communicate_async() works correctly with a variety of flags,
763 * as passed in via @test_data. */
764 static void
765 test_communicate_async (gconstpointer test_data)
767 GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
768 GError *error = NULL;
769 GPtrArray *args;
770 TestAsyncCommunicateData data = { flags, 0, };
771 GSubprocess *proc;
772 GCancellable *cancellable = NULL;
773 GBytes *input;
774 const char *hellostring;
776 args = get_test_subprocess_args ("cat", NULL);
777 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
778 G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
779 &error);
780 g_assert_no_error (error);
781 g_ptr_array_free (args, TRUE);
783 /* Include a leading hash and trailing newline so that if this gets onto the
784 * test’s stdout, it doesn’t mess up TAP output. */
785 hellostring = "# hello world\n";
786 input = g_bytes_new_static (hellostring, strlen (hellostring));
788 g_subprocess_communicate_async (proc, input,
789 cancellable,
790 on_communicate_complete,
791 &data);
793 data.running = TRUE;
794 while (data.running)
795 g_main_context_iteration (NULL, TRUE);
797 g_assert_no_error (data.error);
799 g_bytes_unref (input);
800 g_object_unref (proc);
803 /* Test g_subprocess_communicate() works correctly with a variety of flags,
804 * as passed in via @test_data. */
805 static void
806 test_communicate (gconstpointer test_data)
808 GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
809 GError *error = NULL;
810 GPtrArray *args;
811 GSubprocess *proc;
812 GCancellable *cancellable = NULL;
813 GBytes *input;
814 const gchar *hellostring;
815 GBytes *stdout_bytes, *stderr_bytes;
816 const gchar *stdout_data;
817 gsize stdout_len;
819 args = get_test_subprocess_args ("cat", NULL);
820 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
821 G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
822 &error);
823 g_assert_no_error (error);
824 g_ptr_array_free (args, TRUE);
826 /* Include a leading hash and trailing newline so that if this gets onto the
827 * test’s stdout, it doesn’t mess up TAP output. */
828 hellostring = "# hello world\n";
829 input = g_bytes_new_static (hellostring, strlen (hellostring));
831 g_subprocess_communicate (proc, input, cancellable, &stdout_bytes, &stderr_bytes, &error);
832 g_assert_no_error (error);
834 if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE)
836 stdout_data = g_bytes_get_data (stdout_bytes, &stdout_len);
837 g_assert_cmpmem (stdout_data, stdout_len, "# hello world\n", 14);
839 else
840 g_assert_null (stdout_bytes);
841 if (flags & G_SUBPROCESS_FLAGS_STDERR_PIPE)
842 g_assert_nonnull (stderr_bytes);
843 else
844 g_assert_null (stderr_bytes);
846 g_bytes_unref (input);
847 g_clear_pointer (&stdout_bytes, g_bytes_unref);
848 g_clear_pointer (&stderr_bytes, g_bytes_unref);
849 g_object_unref (proc);
852 /* Test g_subprocess_communicate_utf8_async() works correctly with a variety of
853 * flags, as passed in via @test_data. */
854 static void
855 test_communicate_utf8_async (gconstpointer test_data)
857 GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
858 GError *error = NULL;
859 GPtrArray *args;
860 TestAsyncCommunicateData data = { flags, 0, };
861 GSubprocess *proc;
862 GCancellable *cancellable = NULL;
864 args = get_test_subprocess_args ("cat", NULL);
865 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
866 G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
867 &error);
868 g_assert_no_error (error);
869 g_ptr_array_free (args, TRUE);
871 data.is_utf8 = TRUE;
872 g_subprocess_communicate_utf8_async (proc, "# hello world\n",
873 cancellable,
874 on_communicate_complete,
875 &data);
877 data.running = TRUE;
878 while (data.running)
879 g_main_context_iteration (NULL, TRUE);
881 g_assert_no_error (data.error);
883 g_object_unref (proc);
886 /* Test g_subprocess_communicate_utf8() works correctly with a variety of flags,
887 * as passed in via @test_data. */
888 static void
889 test_communicate_utf8 (gconstpointer test_data)
891 GSubprocessFlags flags = GPOINTER_TO_INT (test_data);
892 GError *error = NULL;
893 GPtrArray *args;
894 GSubprocess *proc;
895 GCancellable *cancellable = NULL;
896 const gchar *stdin_buf;
897 gchar *stdout_buf, *stderr_buf;
899 args = get_test_subprocess_args ("cat", NULL);
900 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
901 G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
902 &error);
903 g_assert_no_error (error);
904 g_ptr_array_free (args, TRUE);
906 /* Include a leading hash and trailing newline so that if this gets onto the
907 * test’s stdout, it doesn’t mess up TAP output. */
908 stdin_buf = "# hello world\n";
910 g_subprocess_communicate_utf8 (proc, stdin_buf, cancellable, &stdout_buf, &stderr_buf, &error);
911 g_assert_no_error (error);
913 if (flags & G_SUBPROCESS_FLAGS_STDOUT_PIPE)
914 g_assert_cmpstr (stdout_buf, ==, "# hello world\n");
915 else
916 g_assert_null (stdout_buf);
917 if (flags & G_SUBPROCESS_FLAGS_STDERR_PIPE)
918 g_assert_nonnull (stderr_buf);
919 else g_assert_null (stderr_buf);
921 g_free (stdout_buf);
922 g_free (stderr_buf);
923 g_object_unref (proc);
926 static void
927 test_communicate_nothing (void)
929 GError *error = NULL;
930 GPtrArray *args;
931 GSubprocess *proc;
932 GCancellable *cancellable = NULL;
933 gchar *stdout_buf;
935 args = get_test_subprocess_args ("cat", NULL);
936 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
937 G_SUBPROCESS_FLAGS_STDIN_PIPE
938 | G_SUBPROCESS_FLAGS_STDOUT_PIPE
939 | G_SUBPROCESS_FLAGS_STDERR_MERGE,
940 &error);
941 g_assert_no_error (error);
942 g_ptr_array_free (args, TRUE);
944 g_subprocess_communicate_utf8 (proc, "", cancellable, &stdout_buf, NULL, &error);
945 g_assert_no_error (error);
947 g_assert_cmpstr (stdout_buf, ==, "");
949 g_free (stdout_buf);
951 g_object_unref (proc);
954 static void
955 test_communicate_utf8_invalid (void)
957 GSubprocessFlags flags = G_SUBPROCESS_FLAGS_STDOUT_PIPE;
958 GError *error = NULL;
959 GPtrArray *args;
960 TestAsyncCommunicateData data = { flags, 0, };
961 GSubprocess *proc;
962 GCancellable *cancellable = NULL;
964 args = get_test_subprocess_args ("cat", NULL);
965 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
966 G_SUBPROCESS_FLAGS_STDIN_PIPE | flags,
967 &error);
968 g_assert_no_error (error);
969 g_ptr_array_free (args, TRUE);
971 data.is_utf8 = TRUE;
972 g_subprocess_communicate_utf8_async (proc, "\xFF\xFF",
973 cancellable,
974 on_communicate_complete,
975 &data);
977 data.running = TRUE;
978 while (data.running)
979 g_main_context_iteration (NULL, TRUE);
981 g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_FAILED);
982 g_error_free (data.error);
984 g_object_unref (proc);
987 static gboolean
988 send_terminate (gpointer user_data)
990 GSubprocess *proc = user_data;
992 g_subprocess_force_exit (proc);
994 return FALSE;
997 static void
998 on_request_quit_exited (GObject *object,
999 GAsyncResult *result,
1000 gpointer user_data)
1002 GSubprocess *subprocess = G_SUBPROCESS (object);
1003 GError *error = NULL;
1005 g_subprocess_wait_finish (subprocess, result, &error);
1006 g_assert_no_error (error);
1007 #ifdef G_OS_UNIX
1008 g_assert (g_subprocess_get_if_signaled (subprocess));
1009 g_assert (g_subprocess_get_term_sig (subprocess) == 9);
1010 #endif
1011 g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
1012 g_assert (error != NULL);
1013 g_clear_error (&error);
1015 g_main_loop_quit ((GMainLoop*)user_data);
1018 static void
1019 test_terminate (void)
1021 GError *local_error = NULL;
1022 GError **error = &local_error;
1023 GSubprocess *proc;
1024 GPtrArray *args;
1025 GMainLoop *loop;
1027 args = get_test_subprocess_args ("sleep-forever", NULL);
1028 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
1029 g_ptr_array_free (args, TRUE);
1030 g_assert_no_error (local_error);
1032 loop = g_main_loop_new (NULL, TRUE);
1034 g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
1036 g_timeout_add_seconds (3, send_terminate, proc);
1038 g_main_loop_run (loop);
1040 g_main_loop_unref (loop);
1041 g_object_unref (proc);
1044 #ifdef G_OS_UNIX
1045 static gboolean
1046 send_signal (gpointer user_data)
1048 GSubprocess *proc = user_data;
1050 g_subprocess_send_signal (proc, SIGKILL);
1052 return FALSE;
1055 static void
1056 test_signal (void)
1058 GError *local_error = NULL;
1059 GError **error = &local_error;
1060 GSubprocess *proc;
1061 GPtrArray *args;
1062 GMainLoop *loop;
1064 args = get_test_subprocess_args ("sleep-forever", NULL);
1065 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
1066 g_ptr_array_free (args, TRUE);
1067 g_assert_no_error (local_error);
1069 loop = g_main_loop_new (NULL, TRUE);
1071 g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
1073 g_timeout_add_seconds (3, send_signal, proc);
1075 g_main_loop_run (loop);
1077 g_main_loop_unref (loop);
1078 g_object_unref (proc);
1080 #endif
1082 static void
1083 test_env (void)
1085 GError *local_error = NULL;
1086 GError **error = &local_error;
1087 GSubprocessLauncher *launcher;
1088 GSubprocess *proc;
1089 GPtrArray *args;
1090 GInputStream *stdout_stream;
1091 gchar *result;
1092 gchar *envp[] = { "ONE=1", "TWO=1", "THREE=3", "FOUR=1", NULL };
1093 gchar **split;
1095 args = get_test_subprocess_args ("env", NULL);
1096 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
1097 g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE);
1098 g_subprocess_launcher_set_environ (launcher, envp);
1099 g_subprocess_launcher_setenv (launcher, "TWO", "2", TRUE);
1100 g_subprocess_launcher_setenv (launcher, "THREE", "1", FALSE);
1101 g_subprocess_launcher_unsetenv (launcher, "FOUR");
1103 g_assert_null (g_subprocess_launcher_getenv (launcher, "FOUR"));
1105 proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL);
1106 g_ptr_array_free (args, TRUE);
1107 g_assert_no_error (local_error);
1109 stdout_stream = g_subprocess_get_stdout_pipe (proc);
1111 result = splice_to_string (stdout_stream, error);
1112 split = g_strsplit (result, "\n", -1);
1113 g_assert_cmpstr (g_environ_getenv (split, "ONE"), ==, "1");
1114 g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2");
1115 g_assert_cmpstr (g_environ_getenv (split, "THREE"), ==, "3");
1116 g_assert_null (g_environ_getenv (split, "FOUR"));
1118 g_strfreev (split);
1119 g_free (result);
1120 g_object_unref (proc);
1121 g_object_unref (launcher);
1124 /* Test that explicitly inheriting and modifying the parent process’
1125 * environment works. */
1126 static void
1127 test_env_inherit (void)
1129 GError *local_error = NULL;
1130 GError **error = &local_error;
1131 GSubprocessLauncher *launcher;
1132 GSubprocess *proc;
1133 GPtrArray *args;
1134 GInputStream *stdout_stream;
1135 gchar *result;
1136 gchar **split;
1138 g_setenv ("TEST_ENV_INHERIT1", "1", TRUE);
1139 g_setenv ("TEST_ENV_INHERIT2", "2", TRUE);
1141 args = get_test_subprocess_args ("env", NULL);
1142 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
1143 g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE);
1144 g_subprocess_launcher_set_environ (launcher, NULL);
1145 g_subprocess_launcher_setenv (launcher, "TWO", "2", TRUE);
1146 g_subprocess_launcher_unsetenv (launcher, "TEST_ENV_INHERIT1");
1148 g_assert_null (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT1"));
1149 g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TEST_ENV_INHERIT2"), ==, "2");
1150 g_assert_cmpstr (g_subprocess_launcher_getenv (launcher, "TWO"), ==, "2");
1152 proc = g_subprocess_launcher_spawn (launcher, error, args->pdata[0], "env", NULL);
1153 g_ptr_array_free (args, TRUE);
1154 g_assert_no_error (local_error);
1156 stdout_stream = g_subprocess_get_stdout_pipe (proc);
1158 result = splice_to_string (stdout_stream, error);
1159 split = g_strsplit (result, "\n", -1);
1160 g_assert_null (g_environ_getenv (split, "TEST_ENV_INHERIT1"));
1161 g_assert_cmpstr (g_environ_getenv (split, "TEST_ENV_INHERIT2"), ==, "2");
1162 g_assert_cmpstr (g_environ_getenv (split, "TWO"), ==, "2");
1164 g_strfreev (split);
1165 g_free (result);
1166 g_object_unref (proc);
1167 g_object_unref (launcher);
1170 static void
1171 test_cwd (void)
1173 GError *local_error = NULL;
1174 GError **error = &local_error;
1175 GSubprocessLauncher *launcher;
1176 GSubprocess *proc;
1177 GPtrArray *args;
1178 GInputStream *stdout_stream;
1179 gchar *result;
1180 const char *basename;
1182 args = get_test_subprocess_args ("cwd", NULL);
1183 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
1184 g_subprocess_launcher_set_flags (launcher, G_SUBPROCESS_FLAGS_STDOUT_PIPE);
1185 g_subprocess_launcher_set_cwd (launcher, "/tmp");
1187 proc = g_subprocess_launcher_spawnv (launcher, (const char * const *)args->pdata, error);
1188 g_ptr_array_free (args, TRUE);
1189 g_assert_no_error (local_error);
1191 stdout_stream = g_subprocess_get_stdout_pipe (proc);
1193 result = splice_to_string (stdout_stream, error);
1195 basename = g_strrstr (result, "/");
1196 g_assert (basename != NULL);
1197 g_assert_cmpstr (basename, ==, "/tmp" LINEEND);
1199 g_free (result);
1200 g_object_unref (proc);
1201 g_object_unref (launcher);
1203 #ifdef G_OS_UNIX
1204 static void
1205 test_stdout_file (void)
1207 GError *local_error = NULL;
1208 GError **error = &local_error;
1209 GSubprocessLauncher *launcher;
1210 GSubprocess *proc;
1211 GPtrArray *args;
1212 GFile *tmpfile;
1213 GFileIOStream *iostream;
1214 GOutputStream *stdin_stream;
1215 const char *test_data = "this is some test data\n";
1216 char *tmp_contents;
1217 char *tmp_file_path;
1219 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
1220 g_assert_no_error (local_error);
1221 g_clear_object (&iostream);
1223 tmp_file_path = g_file_get_path (tmpfile);
1225 args = get_test_subprocess_args ("cat", NULL);
1226 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
1227 g_subprocess_launcher_set_stdout_file_path (launcher, tmp_file_path);
1228 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
1229 g_ptr_array_free (args, TRUE);
1230 g_assert_no_error (local_error);
1232 stdin_stream = g_subprocess_get_stdin_pipe (proc);
1234 g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error);
1235 g_assert_no_error (local_error);
1237 g_output_stream_close (stdin_stream, NULL, error);
1238 g_assert_no_error (local_error);
1240 g_subprocess_wait_check (proc, NULL, error);
1242 g_object_unref (launcher);
1243 g_object_unref (proc);
1245 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
1246 g_assert_no_error (local_error);
1248 g_assert_cmpstr (test_data, ==, tmp_contents);
1249 g_free (tmp_contents);
1251 (void) g_file_delete (tmpfile, NULL, NULL);
1252 g_object_unref (tmpfile);
1253 g_free (tmp_file_path);
1256 static void
1257 test_stdout_fd (void)
1259 GError *local_error = NULL;
1260 GError **error = &local_error;
1261 GSubprocessLauncher *launcher;
1262 GSubprocess *proc;
1263 GPtrArray *args;
1264 GFile *tmpfile;
1265 GFileIOStream *iostream;
1266 GFileDescriptorBased *descriptor_stream;
1267 GOutputStream *stdin_stream;
1268 const char *test_data = "this is some test data\n";
1269 char *tmp_contents;
1271 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
1272 g_assert_no_error (local_error);
1274 args = get_test_subprocess_args ("cat", NULL);
1275 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
1276 descriptor_stream = G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream)));
1277 g_subprocess_launcher_take_stdout_fd (launcher, dup (g_file_descriptor_based_get_fd (descriptor_stream)));
1278 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
1279 g_ptr_array_free (args, TRUE);
1280 g_assert_no_error (local_error);
1282 g_clear_object (&iostream);
1284 stdin_stream = g_subprocess_get_stdin_pipe (proc);
1286 g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error);
1287 g_assert_no_error (local_error);
1289 g_output_stream_close (stdin_stream, NULL, error);
1290 g_assert_no_error (local_error);
1292 g_subprocess_wait_check (proc, NULL, error);
1294 g_object_unref (launcher);
1295 g_object_unref (proc);
1297 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
1298 g_assert_no_error (local_error);
1300 g_assert_cmpstr (test_data, ==, tmp_contents);
1301 g_free (tmp_contents);
1303 (void) g_file_delete (tmpfile, NULL, NULL);
1304 g_object_unref (tmpfile);
1307 static void
1308 child_setup (gpointer user_data)
1310 dup2 (GPOINTER_TO_INT (user_data), 1);
1313 static void
1314 test_child_setup (void)
1316 GError *local_error = NULL;
1317 GError **error = &local_error;
1318 GSubprocessLauncher *launcher;
1319 GSubprocess *proc;
1320 GPtrArray *args;
1321 GFile *tmpfile;
1322 GFileIOStream *iostream;
1323 GOutputStream *stdin_stream;
1324 const char *test_data = "this is some test data\n";
1325 char *tmp_contents;
1326 int fd;
1328 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
1329 g_assert_no_error (local_error);
1331 fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream))));
1333 args = get_test_subprocess_args ("cat", NULL);
1334 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
1335 g_subprocess_launcher_set_child_setup (launcher, child_setup, GINT_TO_POINTER (fd), NULL);
1336 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
1337 g_ptr_array_free (args, TRUE);
1338 g_assert_no_error (local_error);
1340 g_clear_object (&iostream);
1342 stdin_stream = g_subprocess_get_stdin_pipe (proc);
1344 g_output_stream_write_all (stdin_stream, test_data, strlen (test_data), NULL, NULL, error);
1345 g_assert_no_error (local_error);
1347 g_output_stream_close (stdin_stream, NULL, error);
1348 g_assert_no_error (local_error);
1350 g_subprocess_wait_check (proc, NULL, error);
1352 g_object_unref (launcher);
1353 g_object_unref (proc);
1355 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
1356 g_assert_no_error (local_error);
1358 g_assert_cmpstr (test_data, ==, tmp_contents);
1359 g_free (tmp_contents);
1361 (void) g_file_delete (tmpfile, NULL, NULL);
1362 g_object_unref (tmpfile);
1365 static void
1366 test_pass_fd (void)
1368 GError *local_error = NULL;
1369 GError **error = &local_error;
1370 GInputStream *child_input;
1371 GDataInputStream *child_datainput;
1372 GSubprocessLauncher *launcher;
1373 GSubprocess *proc;
1374 GPtrArray *args;
1375 int basic_pipefds[2];
1376 int needdup_pipefds[2];
1377 char *buf;
1378 gsize len;
1379 char *basic_fd_str;
1380 char *needdup_fd_str;
1382 g_unix_open_pipe (basic_pipefds, FD_CLOEXEC, error);
1383 g_assert_no_error (local_error);
1384 g_unix_open_pipe (needdup_pipefds, FD_CLOEXEC, error);
1385 g_assert_no_error (local_error);
1387 basic_fd_str = g_strdup_printf ("%d", basic_pipefds[1]);
1388 needdup_fd_str = g_strdup_printf ("%d", needdup_pipefds[1] + 1);
1390 args = get_test_subprocess_args ("write-to-fds", basic_fd_str, needdup_fd_str, NULL);
1391 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
1392 g_subprocess_launcher_take_fd (launcher, basic_pipefds[1], basic_pipefds[1]);
1393 g_subprocess_launcher_take_fd (launcher, needdup_pipefds[1], needdup_pipefds[1] + 1);
1394 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
1395 g_ptr_array_free (args, TRUE);
1396 g_assert_no_error (local_error);
1398 g_free (basic_fd_str);
1399 g_free (needdup_fd_str);
1401 child_input = g_unix_input_stream_new (basic_pipefds[0], TRUE);
1402 child_datainput = g_data_input_stream_new (child_input);
1403 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
1404 g_assert_no_error (local_error);
1405 g_assert_cmpstr (buf, ==, "hello world");
1406 g_object_unref (child_datainput);
1407 g_object_unref (child_input);
1408 g_free (buf);
1410 child_input = g_unix_input_stream_new (needdup_pipefds[0], TRUE);
1411 child_datainput = g_data_input_stream_new (child_input);
1412 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
1413 g_assert_no_error (local_error);
1414 g_assert_cmpstr (buf, ==, "hello world");
1415 g_free (buf);
1416 g_object_unref (child_datainput);
1417 g_object_unref (child_input);
1419 g_object_unref (launcher);
1420 g_object_unref (proc);
1423 #endif
1425 static void
1426 test_launcher_environment (void)
1428 GSubprocessLauncher *launcher;
1429 GError *error = NULL;
1430 GSubprocess *proc;
1431 GPtrArray *args;
1432 gchar *out;
1434 g_setenv ("A", "B", TRUE);
1435 g_setenv ("C", "D", TRUE);
1437 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDOUT_PIPE);
1439 /* unset a variable */
1440 g_subprocess_launcher_unsetenv (launcher, "A");
1442 /* and set a diffferent one */
1443 g_subprocess_launcher_setenv (launcher, "E", "F", TRUE);
1445 args = get_test_subprocess_args ("printenv", "A", "C", "E", NULL);
1446 proc = g_subprocess_launcher_spawnv (launcher, (const gchar **) args->pdata, &error);
1447 g_assert_no_error (error);
1448 g_assert (proc);
1450 g_subprocess_communicate_utf8 (proc, NULL, NULL, &out, NULL, &error);
1451 g_assert_no_error (error);
1453 g_assert_cmpstr (out, ==, "C=D\nE=F\n");
1454 g_free (out);
1456 g_object_unref (proc);
1457 g_object_unref (launcher);
1458 g_ptr_array_unref (args);
1462 main (int argc, char **argv)
1464 const struct
1466 const gchar *subtest;
1467 GSubprocessFlags flags;
1469 flags_vectors[] =
1471 { "", G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE },
1472 { "/no-pipes", G_SUBPROCESS_FLAGS_NONE },
1473 { "/separate-stderr", G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE },
1474 { "/stdout-only", G_SUBPROCESS_FLAGS_STDOUT_PIPE },
1475 { "/stderr-only", G_SUBPROCESS_FLAGS_STDERR_PIPE },
1476 { "/stdout-silence", G_SUBPROCESS_FLAGS_STDOUT_SILENCE },
1478 gsize i;
1480 g_test_init (&argc, &argv, NULL);
1481 g_test_bug_base ("https://bugzilla.gnome.org/");
1483 g_test_add_func ("/gsubprocess/noop", test_noop);
1484 g_test_add_func ("/gsubprocess/noop-all-to-null", test_noop_all_to_null);
1485 g_test_add_func ("/gsubprocess/noop-no-wait", test_noop_no_wait);
1486 g_test_add_func ("/gsubprocess/noop-stdin-inherit", test_noop_stdin_inherit);
1487 #ifdef G_OS_UNIX
1488 g_test_add_func ("/gsubprocess/search-path", test_search_path);
1489 g_test_add_func ("/gsubprocess/signal", test_signal);
1490 #endif
1491 g_test_add_func ("/gsubprocess/exit1", test_exit1);
1492 g_test_add_func ("/gsubprocess/exit1/cancel", test_exit1_cancel);
1493 g_test_add_func ("/gsubprocess/exit1/cancel_in_cb", test_exit1_cancel_in_cb);
1494 g_test_add_func ("/gsubprocess/echo1", test_echo1);
1495 #ifdef G_OS_UNIX
1496 g_test_add_func ("/gsubprocess/echo-merged", test_echo_merged);
1497 #endif
1498 g_test_add_func ("/gsubprocess/cat-utf8", test_cat_utf8);
1499 g_test_add_func ("/gsubprocess/cat-eof", test_cat_eof);
1500 g_test_add_func ("/gsubprocess/multi1", test_multi_1);
1502 /* Add various tests for g_subprocess_communicate() with different flags. */
1503 for (i = 0; i < G_N_ELEMENTS (flags_vectors); i++)
1505 gchar *test_path = NULL;
1507 test_path = g_strdup_printf ("/gsubprocess/communicate%s", flags_vectors[i].subtest);
1508 g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
1509 test_communicate);
1510 g_free (test_path);
1512 test_path = g_strdup_printf ("/gsubprocess/communicate/async%s", flags_vectors[i].subtest);
1513 g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
1514 test_communicate_async);
1515 g_free (test_path);
1517 test_path = g_strdup_printf ("/gsubprocess/communicate/utf8%s", flags_vectors[i].subtest);
1518 g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
1519 test_communicate_utf8);
1520 g_free (test_path);
1522 test_path = g_strdup_printf ("/gsubprocess/communicate/utf8/async%s", flags_vectors[i].subtest);
1523 g_test_add_data_func (test_path, GINT_TO_POINTER (flags_vectors[i].flags),
1524 test_communicate_utf8_async);
1525 g_free (test_path);
1528 g_test_add_func ("/gsubprocess/communicate/utf8/invalid", test_communicate_utf8_invalid);
1529 g_test_add_func ("/gsubprocess/communicate/nothing", test_communicate_nothing);
1530 g_test_add_func ("/gsubprocess/terminate", test_terminate);
1531 g_test_add_func ("/gsubprocess/env", test_env);
1532 g_test_add_func ("/gsubprocess/env/inherit", test_env_inherit);
1533 g_test_add_func ("/gsubprocess/cwd", test_cwd);
1534 #ifdef G_OS_UNIX
1535 g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file);
1536 g_test_add_func ("/gsubprocess/stdout-fd", test_stdout_fd);
1537 g_test_add_func ("/gsubprocess/child-setup", test_child_setup);
1538 g_test_add_func ("/gsubprocess/pass-fd", test_pass_fd);
1539 #endif
1540 g_test_add_func ("/gsubprocess/launcher-environment", test_launcher_environment);
1542 return g_test_run ();