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