GSubprocess: New class for spawning child processes
[platform/upstream/glib.git] / gio / tests / gsubprocess-testprog.c
1 #include <gio/gio.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <errno.h>
6 #ifdef G_OS_UNIX
7 #include <gio/gunixinputstream.h>
8 #include <gio/gunixoutputstream.h>
9 #endif
10
11 static GOptionEntry options[] = {
12   {NULL}
13 };
14
15 static void
16 write_all (int           fd,
17            const guint8* buf,
18            gsize         len)
19 {
20   while (len > 0)
21     {
22       ssize_t bytes_written = write (fd, buf, len);
23       if (bytes_written < 0)
24         g_error ("Failed to write to fd %d: %s",
25                  fd, strerror (errno));
26       buf += bytes_written;
27       len -= bytes_written;
28     }
29 }
30
31 static int
32 echo_mode (int argc,
33            char **argv)
34 {
35   int i;
36
37   for (i = 2; i < argc; i++)
38     {
39       write_all (1, (guint8*)argv[i], strlen (argv[i]));
40       write_all (1, (guint8*)"\n", 1);
41     }
42
43   return 0;
44 }
45
46 static int
47 echo_stdout_and_stderr_mode (int argc,
48                              char **argv)
49 {
50   int i;
51
52   for (i = 2; i < argc; i++)
53     {
54       write_all (1, (guint8*)argv[i], strlen (argv[i]));
55       write_all (1, (guint8*)"\n", 1);
56       write_all (2, (guint8*)argv[i], strlen (argv[i]));
57       write_all (2, (guint8*)"\n", 1);
58     }
59
60   return 0;
61 }
62
63 static int
64 cat_mode (int argc,
65           char **argv)
66 {
67   GIOChannel *chan_stdin;
68   GIOChannel *chan_stdout;
69   GIOStatus status;
70   char buf[1024];
71   gsize bytes_read, bytes_written;
72   GError *local_error = NULL;
73   GError **error = &local_error;
74
75   chan_stdin = g_io_channel_unix_new (0);
76   g_io_channel_set_encoding (chan_stdin, NULL, error);
77   g_assert_no_error (local_error);
78   chan_stdout = g_io_channel_unix_new (1);
79   g_io_channel_set_encoding (chan_stdout, NULL, error);
80   g_assert_no_error (local_error);
81
82   while (TRUE)
83     {
84       do
85         status = g_io_channel_read_chars (chan_stdin, buf, sizeof (buf),
86                                           &bytes_read, error);
87       while (status == G_IO_STATUS_AGAIN);
88
89       if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR)
90         break;
91
92       do
93         status = g_io_channel_write_chars (chan_stdout, buf, bytes_read,
94                                            &bytes_written, error);
95       while (status == G_IO_STATUS_AGAIN);
96
97       if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_ERROR)
98         break;
99     }
100
101   g_io_channel_unref (chan_stdin);
102   g_io_channel_unref (chan_stdout);
103
104   if (local_error)
105     {
106       g_printerr ("I/O error: %s\n", local_error->message);
107       g_clear_error (&local_error);
108       return 1;
109     }
110   return 0;
111 }
112
113 static gint
114 sleep_forever_mode (int argc,
115                     char **argv)
116 {
117   GMainLoop *loop;
118   
119   loop = g_main_loop_new (NULL, TRUE);
120   g_main_loop_run (loop);
121
122   return 0;
123 }
124
125 static int
126 write_to_fds (int argc, char **argv)
127 {
128   int i;
129
130   for (i = 2; i < argc; i++)
131     {
132       int fd = atoi (argv[i]);
133       FILE *f = fdopen (fd, "w");
134       const char buf[] = "hello world\n";
135       size_t bytes_written;
136       
137       g_assert (f != NULL);
138       
139       bytes_written = fwrite (buf, 1, sizeof (buf), f);
140       g_assert (bytes_written == sizeof (buf));
141       
142       if (fclose (f) == -1)
143         g_assert_not_reached ();
144     }
145
146   return 0;
147 }
148
149 int
150 main (int argc, char **argv)
151 {
152   GOptionContext *context;
153   GError *error = NULL;
154   const char *mode;
155
156   context = g_option_context_new ("MODE - Test GSubprocess stuff");
157   g_option_context_add_main_entries (context, options, NULL);
158   if (!g_option_context_parse (context, &argc, &argv, &error))
159     {
160       g_printerr ("%s: %s\n", argv[0], error->message);
161       return 1;
162     }
163
164   if (argc < 2)
165     {
166       g_printerr ("MODE argument required\n");
167       return 1;
168     }
169
170   mode = argv[1];
171   if (strcmp (mode, "noop") == 0)
172     return 0;
173   else if (strcmp (mode, "exit1") == 0)
174     return 1;
175   else if (strcmp (mode, "assert-argv0") == 0)
176     {
177       if (strcmp (argv[0], "moocow") == 0)
178         return 0;
179       g_printerr ("argv0=%s != moocow\n", argv[0]);
180       return 1;
181     }
182   else if (strcmp (mode, "echo") == 0)
183     return echo_mode (argc, argv);
184   else if (strcmp (mode, "echo-stdout-and-stderr") == 0)
185     return echo_stdout_and_stderr_mode (argc, argv);
186   else if (strcmp (mode, "cat") == 0)
187     return cat_mode (argc, argv);
188   else if (strcmp (mode, "sleep-forever") == 0)
189     return sleep_forever_mode (argc, argv);
190   else if (strcmp (mode, "write-to-fds") == 0)
191     return write_to_fds (argc, argv);
192   else
193     {
194       g_printerr ("Unknown MODE %s\n", argv[1]);
195       return 1;
196     }
197
198   return TRUE;
199 }