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,
26 ret = g_ptr_array_new_with_free_func (g_free);
28 cwd = g_get_current_dir ();
31 binname = "gsubprocess-testprog.exe";
33 binname = "gsubprocess-testprog";
36 cwd_path = g_build_filename (cwd, binname, NULL);
38 g_ptr_array_add (ret, cwd_path);
39 g_ptr_array_add (ret, g_strdup (mode));
41 va_start (args, mode);
42 while ((arg = va_arg (args, gpointer)) != NULL)
43 g_ptr_array_add (ret, g_strdup (arg));
46 g_ptr_array_add (ret, NULL);
53 GError *local_error = NULL;
54 GError **error = &local_error;
58 args = get_test_subprocess_args ("noop", NULL);
59 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
60 g_ptr_array_free (args, TRUE);
61 g_assert_no_error (local_error);
63 g_subprocess_wait_check (proc, NULL, error);
64 g_assert_no_error (local_error);
66 g_object_unref (proc);
70 test_noop_all_to_null (void)
72 GError *local_error = NULL;
73 GError **error = &local_error;
77 args = get_test_subprocess_args ("noop", NULL);
78 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
79 G_SUBPROCESS_FLAGS_STDOUT_SILENCE | G_SUBPROCESS_FLAGS_STDERR_SILENCE,
81 g_ptr_array_free (args, TRUE);
82 g_assert_no_error (local_error);
84 g_subprocess_wait_check (proc, NULL, error);
85 g_assert_no_error (local_error);
87 g_object_unref (proc);
91 test_noop_no_wait (void)
93 GError *local_error = NULL;
94 GError **error = &local_error;
98 args = get_test_subprocess_args ("noop", NULL);
99 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
100 g_ptr_array_free (args, TRUE);
101 g_assert_no_error (local_error);
103 g_object_unref (proc);
107 test_noop_stdin_inherit (void)
109 GError *local_error = NULL;
110 GError **error = &local_error;
114 args = get_test_subprocess_args ("noop", NULL);
115 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDIN_INHERIT, error);
116 g_ptr_array_free (args, TRUE);
117 g_assert_no_error (local_error);
119 g_subprocess_wait_check (proc, NULL, error);
120 g_assert_no_error (local_error);
122 g_object_unref (proc);
127 test_search_path (void)
129 GError *local_error = NULL;
130 GError **error = &local_error;
133 proc = g_subprocess_new (G_SUBPROCESS_FLAGS_NONE, error, "true", NULL);
134 g_assert_no_error (local_error);
136 g_subprocess_wait_check (proc, NULL, error);
137 g_assert_no_error (local_error);
139 g_object_unref (proc);
146 GError *local_error = NULL;
147 GError **error = &local_error;
151 args = get_test_subprocess_args ("exit1", NULL);
152 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
153 g_ptr_array_free (args, TRUE);
154 g_assert_no_error (local_error);
156 g_subprocess_wait_check (proc, NULL, error);
157 g_assert_error (local_error, G_SPAWN_EXIT_ERROR, 1);
158 g_clear_error (error);
160 g_object_unref (proc);
164 splice_to_string (GInputStream *stream,
167 GMemoryOutputStream *buffer = NULL;
170 buffer = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
171 if (g_output_stream_splice ((GOutputStream*)buffer, stream, 0, NULL, error) < 0)
174 if (!g_output_stream_write ((GOutputStream*)buffer, "\0", 1, NULL, error))
177 if (!g_output_stream_close ((GOutputStream*)buffer, NULL, error))
180 ret = g_memory_output_stream_steal_data (buffer);
182 g_clear_object (&buffer);
189 GError *local_error = NULL;
190 GError **error = &local_error;
193 GInputStream *stdout;
196 args = get_test_subprocess_args ("echo", "hello", "world!", NULL);
197 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_STDOUT_PIPE, error);
198 g_ptr_array_free (args, TRUE);
199 g_assert_no_error (local_error);
201 stdout = g_subprocess_get_stdout_pipe (proc);
203 result = splice_to_string (stdout, error);
204 g_assert_no_error (local_error);
206 g_assert_cmpstr (result, ==, "hello\nworld!\n");
209 g_object_unref (proc);
214 test_echo_merged (void)
216 GError *local_error = NULL;
217 GError **error = &local_error;
220 GInputStream *stdout;
223 args = get_test_subprocess_args ("echo-stdout-and-stderr", "merge", "this", NULL);
224 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
225 G_SUBPROCESS_FLAGS_STDOUT_PIPE | G_SUBPROCESS_FLAGS_STDERR_MERGE,
227 g_ptr_array_free (args, TRUE);
228 g_assert_no_error (local_error);
230 stdout = g_subprocess_get_stdout_pipe (proc);
231 result = splice_to_string (stdout, error);
232 g_assert_no_error (local_error);
234 g_assert_cmpstr (result, ==, "merge\nmerge\nthis\nthis\n");
237 g_object_unref (proc);
242 guint events_pending;
247 test_cat_on_input_splice_complete (GObject *object,
248 GAsyncResult *result,
251 TestCatData *data = user_data;
252 GError *error = NULL;
254 (void)g_output_stream_splice_finish ((GOutputStream*)object, result, &error);
255 g_assert_no_error (error);
257 data->events_pending--;
258 if (data->events_pending == 0)
259 g_main_loop_quit (data->loop);
265 GError *local_error = NULL;
266 GError **error = &local_error;
271 GInputStream *input_buf_stream = NULL;
272 GOutputStream *output_buf_stream = NULL;
273 GOutputStream *stdin_stream = NULL;
274 GInputStream *stdout_stream = NULL;
277 memset (&data, 0, sizeof (data));
278 data.loop = g_main_loop_new (NULL, TRUE);
280 args = get_test_subprocess_args ("cat", NULL);
281 proc = g_subprocess_newv ((const gchar * const *) args->pdata,
282 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
284 g_ptr_array_free (args, TRUE);
285 g_assert_no_error (local_error);
287 stdin_stream = g_subprocess_get_stdin_pipe (proc);
288 stdout_stream = g_subprocess_get_stdout_pipe (proc);
290 input_buf = g_bytes_new_static ("hello, world!", strlen ("hello, world!"));
291 input_buf_stream = g_memory_input_stream_new_from_bytes (input_buf);
292 g_bytes_unref (input_buf);
294 output_buf_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
296 g_output_stream_splice_async (stdin_stream, input_buf_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++;
300 g_output_stream_splice_async (output_buf_stream, stdout_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
301 G_PRIORITY_DEFAULT, NULL, test_cat_on_input_splice_complete,
303 data.events_pending++;
305 g_main_loop_run (data.loop);
307 g_subprocess_wait_check (proc, NULL, error);
308 g_assert_no_error (local_error);
310 output_buf = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)output_buf_stream);
312 g_assert_cmpint (g_bytes_get_size (output_buf), ==, 13);
313 g_assert_cmpint (memcmp (g_bytes_get_data (output_buf, NULL), "hello, world!", 13), ==, 0);
315 g_bytes_unref (output_buf);
316 g_main_loop_unref (data.loop);
317 g_object_unref (input_buf_stream);
318 g_object_unref (output_buf_stream);
319 g_object_unref (proc);
323 cancel_soon (gpointer user_data)
325 GCancellable *cancellable = user_data;
327 g_usleep (G_TIME_SPAN_SECOND);
328 g_cancellable_cancel (cancellable);
329 g_object_unref (cancellable);
337 GCancellable *cancellable;
338 GError *error = NULL;
345 cat = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "cat", NULL);
346 g_assert_no_error (error);
349 /* Make sure that reading stdout blocks (until we cancel) */
350 cancellable = g_cancellable_new ();
351 g_thread_unref (g_thread_new ("cancel thread", cancel_soon, g_object_ref (cancellable)));
352 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, cancellable, &error);
353 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
354 g_assert_cmpint (s, ==, -1);
355 g_object_unref (cancellable);
356 g_clear_error (&error);
358 /* Close the stream (EOF on cat's stdin) */
359 result = g_output_stream_close (g_subprocess_get_stdin_pipe (cat), NULL, &error);
360 g_assert_no_error (error);
363 /* Now check that reading cat's stdout gets us an EOF (since it quit) */
364 s = g_input_stream_read (g_subprocess_get_stdout_pipe (cat), &buffer, sizeof buffer, NULL, &error);
365 g_assert_no_error (error);
368 /* Check that the process has exited as a result of the EOF */
369 result = g_subprocess_wait (cat, NULL, &error);
370 g_assert_no_error (error);
371 g_assert (g_subprocess_get_if_exited (cat));
372 g_assert_cmpint (g_subprocess_get_exit_status (cat), ==, 0);
375 g_object_unref (cat);
379 guint events_pending;
380 gboolean caught_error;
385 GOutputStream *first_stdin;
386 } TestMultiSpliceData;
389 on_one_multi_splice_done (GObject *obj,
393 TestMultiSpliceData *data = user_data;
395 if (!data->caught_error)
397 if (g_output_stream_splice_finish ((GOutputStream*)obj, res, &data->error) < 0)
398 data->caught_error = TRUE;
401 data->events_pending--;
402 if (data->events_pending == 0)
403 g_main_loop_quit (data->loop);
407 on_idle_multisplice (gpointer user_data)
409 TestMultiSpliceData *data = user_data;
411 /* We write 2^1 + 2^2 ... + 2^10 or 2047 copies of "Hello World!\n"
414 if (data->counter >= 2047 || data->caught_error)
416 if (!g_output_stream_close (data->first_stdin, NULL, &data->error))
417 data->caught_error = TRUE;
418 data->events_pending--;
419 if (data->events_pending == 0)
421 g_main_loop_quit (data->loop);
428 for (i = 0; i < data->counter; i++)
431 if (!g_output_stream_write_all (data->first_stdin, "hello world!\n",
432 strlen ("hello world!\n"), &bytes_written,
435 data->caught_error = TRUE;
445 on_subprocess_exited (GObject *object,
446 GAsyncResult *result,
449 GSubprocess *subprocess = G_SUBPROCESS (object);
450 TestMultiSpliceData *data = user_data;
451 GError *error = NULL;
453 if (!g_subprocess_wait_finish (subprocess, result, &error))
455 if (!data->caught_error)
457 data->caught_error = TRUE;
458 g_propagate_error (&data->error, error);
461 g_spawn_check_exit_status (g_subprocess_get_exit_status (subprocess), &error);
462 g_assert_no_error (error);
463 data->events_pending--;
464 if (data->events_pending == 0)
465 g_main_loop_quit (data->loop);
471 GError *local_error = NULL;
472 GError **error = &local_error;
474 GSubprocessLauncher *launcher;
478 GOutputStream *first_stdin;
479 GInputStream *first_stdout;
480 GOutputStream *second_stdin;
481 GInputStream *second_stdout;
482 GOutputStream *third_stdin;
483 GInputStream *third_stdout;
484 GOutputStream *membuf;
485 TestMultiSpliceData data;
486 int splice_flags = G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET;
488 args = get_test_subprocess_args ("cat", NULL);
489 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE);
490 first = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
491 g_assert_no_error (local_error);
492 second = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
493 g_assert_no_error (local_error);
494 third = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
495 g_assert_no_error (local_error);
497 g_ptr_array_free (args, TRUE);
499 membuf = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
501 first_stdin = g_subprocess_get_stdin_pipe (first);
502 first_stdout = g_subprocess_get_stdout_pipe (first);
503 second_stdin = g_subprocess_get_stdin_pipe (second);
504 second_stdout = g_subprocess_get_stdout_pipe (second);
505 third_stdin = g_subprocess_get_stdin_pipe (third);
506 third_stdout = g_subprocess_get_stdout_pipe (third);
508 memset (&data, 0, sizeof (data));
509 data.loop = g_main_loop_new (NULL, TRUE);
511 data.first_stdin = first_stdin;
513 data.events_pending++;
514 g_output_stream_splice_async (second_stdin, first_stdout, splice_flags, G_PRIORITY_DEFAULT,
515 NULL, on_one_multi_splice_done, &data);
516 data.events_pending++;
517 g_output_stream_splice_async (third_stdin, second_stdout, splice_flags, G_PRIORITY_DEFAULT,
518 NULL, on_one_multi_splice_done, &data);
519 data.events_pending++;
520 g_output_stream_splice_async (membuf, third_stdout, splice_flags, G_PRIORITY_DEFAULT,
521 NULL, on_one_multi_splice_done, &data);
523 data.events_pending++;
524 g_timeout_add (250, on_idle_multisplice, &data);
526 data.events_pending++;
527 g_subprocess_wait_async (first, NULL, on_subprocess_exited, &data);
528 data.events_pending++;
529 g_subprocess_wait_async (second, NULL, on_subprocess_exited, &data);
530 data.events_pending++;
531 g_subprocess_wait_async (third, NULL, on_subprocess_exited, &data);
533 g_main_loop_run (data.loop);
535 g_assert (!data.caught_error);
536 g_assert_no_error (data.error);
538 g_assert_cmpint (g_memory_output_stream_get_data_size ((GMemoryOutputStream*)membuf), ==, 26611);
540 g_main_loop_unref (data.loop);
541 g_object_unref (membuf);
542 g_object_unref (launcher);
543 g_object_unref (first);
544 g_object_unref (second);
545 g_object_unref (third);
550 gboolean is_invalid_utf8;
553 } TestAsyncCommunicateData;
556 on_communicate_complete (GObject *proc,
557 GAsyncResult *result,
560 TestAsyncCommunicateData *data = user_data;
561 GBytes *stdout = NULL;
562 char *stdout_str = NULL;
563 const guint8 *stdout_data;
566 data->running = FALSE;
568 (void) g_subprocess_communicate_utf8_finish ((GSubprocess*)proc, result,
569 &stdout_str, NULL, &data->error);
571 (void) g_subprocess_communicate_finish ((GSubprocess*)proc, result,
572 &stdout, NULL, &data->error);
573 if (data->is_invalid_utf8)
575 g_assert_error (data->error, G_IO_ERROR, G_IO_ERROR_FAILED);
579 g_assert_no_error (data->error);
583 stdout_data = g_bytes_get_data (stdout, &stdout_len);
587 stdout_data = (guint8*)stdout_str;
588 stdout_len = strlen (stdout_str);
591 g_assert_cmpint (stdout_len, ==, 11);
592 g_assert (memcmp (stdout_data, "hello world", 11) == 0);
594 g_bytes_unref (stdout);
599 test_communicate (void)
601 GError *local_error = NULL;
602 GError **error = &local_error;
604 TestAsyncCommunicateData data = { 0, };
606 GCancellable *cancellable = NULL;
608 const char *hellostring;
610 args = get_test_subprocess_args ("cat", NULL);
611 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
612 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
614 g_assert_no_error (local_error);
615 g_ptr_array_free (args, TRUE);
617 hellostring = "hello world";
618 input = g_bytes_new_static (hellostring, strlen (hellostring));
620 data.error = local_error;
621 g_subprocess_communicate_async (proc, input,
623 on_communicate_complete,
628 g_main_context_iteration (NULL, TRUE);
630 g_assert_no_error (local_error);
632 g_object_unref (proc);
636 test_communicate_utf8 (void)
638 GError *local_error = NULL;
639 GError **error = &local_error;
641 TestAsyncCommunicateData data = { 0, };
643 GCancellable *cancellable = NULL;
645 args = get_test_subprocess_args ("cat", NULL);
646 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
647 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
649 g_assert_no_error (local_error);
650 g_ptr_array_free (args, TRUE);
652 data.error = local_error;
654 g_subprocess_communicate_utf8_async (proc, "hello world",
656 on_communicate_complete,
661 g_main_context_iteration (NULL, TRUE);
663 g_assert_no_error (local_error);
665 g_object_unref (proc);
669 test_communicate_utf8_invalid (void)
671 GError *local_error = NULL;
672 GError **error = &local_error;
674 TestAsyncCommunicateData data = { 0, };
676 GCancellable *cancellable = NULL;
678 args = get_test_subprocess_args ("cat", NULL);
679 proc = g_subprocess_newv ((const gchar* const*)args->pdata,
680 G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDOUT_PIPE,
682 g_assert_no_error (local_error);
683 g_ptr_array_free (args, TRUE);
685 data.error = local_error;
687 data.is_invalid_utf8 = TRUE;
688 g_subprocess_communicate_utf8_async (proc, "\xFF\xFF",
690 on_communicate_complete,
695 g_main_context_iteration (NULL, TRUE);
697 g_assert_no_error (local_error);
699 g_object_unref (proc);
703 send_terminate (gpointer user_data)
705 GSubprocess *proc = user_data;
707 g_subprocess_force_exit (proc);
713 on_request_quit_exited (GObject *object,
714 GAsyncResult *result,
717 GSubprocess *subprocess = G_SUBPROCESS (object);
718 GError *error = NULL;
720 g_subprocess_wait_finish (subprocess, result, &error);
721 g_assert_no_error (error);
723 g_assert (g_subprocess_get_if_signaled (subprocess));
724 g_assert (g_subprocess_get_term_sig (subprocess) == 9);
726 g_spawn_check_exit_status (g_subprocess_get_status (subprocess), &error);
727 g_assert (error != NULL);
728 g_clear_error (&error);
730 g_main_loop_quit ((GMainLoop*)user_data);
734 test_terminate (void)
736 GError *local_error = NULL;
737 GError **error = &local_error;
742 args = get_test_subprocess_args ("sleep-forever", NULL);
743 proc = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
744 g_ptr_array_free (args, TRUE);
745 g_assert_no_error (local_error);
747 loop = g_main_loop_new (NULL, TRUE);
749 g_subprocess_wait_async (proc, NULL, on_request_quit_exited, loop);
751 g_timeout_add_seconds (3, send_terminate, proc);
753 g_main_loop_run (loop);
755 g_main_loop_unref (loop);
756 g_object_unref (proc);
761 test_stdout_file (void)
763 GError *local_error = NULL;
764 GError **error = &local_error;
765 GSubprocessLauncher *launcher;
769 GFileIOStream *iostream;
770 GOutputStream *stdin;
771 const char *test_data = "this is some test data\n";
775 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
776 g_assert_no_error (local_error);
777 g_clear_object (&iostream);
779 tmp_file_path = g_file_get_path (tmpfile);
781 args = get_test_subprocess_args ("cat", NULL);
782 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
783 g_subprocess_launcher_set_stdout_file_path (launcher, tmp_file_path);
784 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
785 g_ptr_array_free (args, TRUE);
786 g_assert_no_error (local_error);
788 stdin = g_subprocess_get_stdin_pipe (proc);
790 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
791 g_assert_no_error (local_error);
793 g_output_stream_close (stdin, NULL, error);
794 g_assert_no_error (local_error);
796 g_subprocess_wait_check (proc, NULL, error);
798 g_object_unref (launcher);
799 g_object_unref (proc);
801 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
802 g_assert_no_error (local_error);
804 g_assert_cmpstr (test_data, ==, tmp_contents);
805 g_free (tmp_contents);
807 (void) g_file_delete (tmpfile, NULL, NULL);
808 g_free (tmp_file_path);
812 test_stdout_fd (void)
814 GError *local_error = NULL;
815 GError **error = &local_error;
816 GSubprocessLauncher *launcher;
820 GFileIOStream *iostream;
821 GFileDescriptorBased *descriptor_stream;
822 GOutputStream *stdin;
823 const char *test_data = "this is some test data\n";
826 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
827 g_assert_no_error (local_error);
829 args = get_test_subprocess_args ("cat", NULL);
830 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
831 descriptor_stream = G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream)));
832 g_subprocess_launcher_take_stdout_fd (launcher, dup (g_file_descriptor_based_get_fd (descriptor_stream)));
833 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
834 g_ptr_array_free (args, TRUE);
835 g_assert_no_error (local_error);
837 g_clear_object (&iostream);
839 stdin = g_subprocess_get_stdin_pipe (proc);
841 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
842 g_assert_no_error (local_error);
844 g_output_stream_close (stdin, NULL, error);
845 g_assert_no_error (local_error);
847 g_subprocess_wait_check (proc, NULL, error);
849 g_object_unref (launcher);
850 g_object_unref (proc);
852 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
853 g_assert_no_error (local_error);
855 g_assert_cmpstr (test_data, ==, tmp_contents);
856 g_free (tmp_contents);
858 (void) g_file_delete (tmpfile, NULL, NULL);
862 child_setup (gpointer user_data)
864 dup2 (GPOINTER_TO_INT (user_data), 1);
868 test_child_setup (void)
870 GError *local_error = NULL;
871 GError **error = &local_error;
872 GSubprocessLauncher *launcher;
876 GFileIOStream *iostream;
877 GOutputStream *stdin;
878 const char *test_data = "this is some test data\n";
882 tmpfile = g_file_new_tmp ("gsubprocessXXXXXX", &iostream, error);
883 g_assert_no_error (local_error);
885 fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (g_io_stream_get_output_stream (G_IO_STREAM (iostream))));
887 args = get_test_subprocess_args ("cat", NULL);
888 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE);
889 g_subprocess_launcher_set_child_setup (launcher, child_setup, GINT_TO_POINTER (fd), NULL);
890 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
891 g_ptr_array_free (args, TRUE);
892 g_assert_no_error (local_error);
894 g_clear_object (&iostream);
896 stdin = g_subprocess_get_stdin_pipe (proc);
898 g_output_stream_write_all (stdin, test_data, strlen (test_data), NULL, NULL, error);
899 g_assert_no_error (local_error);
901 g_output_stream_close (stdin, NULL, error);
902 g_assert_no_error (local_error);
904 g_subprocess_wait_check (proc, NULL, error);
906 g_object_unref (launcher);
907 g_object_unref (proc);
909 g_file_load_contents (tmpfile, NULL, &tmp_contents, NULL, NULL, error);
910 g_assert_no_error (local_error);
912 g_assert_cmpstr (test_data, ==, tmp_contents);
913 g_free (tmp_contents);
915 (void) g_file_delete (tmpfile, NULL, NULL);
921 GError *local_error = NULL;
922 GError **error = &local_error;
923 GInputStream *child_input;
924 GDataInputStream *child_datainput;
925 GSubprocessLauncher *launcher;
928 int basic_pipefds[2];
929 int needdup_pipefds[2];
933 char *needdup_fd_str;
935 g_unix_open_pipe (basic_pipefds, FD_CLOEXEC, error);
936 g_assert_no_error (local_error);
937 g_unix_open_pipe (needdup_pipefds, FD_CLOEXEC, error);
938 g_assert_no_error (local_error);
940 basic_fd_str = g_strdup_printf ("%d", basic_pipefds[1]);
941 needdup_fd_str = g_strdup_printf ("%d", needdup_pipefds[1] + 1);
943 args = get_test_subprocess_args ("write-to-fds", basic_fd_str, needdup_fd_str, NULL);
944 launcher = g_subprocess_launcher_new (G_SUBPROCESS_FLAGS_NONE);
945 g_subprocess_launcher_take_fd (launcher, basic_pipefds[1], basic_pipefds[1]);
946 g_subprocess_launcher_take_fd (launcher, needdup_pipefds[1], needdup_pipefds[1] + 1);
947 proc = g_subprocess_launcher_spawnv (launcher, (const gchar * const *) args->pdata, error);
948 g_ptr_array_free (args, TRUE);
949 g_assert_no_error (local_error);
951 g_free (basic_fd_str);
952 g_free (needdup_fd_str);
954 child_input = g_unix_input_stream_new (basic_pipefds[0], TRUE);
955 child_datainput = g_data_input_stream_new (child_input);
956 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
957 g_assert_no_error (local_error);
958 g_assert_cmpstr (buf, ==, "hello world");
959 g_object_unref (child_datainput);
960 g_object_unref (child_input);
963 child_input = g_unix_input_stream_new (needdup_pipefds[0], TRUE);
964 child_datainput = g_data_input_stream_new (child_input);
965 buf = g_data_input_stream_read_line_utf8 (child_datainput, &len, NULL, error);
966 g_assert_no_error (local_error);
967 g_assert_cmpstr (buf, ==, "hello world");
969 g_object_unref (child_datainput);
970 g_object_unref (child_input);
972 g_object_unref (launcher);
973 g_object_unref (proc);
979 main (int argc, char **argv)
981 g_test_init (&argc, &argv, NULL);
983 g_test_add_func ("/gsubprocess/noop", test_noop);
984 g_test_add_func ("/gsubprocess/noop-all-to-null", test_noop_all_to_null);
985 g_test_add_func ("/gsubprocess/noop-no-wait", test_noop_no_wait);
986 g_test_add_func ("/gsubprocess/noop-stdin-inherit", test_noop_stdin_inherit);
988 g_test_add_func ("/gsubprocess/search-path", test_search_path);
990 g_test_add_func ("/gsubprocess/exit1", test_exit1);
991 g_test_add_func ("/gsubprocess/echo1", test_echo1);
993 g_test_add_func ("/gsubprocess/echo-merged", test_echo_merged);
995 g_test_add_func ("/gsubprocess/cat-utf8", test_cat_utf8);
996 g_test_add_func ("/gsubprocess/cat-eof", test_cat_eof);
997 g_test_add_func ("/gsubprocess/multi1", test_multi_1);
998 g_test_add_func ("/gsubprocess/communicate", test_communicate);
999 g_test_add_func ("/gsubprocess/communicate-utf8", test_communicate_utf8);
1000 g_test_add_func ("/gsubprocess/communicate-utf8-invalid", test_communicate_utf8_invalid);
1001 g_test_add_func ("/gsubprocess/terminate", test_terminate);
1003 g_test_add_func ("/gsubprocess/stdout-file", test_stdout_file);
1004 g_test_add_func ("/gsubprocess/stdout-fd", test_stdout_fd);
1005 g_test_add_func ("/gsubprocess/child-setup", test_child_setup);
1006 g_test_add_func ("/gsubprocess/pass-fd", test_pass_fd);
1009 return g_test_run ();