gsubprocess: test environment a bit more
[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 static int
167 cwd_mode (int argc, char **argv)
168 {
169   char *cwd;
170
171   cwd = g_get_current_dir ();
172   g_print ("%s\n", cwd);
173   g_free (cwd);
174
175   return 0;
176 }
177
178 static int
179 printenv_mode (int argc, char **argv)
180 {
181   gint i;
182
183   for (i = 2; i < argc; i++)
184     {
185       const gchar *value = g_getenv (argv[i]);
186
187       if (value != NULL)
188         g_print ("%s=%s\n", argv[i], value);
189     }
190
191   return 0;
192 }
193
194 int
195 main (int argc, char **argv)
196 {
197   GOptionContext *context;
198   GError *error = NULL;
199   const char *mode;
200
201   context = g_option_context_new ("MODE - Test GSubprocess stuff");
202   g_option_context_add_main_entries (context, options, NULL);
203   if (!g_option_context_parse (context, &argc, &argv, &error))
204     {
205       g_printerr ("%s: %s\n", argv[0], error->message);
206       return 1;
207     }
208
209   if (argc < 2)
210     {
211       g_printerr ("MODE argument required\n");
212       return 1;
213     }
214
215   mode = argv[1];
216   if (strcmp (mode, "noop") == 0)
217     return 0;
218   else if (strcmp (mode, "exit1") == 0)
219     return 1;
220   else if (strcmp (mode, "assert-argv0") == 0)
221     {
222       if (strcmp (argv[0], "moocow") == 0)
223         return 0;
224       g_printerr ("argv0=%s != moocow\n", argv[0]);
225       return 1;
226     }
227   else if (strcmp (mode, "echo") == 0)
228     return echo_mode (argc, argv);
229   else if (strcmp (mode, "echo-stdout-and-stderr") == 0)
230     return echo_stdout_and_stderr_mode (argc, argv);
231   else if (strcmp (mode, "cat") == 0)
232     return cat_mode (argc, argv);
233   else if (strcmp (mode, "sleep-forever") == 0)
234     return sleep_forever_mode (argc, argv);
235   else if (strcmp (mode, "write-to-fds") == 0)
236     return write_to_fds (argc, argv);
237   else if (strcmp (mode, "env") == 0)
238     return env_mode (argc, argv);
239   else if (strcmp (mode, "cwd") == 0)
240     return cwd_mode (argc, argv);
241   else if (strcmp (mode, "printenv") == 0)
242     return printenv_mode (argc, argv);
243   else
244     {
245       g_printerr ("Unknown MODE %s\n", argv[1]);
246       return 1;
247     }
248
249   return TRUE;
250 }