1/* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22 * file for a list of people on the GLib Team.  See the ChangeLog
23 * files for a list of changes.  These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27#undef G_DISABLE_ASSERT
28#undef G_LOG_DOMAIN
29
30#include <glib.h>
31#include <stdio.h>
32#include <string.h>
33#include <stdlib.h>
34
35#ifdef G_OS_WIN32
36#include <fcntl.h>
37#include <io.h>
38#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
39#endif
40
41
42static void
43run_tests (void)
44{
45  GError *err;
46  gchar *output = NULL;
47#ifdef G_OS_WIN32
48  gchar *erroutput = NULL;
49  int pipedown[2], pipeup[2];
50  gchar **argv = 0;
51#endif
52
53  err = NULL;
54  if (!g_spawn_command_line_sync ("nonexistent_application foo 'bar baz' blah blah",
55                                  NULL, NULL, NULL,
56                                  &err))
57    {
58      g_error_free (err);
59    }
60  else
61    {
62      g_warning ("no error for sync spawn of nonexistent application");
63      exit (1);
64    }
65
66  err = NULL;
67  if (!g_spawn_command_line_async ("nonexistent_application foo bar baz \"blah blah\"",
68                                   &err))
69    {
70      g_error_free (err);
71    }
72  else
73    {
74      g_warning ("no error for async spawn of nonexistent application");
75      exit (1);
76    }
77
78  err = NULL;
79#ifdef G_OS_UNIX
80  if (!g_spawn_command_line_sync ("/bin/sh -c 'echo hello'",
81                                  &output, NULL, NULL,
82                                  &err))
83    {
84      fprintf (stderr, "Error: %s\n", err->message);
85      g_error_free (err);
86      exit (1);
87    }
88  else
89    {
90      g_assert (output != NULL);
91
92      if (strcmp (output, "hello\n") != 0)
93        {
94          printf ("output was '%s', should have been 'hello'\n",
95                  output);
96
97          exit (1);
98        }
99
100      g_free (output);
101    }
102#else
103#ifdef G_OS_WIN32
104  printf ("Running netstat synchronously, collecting its output\n");
105
106  if (!g_spawn_command_line_sync ("netstat -n",
107                                  &output, &erroutput, NULL,
108                                  &err))
109    {
110      fprintf (stderr, "Error: %s\n", err->message);
111      g_error_free (err);
112      exit (1);
113    }
114  else
115    {
116      g_assert (output != NULL);
117      g_assert (erroutput != NULL);
118
119      if (strstr (output, "Active Connections") == 0)
120        {
121          printf ("output was '%s', should have contained 'Active Connections'\n",
122                  output);
123
124          exit (1);
125        }
126      if (erroutput[0] != '\0')
127	{
128	  printf ("error output was '%s', should have been empty\n",
129		  erroutput);
130	  exit (1);
131	}
132
133      g_free (output);
134      output = NULL;
135      g_free (erroutput);
136      erroutput = NULL;
137    }
138
139  printf ("Running spawn-test-win32-gui in various ways. Click on the OK buttons.\n");
140
141  printf ("First asynchronously (without wait).\n");
142
143  if (!g_spawn_command_line_async ("'.\\spawn-test-win32-gui.exe' 1", &err))
144    {
145      fprintf (stderr, "Error: %s\n", err->message);
146      g_error_free (err);
147      exit (1);
148    }
149
150  printf ("Now synchronously, collecting its output.\n");
151  if (!g_spawn_command_line_sync ("'.\\spawn-test-win32-gui.exe' 2",
152				  &output, &erroutput, NULL,
153				  &err))
154    {
155      fprintf (stderr, "Error: %s\n", err->message);
156      g_error_free (err);
157      exit (1);
158    }
159  else
160    {
161      g_assert (output != NULL);
162      g_assert (erroutput != NULL);
163
164      if (strcmp (output, "This is stdout\r\n") != 0)
165        {
166          printf ("output was '%s', should have been 'This is stdout'\n",
167                  g_strescape (output, NULL));
168
169          exit (1);
170        }
171      if (strcmp (erroutput, "This is stderr\r\n") != 0)
172	{
173	  printf ("error output was '%s', should have been 'This is stderr'\n",
174		  g_strescape (erroutput, NULL));
175	  exit (1);
176	}
177
178      g_free (output);
179      g_free (erroutput);
180    }
181
182  printf ("Now with G_SPAWN_FILE_AND_ARGV_ZERO.\n");
183
184  if (!g_shell_parse_argv ("'.\\spawn-test-win32-gui.exe' this-should-be-argv-zero nop", NULL, &argv, &err))
185    {
186      fprintf (stderr, "Error parsing command line? %s\n", err->message);
187      g_error_free (err);
188      exit (1);
189    }
190
191  if (!g_spawn_async (NULL, argv, NULL,
192		      G_SPAWN_FILE_AND_ARGV_ZERO,
193		      NULL, NULL, NULL,
194		      &err))
195    {
196      fprintf (stderr, "Error: %s\n", err->message);
197      g_error_free (err);
198      exit (1);
199    }
200
201  printf ("Now talking to it through pipes.\n");
202
203  if (pipe (pipedown) < 0 ||
204      pipe (pipeup) < 0)
205    {
206      fprintf (stderr, "Could not create pipes\n");
207      exit (1);
208    }
209
210  if (!g_shell_parse_argv (g_strdup_printf ("'.\\spawn-test-win32-gui.exe' pipes %d %d",
211					    pipedown[0], pipeup[1]),
212                           NULL, &argv,
213                           &err))
214    {
215      fprintf (stderr, "Error parsing command line? %s\n", err->message);
216      g_error_free (err);
217      exit (1);
218    }
219
220  if (!g_spawn_async (NULL, argv, NULL,
221		      G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
222		      G_SPAWN_DO_NOT_REAP_CHILD,
223		      NULL, NULL, NULL,
224		      &err))
225    {
226      fprintf (stderr, "Error: %s\n", err->message);
227      g_error_free (err);
228      exit (1);
229    }
230  else
231    {
232      int k, n;
233      char buf[100];
234
235      if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n))
236	{
237	  if (k == -1)
238	    fprintf (stderr, "Read error: %s\n", g_strerror (errno));
239	  else
240	    fprintf (stderr, "Wanted to read %d bytes, got %d\n",
241		     sizeof (n), k);
242	  exit (1);
243	}
244
245      if ((k = read (pipeup[0], buf, n)) != n)
246	{
247	  if (k == -1)
248	    fprintf (stderr, "Read error: %s\n", g_strerror (errno));
249	  else
250	    fprintf (stderr, "Wanted to read %d bytes, got %d\n",
251		     n, k);
252	  exit (1);
253	}
254
255      n = strlen ("Bye then");
256      if (write (pipedown[1], &n, sizeof (n)) == -1 ||
257	  write (pipedown[1], "Bye then", n) == -1)
258	{
259	  fprintf (stderr, "Write error: %s\n", g_strerror (errno));
260	  exit (1);
261	}
262
263      if ((k = read (pipeup[0], &n, sizeof (n))) != sizeof (n))
264	{
265	  if (k == -1)
266	    fprintf (stderr, "Read error: %s\n", g_strerror (errno));
267	  else
268	    fprintf (stderr, "Wanted to read %d bytes, got %d\n",
269		     sizeof (n), k);
270	  exit (1);
271	}
272
273      if ((k = read (pipeup[0], buf, n)) != n)
274	{
275	  if (k == -1)
276	    fprintf (stderr, "Read error: %s\n", g_strerror (errno));
277	  else
278	    fprintf (stderr, "Wanted to read %d bytes, got %d\n",
279		     n, k);
280	  exit (1);
281	}
282    }
283#endif
284#endif
285}
286
287int
288main (int   argc,
289      char *argv[])
290{
291  run_tests ();
292
293  return 0;
294}
295