7 #include <gio/gunixinputstream.h>
8 #include <gio/gfiledescriptorbased.h>
12 get_test_subprocess_args (const char *mode,
13 ...) G_GNUC_NULL_TERMINATED;
16 get_test_subprocess_args (const char *mode,
25 ret = g_ptr_array_new_with_free_func (g_free);
28 binname = "gsubprocess-testprog.exe";
30 binname = "gsubprocess-testprog";
33 path = g_test_build_filename (G_TEST_BUILT, binname, NULL);
34 g_ptr_array_add (ret, path);
35 g_ptr_array_add (ret, g_strdup (mode));
37 va_start (args, mode);
38 while ((arg = va_arg (args, gpointer)) != NULL)
39 g_ptr_array_add (ret, g_strdup (arg));
42 g_ptr_array_add (ret, NULL);
49 GError *local_error = NULL;
50 GError **error = &local_error;
54 args = get_test_subprocess_args ("noop", NULL);
55 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
56 g_ptr_array_free (args, TRUE);
57 g_assert_no_error (local_error);
59 g_subprocess_wait_check (proc, NULL, error);
60 g_assert_no_error (local_error);
62 g_object_unref (proc);
66 test_noop_all_to_null (void)
68 GError *local_error = NULL;
69 GError **error = &local_error;
73 args = get_test_subprocess_args ("noop", NULL);
74 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
75 G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE,
77 g_ptr_array_free (args, TRUE);
78 g_assert_no_error (local_error);
80 g_subprocess_wait_check (proc, NULL, error);
81 g_assert_no_error (local_error);
83 g_object_unref (proc);
87 test_noop_no_wait (void)
89 GError *local_error = NULL;
90 GError **error = &local_error;
94 args = get_test_subprocess_args ("noop", NULL);
95 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
96 g_ptr_array_free (args, TRUE);
97 g_assert_no_error (local_error);
99 g_object_unref (proc);
103 test_noop_stdin_inherit (void)
105 GError *local_error = NULL;
106 GError **error = &local_error;
110 args = get_test_subprocess_args ("noop", NULL);
111 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDIN_INHERIT, error);
112 g_ptr_array_free (args, TRUE);
113 g_assert_no_error (local_error);
115 g_subprocess_wait_check (proc, NULL, error);
116 g_assert_no_error (local_error);
118 g_object_unref (proc);
123 test_search_path (void)
125 GError *local_error = NULL;
126 GError **error = &local_error;
129 proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, error, "true", NULL);
130 g_assert_no_error (local_error);
132 g_subprocess_wait_check (proc, NULL, error);
133 g_assert_no_error (local_error);
135 g_object_unref (proc);
142 GError *local_error = NULL;
143 GError **error = &local_error;
147 args = get_test_subprocess_args ("exit1", NULL);
148 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
149 g_ptr_array_free (args, TRUE);
150 g_assert_no_error (local_error);
152 g_subprocess_wait_check (proc, NULL, error);
153 g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
154 g_clear_error (error);
156 g_object_unref (proc);
160 splice_to_string (GInputStream *stream,
163 GMemoryOutputStream *buffer = NULL;
166 buffer = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
167 if (g_output_stream_splice ((GOutputStream*)buffer, stream, 0, NULL, error) < 0)
170 if (!g_output_stream_write ((GOutputStream*)buffer, "\0", 1, NULL, error))
173 if (!g_output_stream_close ((GOutputStream*)buffer, NULL, error))
176 ret = g_memory_output_stream_steal_data (buffer);
178 g_clear_object (&buffer);
185 GError *local_error = NULL;
186 GError **error = &local_error;
189 GInputStream *stdout;
192 args = get_test_subprocess_args ("echo", "hello", "world!", NULL);
193 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, error);
194 g_ptr_array_free (args, TRUE);
195 g_assert_no_error (local_error);
197 stdout = g_subprocess_get_stdout_pipe (proc);
199 result = splice_to_string (stdout, error);
200 g_assert_no_error (local_error);
202 g_assert_cmpstr (result, ==, "hello\nworld!\n");
205 g_object_unref (proc);
210 test_echo_merged (void)
212 GError *local_error = NULL;
213 GError **error = &local_error;
216 GInputStream *stdout;
219 args = get_test_subprocess_args ("echo-stdout-and-stderr", "merge", "this", NULL);
220 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
221 G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE,
223 g_ptr_array_free (args, TRUE);
224 g_assert_no_error (local_error);
226 stdout = g_subprocess_get_stdout_pipe (proc);
227 result = splice_to_string (stdout, error);
228 g_assert_no_error (local_error);
230 g_assert_cmpstr (result, ==, "merge\nmerge\nthis\nthis\n");
233 g_object_unref (proc);
238 guint events_pending;
243 test_cat_on_input_splice_complete (GObject *object,
244 GAsyncResult *result,
247 TestCatData *data = user_data;
248 GError *error = NULL;
250 (void)g_output_stream_splice_finish ((GOutputStream*)object, result, &error);
251 g_assert_no_error (error);
253 data->events_pending--;
254 if (data->events_pending == 0)
255 g_main_loop_quit (data->loop);
261 GError *local_error = NULL;
262 GError **error = &local_error;
267 GInputStream *input_buf_stream = NULL;
268 GOutputStream *output_buf_stream = NULL;
269 GOutputStream *stdin_stream = NULL;
270 GInputStream *stdout_stream = NULL;
273 memset (&data, 0, sizeof (data));
274 data.loop = g_main_loop_new (NULL, TRUE);
276 args = get_test_subprocess_args ("cat", NULL);
277 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
278 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
280 g_ptr_array_free (args, TRUE);
281 g_assert_no_error (local_error);
283 stdin_stream = g_subprocess_get_stdin_pipe (proc);
284 stdout_stream = g_subprocess_get_stdout_pipe (proc);
286 input_buf = g_bytes_new_static ("hello, world!", strlen ("hello, world!"));
287 input_buf_stream = g_memory_input_stream_new_from_bytes (input_buf);
288 g_bytes_unref (input_buf);
290 output_buf_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
292 g_output_stream_splice_async (stdin_stream, input_buf_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
293 G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete,
295 data.events_pending++;
296 g_output_stream_splice_async (output_buf_stream, stdout_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
297 G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete,
299 data.events_pending++;
301 g_main_loop_run (data.loop);
303 g_subprocess_wait_check (proc, NULL, error);
304 g_assert_no_error (local_error);
306 output_buf = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)output_buf_stream);
308 g_assert_cmpint (g_bytes_get_size (output_buf), ==, 13);
309 g_assert_cmpint (memcmp (g_bytes_get_data (output_buf, NULL), "hello, world!", 13), ==, 0);
311 g_bytes_unref (output_buf);
312 g_main_loop_unref (data.loop);
313 g_object_unref (input_buf_stream);
314 g_object_unref (output_buf_stream);
315 g_object_unref (proc);
319 cancel_soon (gpointer user_data)
321 GCancellable *cancellable = user_data;
323 g_usleep (G_TIME_SPAN_SECOND);
324 g_cancellable_cancel (cancellable);
325 g_object_unref (cancellable);
333 GCancellable *cancellable;
334 GError *error = NULL;
341 cat = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "cat", NULL);
342 g_assert_no_error (error);
345 /* Make sure that reading stdout blocks (until we cancel) */
346 cancellable = g_cancellable_new ();
347 g_thread_unref (g_thread_new ("cancel thread", cancel_soon, g_object_ref (cancellable)));
348 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, cancellable, &error);
349 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
350 g_assert_cmpint (s, ==, -1);
351 g_object_unref (cancellable);
352 g_clear_error (&error);
354 /* Close the stream (EOF on cat's stdin) */
355 result = g_output_stream_close (g_subprocess_get_stdin_pipe (cat), NULL, &error);
356 g_assert_no_error (error);
359 /* Now check that reading cat's stdout gets us an EOF (since it quit) */
360 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, NULL, &error);
361 g_assert_no_error (error);
364 /* Check that the process has exited as a result of the EOF */
365 result = g_subprocess_wait (cat, NULL, &error);
366 g_assert_no_error (error);
367 g_assert (g_subprocess_get_if_exited (cat));
368 g_assert_cmpint (g_subprocess_get_exit_status (cat), ==, 0);
371 g_object_unref (cat);
375 guint events_pending;
376 gboolean caught_error;
381 GOutputStream *first_stdin;
382 } TestMultiSpliceData;
385 on_one_multi_splice_done (GObject *obj,
389 TestMultiSpliceData *data = user_data;
391 if (!data->caught_error)
393 if (g_output_stream_splice_finish ((GOutputStream*)obj, res, &data->error) < 0)
394 data->caught_error = TRUE;
397 data->events_pending--;
398 if (data->events_pending == 0)
399 g_main_loop_quit (data->loop);
403 on_idle_multisplice (gpointer user_data)
405 TestMultiSpliceData *data = user_data;
407 /* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n"
410 if (data->counter >= 2047 || data->caught_error)
412 if (!g_output_stream_close (data->first_stdin, NULL, &data->error))
413 data->caught_error = TRUE;
414 data->events_pending--;
415 if (data->events_pending == 0)
417 g_main_loop_quit (data->loop);
424 for (i = 0; i < data->counter; i++)
427 if (!g_output_stream_write_all (data->first_stdin, "hello world!\n",
428 strlen ("hello world!\n"), &bytes_written,
431 data->caught_error = TRUE;
441 on_subprocess_exited (GObject *object,
442 GAsyncResult *result,
445 GSubprocess *subprocess = G_SUBPROCESS (object);
446 TestMultiSpliceData *data = user_data;
447 GError *error = NULL;
449 if (!g_subprocess_wait_finish (subprocess, result, &error))
451 if (!data->caught_error)
453 data->caught_error = TRUE;
454 g_propagate_error (&data->error, error);
457 g_spawn_check_exit_status (g_subprocess_get_exit_status (subprocess), &error);
458 g_assert_no_error (error);
459 data->events_pending--;
460 if (data->events_pending == 0)
461 g_main_loop_quit (data->loop);
467 GError *local_error = NULL;
468 GError **error = &local_error;
470 GSubprocessLauncher *launcher;
474 GOutputStream *first_stdin;
475 GInputStream *first_stdout;
476 GOutputStream *second_stdin;
477 GInputStream *second_stdout;
478 GOutputStream *third_stdin;
479 GInputStream *third_stdout;
480 GOutputStream *membuf;
481 TestMultiSpliceData data;
482 int splice_flags = G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET;
484 args = get_test_subprocess_args ("cat", NULL);
485 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE);
486 first = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
487 g_assert_no_error (local_error);
488 second = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
489 g_assert_no_error (local_error);
490 third = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
491 g_assert_no_error (local_error);
493 g_ptr_array_free (args, TRUE);
495 membuf = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
497 first_stdin = g_subprocess_get_stdin_pipe (first);
498 first_stdout = g_subprocess_get_stdout_pipe (first);
499 second_stdin = g_subprocess_get_stdin_pipe (second);
500 second_stdout = g_subprocess_get_stdout_pipe (second);
501 third_stdin = g_subprocess_get_stdin_pipe (third);
502 third_stdout = g_subprocess_get_stdout_pipe (third);
504 memset (&data, 0, sizeof (data));
505 data.loop = g_main_loop_new (NULL, TRUE);
507 data.first_stdin = first_stdin;
509 data.events_pending++;
510 g_output_stream_splice_async (second_stdin, first_stdout, splice_flags, G_PRIORITY_DEFAULT,
511 NULL, on_one_multi_splice_done, &data);
512 data.events_pending++;
513 g_output_stream_splice_async (third_stdin, second_stdout, splice_flags, G_PRIORITY_DEFAULT,
514 NULL, on_one_multi_splice_done, &data);
515 data.events_pending++;
516 g_output_stream_splice_async (membuf, third_stdout, splice_flags, G_PRIORITY_DEFAULT,
517 NULL, on_one_multi_splice_done, &data);
519 data.events_pending++;
520 g_timeout_add (250, on_idle_multisplice, &data);
522 data.events_pending++;
523 g_subprocess_wait_async (first, NULL, on_subprocess_exited, &data);
524 data.events_pending++;
525 g_subprocess_wait_async (second, NULL, on_subprocess_exited, &data);
526 data.events_pending++;
527 g_subprocess_wait_async (third, NULL, on_subprocess_exited, &data);
529 g_main_loop_run (data.loop);
531 g_assert (!data.caught_error);
532 g_assert_no_error (data.error);
534 g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, 26611);
536 g_main_loop_unref (data.loop);
537 g_object_unref (membuf);
538 g_object_unref (launcher);
539 g_object_unref (first);
540 g_object_unref (second);
541 g_object_unref (third);
548 } TestAsyncCommunicateData;
551 on_communicate_complete (GObject *proc,
552 GAsyncResult *result,
555 TestAsyncCommunicateData *data = user_data;
556 GBytes *stdout = NULL;
557 char *stdout_str = NULL;
558 const guint8 *stdout_data;
561 data->running = FALSE;
563 (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result,
564 &stdout_str, NULL, &data->error);
566 (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result,
567 &stdout, NULL, &data->error);
573 stdout_data = g_bytes_get_data (stdout, &stdout_len);
577 stdout_data = (guint8*)stdout_str;
578 stdout_len = strlen (stdout_str);
581 g_assert_cmpint (stdout_len, ==, 11);
582 g_assert (memcmp (stdout_data, "hello world", 11) == 0);
584 g_bytes_unref (stdout);
589 test_communicate (void)
591 GError *error = NULL;
593 TestAsyncCommunicateData data = { 0, };
595 GCancellable *cancellable = NULL;
597 const char *hellostring;
599 args = get_test_subprocess_args ("cat", NULL);
600 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
601 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
603 g_assert_no_error (error);
604 g_ptr_array_free (args, TRUE);
606 hellostring = "hello world";
607 input = g_bytes_new_static (hellostring, strlen (hellostring));
609 g_subprocess_communicate_async (proc, input,
611 on_communicate_complete,
616 g_main_context_iteration (NULL, TRUE);
618 g_assert_no_error (data.error);
620 g_object_unref (proc);
624 test_communicate_utf8 (void)
626 GError *error = NULL;
628 TestAsyncCommunicateData data = { 0, };
630 GCancellable *cancellable = NULL;
632 args = get_test_subprocess_args ("cat", NULL);
633 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
634 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
636 g_assert_no_error (error);
637 g_ptr_array_free (args, TRUE);
640 g_subprocess_communicate_utf8_async (proc, "hello world",
642 on_communicate_complete,
647 g_main_context_iteration (NULL, TRUE);
649 g_assert_no_error (data.error);
651 g_object_unref (proc);
655 test_communicate_utf8_invalid (void)
657 GError *error = NULL;
659 TestAsyncCommunicateData data = { 0, };
661 GCancellable *cancellable = NULL;
663 args = get_test_subprocess_args ("cat", NULL);
664 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
665 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
667 g_assert_no_error (error);
668 g_ptr_array_free (args, TRUE);
671 g_subprocess_communicate_utf8_async (proc, "\xFF\xFF",
673 on_communicate_complete,
678 g_main_context_iteration (NULL, TRUE);
680 g_assert_error (data.error, G_IO_ERROR, G_IO_ERROR_FAILED);
681 g_error_free (data.error);
683 g_object_unref (proc);
687 send_terminate (gpointer user_data)
689 GSubprocess *proc = user_data;
691 g_subprocess_force_exit (proc);
697 on_request_quit_exited (GObject *object,
698 GAsyncResult *result,
701 GSubprocess *subprocess = G_SUBPROCESS (object);
702 GError *error = NULL;
704 g_subprocess_wait_finish (subprocess, result, &error);
705 g_assert_no_error (error);
707 g_assert (g_subprocess_get_if_signaled (subprocess));
708 g_assert (g_subprocess_get_term_sig (subprocess) == 9);
710 g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
711 g_assert (error != NULL);
712 g_clear_error (&error);
714 g_main_loop_quit ((GMainLoop*)user_data);
718 test_terminate (void)
720 GError *local_error = NULL;
721 GError **error = &local_error;
726 args = get_test_subprocess_args ("sleep-forever", NULL);
727 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
728 g_ptr_array_free (args, TRUE);
729 g_assert_no_error (local_error);
731 loop = g_main_loop_new (NULL, TRUE);
733 g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
735 g_timeout_add_seconds (3, send_terminate, proc);
737 g_main_loop_run (loop);
739 g_main_loop_unref (loop);
740 g_object_unref (proc);
745 test_stdout_file (void)
747 GError *local_error = NULL;
748 GError **error = &local_error;
749 GSubprocessLauncher *launcher;
753 GFileIOStream *iostream;
754 GOutputStream *stdin;
755 const char *test_data = "this is some test data\n";
759 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
760 g_assert_no_error (local_error);
761 g_clear_object (&iostream);
763 tmp_file_path = g_file_get_path (tmpfile);
765 args = get_test_subprocess_args ("cat", NULL);
766 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
767 g_subprocess_launcher_set_stdout_file_path (launcher, tmp_file_path);
768 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
769 g_ptr_array_free (args, TRUE);
770 g_assert_no_error (local_error);
772 stdin = g_subprocess_get_stdin_pipe (proc);
774 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
775 g_assert_no_error (local_error);
777 g_output_stream_close (stdin, NULL, error);
778 g_assert_no_error (local_error);
780 g_subprocess_wait_check (proc, NULL, error);
782 g_object_unref (launcher);
783 g_object_unref (proc);
785 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
786 g_assert_no_error (local_error);
788 g_assert_cmpstr (test_data, ==, tmp_contents);
789 g_free (tmp_contents);
791 (void) g_file_delete (tmpfile, NULL, NULL);
792 g_free (tmp_file_path);
796 test_stdout_fd (void)
798 GError *local_error = NULL;
799 GError **error = &local_error;
800 GSubprocessLauncher *launcher;
804 GFileIOStream *iostream;
805 GFileDescriptorBased *descriptor_stream;
806 GOutputStream *stdin;
807 const char *test_data = "this is some test data\n";
810 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
811 g_assert_no_error (local_error);
813 args = get_test_subprocess_args ("cat", NULL);
814 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
815 descriptor_stream = G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream)));
816 g_subprocess_launcher_take_stdout_fd (launcher, dup (g_file_descriptor_based_get_fd (descriptor_stream)));
817 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
818 g_ptr_array_free (args, TRUE);
819 g_assert_no_error (local_error);
821 g_clear_object (&iostream);
823 stdin = g_subprocess_get_stdin_pipe (proc);
825 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
826 g_assert_no_error (local_error);
828 g_output_stream_close (stdin, NULL, error);
829 g_assert_no_error (local_error);
831 g_subprocess_wait_check (proc, NULL, error);
833 g_object_unref (launcher);
834 g_object_unref (proc);
836 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
837 g_assert_no_error (local_error);
839 g_assert_cmpstr (test_data, ==, tmp_contents);
840 g_free (tmp_contents);
842 (void) g_file_delete (tmpfile, NULL, NULL);
846 child_setup (gpointer user_data)
848 dup2 (GPOINTER_TO_INT (user_data), 1);
852 test_child_setup (void)
854 GError *local_error = NULL;
855 GError **error = &local_error;
856 GSubprocessLauncher *launcher;
860 GFileIOStream *iostream;
861 GOutputStream *stdin;
862 const char *test_data = "this is some test data\n";
866 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
867 g_assert_no_error (local_error);
869 fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream))));
871 args = get_test_subprocess_args ("cat", NULL);
872 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
873 g_subprocess_launcher_set_child_setup (launcher, child_setup, GINT_TO_POINTER (fd), NULL);
874 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
875 g_ptr_array_free (args, TRUE);
876 g_assert_no_error (local_error);
878 g_clear_object (&iostream);
880 stdin = g_subprocess_get_stdin_pipe (proc);
882 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
883 g_assert_no_error (local_error);
885 g_output_stream_close (stdin, NULL, error);
886 g_assert_no_error (local_error);
888 g_subprocess_wait_check (proc, NULL, error);
890 g_object_unref (launcher);
891 g_object_unref (proc);
893 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
894 g_assert_no_error (local_error);
896 g_assert_cmpstr (test_data, ==, tmp_contents);
897 g_free (tmp_contents);
899 (void) g_file_delete (tmpfile, NULL, NULL);
905 GError *local_error = NULL;
906 GError **error = &local_error;
907 GInputStream *child_input;
908 GDataInputStream *child_datainput;
909 GSubprocessLauncher *launcher;
912 int basic_pipefds[2];
913 int needdup_pipefds[2];
917 char *needdup_fd_str;
919 g_unix_open_pipe (basic_pipefds, FD_CLOEXEC, error);
920 g_assert_no_error (local_error);
921 g_unix_open_pipe (needdup_pipefds, FD_CLOEXEC, error);
922 g_assert_no_error (local_error);
924 basic_fd_str = g_strdup_printf ("%d", basic_pipefds[1]);
925 needdup_fd_str = g_strdup_printf ("%d", needdup_pipefds[1] + 1);
927 args = get_test_subprocess_args ("write-to-fds", basic_fd_str, needdup_fd_str, NULL);
928 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
929 g_subprocess_launcher_take_fd (launcher, basic_pipefds[1], basic_pipefds[1]);
930 g_subprocess_launcher_take_fd (launcher, needdup_pipefds[1], needdup_pipefds[1] + 1);
931 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
932 g_ptr_array_free (args, TRUE);
933 g_assert_no_error (local_error);
935 g_free (basic_fd_str);
936 g_free (needdup_fd_str);
938 child_input = g_unix_input_stream_new (basic_pipefds[0], TRUE);
939 child_datainput = g_data_input_stream_new (child_input);
940 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
941 g_assert_no_error (local_error);
942 g_assert_cmpstr (buf, ==, "hello world");
943 g_object_unref (child_datainput);
944 g_object_unref (child_input);
947 child_input = g_unix_input_stream_new (needdup_pipefds[0], TRUE);
948 child_datainput = g_data_input_stream_new (child_input);
949 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
950 g_assert_no_error (local_error);
951 g_assert_cmpstr (buf, ==, "hello world");
953 g_object_unref (child_datainput);
954 g_object_unref (child_input);
956 g_object_unref (launcher);
957 g_object_unref (proc);
963 main (int argc, char **argv)
965 g_test_init (&argc, &argv, NULL);
967 g_test_add_func ("/gsubprocess/noop", test_noop);
968 g_test_add_func ("/gsubprocess/noop-all-to-null", test_noop_all_to_null);
969 g_test_add_func ("/gsubprocess/noop-no-wait", test_noop_no_wait);
970 g_test_add_func ("/gsubprocess/noop-stdin-inherit", test_noop_stdin_inherit);
972 g_test_add_func ("/gsubprocess/search-path", test_search_path);
974 g_test_add_func ("/gsubprocess/exit1", test_exit1);
975 g_test_add_func ("/gsubprocess/echo1", test_echo1);
977 g_test_add_func ("/gsubprocess/echo-merged", test_echo_merged);
979 g_test_add_func ("/gsubprocess/cat-utf8", test_cat_utf8);
980 g_test_add_func ("/gsubprocess/cat-eof", test_cat_eof);
981 g_test_add_func ("/gsubprocess/multi1", test_multi_1);
982 g_test_add_func ("/gsubprocess/communicate", test_communicate);
983 g_test_add_func ("/gsubprocess/communicate-utf8", test_communicate_utf8);
984 g_test_add_func ("/gsubprocess/communicate-utf8-invalid", test_communicate_utf8_invalid);
985 g_test_add_func ("/gsubprocess/terminate", test_terminate);
987 g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file);
988 g_test_add_func ("/gsubprocess/stdout-fd", test_stdout_fd);
989 g_test_add_func ("/gsubprocess/child-setup", test_child_setup);
990 g_test_add_func ("/gsubprocess/pass-fd", test_pass_fd);
993 return g_test_run ();