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