Include <config.h> first here, too. Use g_io_channel_read_chars() instead
[platform/upstream/glib.git] / glib / gspawn-win32.c
1 /* gspawn-win32.c - Process launching on Win32
2  *
3  *  Copyright 2000 Red Hat, Inc.
4  *
5  * GLib is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * GLib is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with GLib; see the file COPYING.LIB.  If not, write
17  * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Implementation details on Win32.
23  *
24  * - There is no way to set the no-inherit flag for
25  *   a "file descriptor" in the MS C runtime. The flag is there,
26  *   and the dospawn() function uses it, but unfortunately
27  *   this flag can only be set when opening the file.
28  * - As there is no fork(), we cannot reliably change directory
29  *   before starting the child process. (There might be several threads
30  *   running, and the current directory is common for all threads.)
31  *
32  * Thus, we must in most cases use a helper program to handle closing
33  * of (inherited) file descriptors and changing of directory. In fact,
34  * we do it all the time.
35  */
36
37 /* Define this to get some logging all the time */
38 /* #define G_SPAWN_WIN32_DEBUG */
39
40 #include <config.h>
41
42 #include "glib.h"
43
44 #include <string.h>
45 #include <stdlib.h>
46 #include <stdio.h>
47
48 #include <windows.h>
49 #include <errno.h>
50 #include <fcntl.h>
51 #include <io.h>
52 #include <process.h>
53 #include <direct.h>
54
55 #include "glibintl.h"
56
57 #ifdef G_SPAWN_WIN32_DEBUG
58   static int debug = 1;
59   #define SETUP_DEBUG() /* empty */
60
61 #else
62   static int debug = -1;
63   #define SETUP_DEBUG()                                 \
64     G_STMT_START                                        \
65       {                                                 \
66         if (debug == -1)                                \
67           {                                             \
68             if (getenv ("G_SPAWN_WIN32_DEBUG") != NULL) \
69               debug = 1;                                \
70             else                                        \
71               debug = 0;                                \
72           }                                             \
73       }                                                 \
74     G_STMT_END
75 #endif
76
77 enum
78 {
79   CHILD_NO_ERROR,
80   CHILD_CHDIR_FAILED,
81   CHILD_SPAWN_FAILED,
82 };
83
84 enum {
85   ARG_CHILD_ERR_REPORT = 1,
86   ARG_STDIN,
87   ARG_STDOUT,
88   ARG_STDERR,
89   ARG_WORKING_DIRECTORY,
90   ARG_CLOSE_DESCRIPTORS,
91   ARG_USE_PATH,
92   ARG_WAIT,
93   ARG_PROGRAM,
94   ARG_COUNT = ARG_PROGRAM
95 };
96
97 #ifndef GSPAWN_HELPER
98
99 static gboolean make_pipe            (gint                  p[2],
100                                       GError              **error);
101 static gboolean fork_exec_with_pipes (gboolean              dont_wait,
102                                       const gchar          *working_directory,
103                                       gchar               **argv,
104                                       gchar               **envp,
105                                       gboolean              close_descriptors,
106                                       gboolean              search_path,
107                                       gboolean              stdout_to_null,
108                                       gboolean              stderr_to_null,
109                                       gboolean              child_inherits_stdin,
110                                       GSpawnChildSetupFunc  child_setup,
111                                       gpointer              user_data,
112                                       gint                 *standard_input,
113                                       gint                 *standard_output,
114                                       gint                 *standard_error,
115                                       gint                 *exit_status,
116                                       GError              **error);
117
118 GQuark
119 g_spawn_error_quark (void)
120 {
121   static GQuark quark = 0;
122   if (quark == 0)
123     quark = g_quark_from_static_string ("g-exec-error-quark");
124   return quark;
125 }
126
127 /**
128  * g_spawn_async:
129  * @working_directory: child's current working directory, or %NULL to inherit parent's
130  * @argv: child's argument vector
131  * @envp: child's environment, or %NULL to inherit parent's
132  * @flags: flags from #GSpawnFlags
133  * @child_setup: function to run in the child just before <function>exec()</function>
134  * @user_data: user data for @child_setup
135  * @child_pid: return location for child process ID, or %NULL
136  * @error: return location for error
137  * 
138  * See g_spawn_async_with_pipes() for a full description; this function
139  * simply calls the g_spawn_async_with_pipes() without any pipes.
140  * 
141  * Return value: %TRUE on success, %FALSE if error is set
142  **/
143 gboolean
144 g_spawn_async (const gchar          *working_directory,
145                gchar               **argv,
146                gchar               **envp,
147                GSpawnFlags           flags,
148                GSpawnChildSetupFunc  child_setup,
149                gpointer              user_data,
150                gint                 *child_pid,
151                GError              **error)
152 {
153   g_return_val_if_fail (argv != NULL, FALSE);
154   
155   return g_spawn_async_with_pipes (working_directory,
156                                    argv, envp,
157                                    flags,
158                                    child_setup,
159                                    user_data,
160                                    child_pid,
161                                    NULL, NULL, NULL,
162                                    error);
163 }
164
165 /* Avoids a danger in threaded situations (calling close()
166  * on a file descriptor twice, and another thread has
167  * re-opened it since the first close)
168  */
169 static gint
170 close_and_invalidate (gint *fd)
171 {
172   gint ret;
173
174   ret = close (*fd);
175   *fd = -1;
176
177   return ret;
178 }
179
180 typedef enum
181 {
182   READ_FAILED = 0, /* FALSE */
183   READ_OK,
184   READ_EOF
185 } ReadResult;
186
187 static ReadResult
188 read_data (GString     *str,
189            GIOChannel  *iochannel,
190            GError     **error)
191 {
192   GIOStatus giostatus;
193   gint bytes;
194   gchar buf[4096];
195
196  again:
197   
198   giostatus = g_io_channel_read_chars (iochannel, buf, sizeof (buf), &bytes, NULL);
199
200   if (bytes == 0)
201     return READ_EOF;
202   else if (bytes > 0)
203     {
204       g_string_append_len (str, buf, bytes);
205       return READ_OK;
206     }
207   else if (giostatus == G_IO_STATUS_AGAIN)
208     goto again;
209   else if (giostatus == G_IO_STATUS_ERROR)
210     {
211       g_set_error (error,
212                    G_SPAWN_ERROR,
213                    G_SPAWN_ERROR_READ,
214                    _("Failed to read data from child process"));
215       
216       return READ_FAILED;
217     }
218   else
219     return READ_OK;
220 }
221
222 /**
223  * g_spawn_sync:
224  * @working_directory: child's current working directory, or %NULL to inherit parent's
225  * @argv: child's argument vector
226  * @envp: child's environment, or %NULL to inherit parent's
227  * @flags: flags from #GSpawnFlags
228  * @child_setup: function to run in the child just before <function>exec()</function>
229  * @user_data: user data for @child_setup
230  * @standard_output: return location for child output 
231  * @standard_error: return location for child error messages
232  * @exit_status: child exit status, as returned by <function>waitpid()</function>
233  * @error: return location for error
234  *
235  * Executes a child synchronously (waits for the child to exit before returning).
236  * All output from the child is stored in @standard_output and @standard_error,
237  * if those parameters are non-%NULL. If @exit_status is non-%NULL, the exit status
238  * of the child is stored there as it would be returned by <function>waitpid()</function>; standard UNIX
239  * macros such as <function>WIFEXITED()</function> and <function>WEXITSTATUS()</function> must be used to evaluate the
240  * exit status. If an error occurs, no data is returned in @standard_output,
241  * @standard_error, or @exit_status.
242  * 
243  * This function calls g_spawn_async_with_pipes() internally; see that function
244  * for full details on the other parameters.
245  * 
246  * Return value: %TRUE on success, %FALSE if an error was set.
247  **/
248 gboolean
249 g_spawn_sync (const gchar          *working_directory,
250               gchar               **argv,
251               gchar               **envp,
252               GSpawnFlags           flags,
253               GSpawnChildSetupFunc  child_setup,
254               gpointer              user_data,
255               gchar               **standard_output,
256               gchar               **standard_error,
257               gint                 *exit_status,
258               GError              **error)     
259 {
260   gint outpipe = -1;
261   gint errpipe = -1;
262   GIOChannel *outchannel = NULL;
263   GIOChannel *errchannel = NULL;
264   GPollFD outfd, errfd;
265   GPollFD fds[2];
266   gint nfds;
267   gint outindex = -1;
268   gint errindex = -1;
269   gint ret;
270   GString *outstr = NULL;
271   GString *errstr = NULL;
272   gboolean failed;
273   gint status;
274   
275   g_return_val_if_fail (argv != NULL, FALSE);
276   g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
277   g_return_val_if_fail (standard_output == NULL ||
278                         !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
279   g_return_val_if_fail (standard_error == NULL ||
280                         !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
281   
282   /* Just to ensure segfaults if callers try to use
283    * these when an error is reported.
284    */
285   if (standard_output)
286     *standard_output = NULL;
287
288   if (standard_error)
289     *standard_error = NULL;
290   
291   if (!fork_exec_with_pipes (FALSE,
292                              working_directory,
293                              argv,
294                              envp,
295                              !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
296                              (flags & G_SPAWN_SEARCH_PATH) != 0,
297                              (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
298                              (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
299                              (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
300                              child_setup,
301                              user_data,
302                              NULL,
303                              standard_output ? &outpipe : NULL,
304                              standard_error ? &errpipe : NULL,
305                              &status,
306                              error))
307     return FALSE;
308
309   /* Read data from child. */
310   
311   failed = FALSE;
312
313   if (outpipe >= 0)
314     {
315       outstr = g_string_new ("");
316       outchannel = g_io_channel_win32_new_fd (outpipe);
317       g_io_channel_set_encoding (outchannel, NULL, NULL);
318       g_io_channel_win32_make_pollfd (outchannel,
319                                       G_IO_IN | G_IO_ERR | G_IO_HUP,
320                                       &outfd);
321     }
322       
323   if (errpipe >= 0)
324     {
325       errstr = g_string_new ("");
326       errchannel = g_io_channel_win32_new_fd (errpipe);
327       g_io_channel_set_encoding (errchannel, NULL, NULL);
328       g_io_channel_win32_make_pollfd (errchannel,
329                                       G_IO_IN | G_IO_ERR | G_IO_HUP,
330                                       &errfd);
331     }
332
333   /* Read data until we get EOF on both pipes. */
334   while (!failed &&
335          (outpipe >= 0 ||
336           errpipe >= 0))
337     {
338       nfds = 0;
339       if (outpipe >= 0)
340         {
341           fds[nfds] = outfd;
342           outindex = nfds;
343           nfds++;
344         }
345       if (errpipe >= 0)
346         {
347           fds[nfds] = errfd;
348           errindex = nfds;
349           nfds++;
350         }
351
352       if (debug)
353         g_print ("%s:g_spawn_sync: calling g_io_channel_win32_poll, nfds=%d\n",
354                  __FILE__, nfds);
355
356       ret = g_io_channel_win32_poll (fds, nfds, -1);
357
358       if (ret < 0)
359         {
360           failed = TRUE;
361
362           g_set_error (error,
363                        G_SPAWN_ERROR,
364                        G_SPAWN_ERROR_READ,
365                        _("Unexpected error in g_io_channel_win32_poll() reading data from a child process"));
366               
367           break;
368         }
369
370       if (outpipe >= 0 && (fds[outindex].revents & G_IO_IN))
371         {
372           switch (read_data (outstr, outchannel, error))
373             {
374             case READ_FAILED:
375               if (debug)
376                 g_print ("g_spawn_sync: outchannel: READ_FAILED\n");
377               failed = TRUE;
378               break;
379             case READ_EOF:
380               if (debug)
381                 g_print ("g_spawn_sync: outchannel: READ_EOF\n");
382               g_io_channel_unref (outchannel);
383               outchannel = NULL;
384               close_and_invalidate (&outpipe);
385               break;
386             default:
387               if (debug)
388                 g_print ("g_spawn_sync: outchannel: OK\n");
389               break;
390             }
391
392           if (failed)
393             break;
394         }
395
396       if (errpipe >= 0 && (fds[errindex].revents & G_IO_IN))
397         {
398           switch (read_data (errstr, errchannel, error))
399             {
400             case READ_FAILED:
401               if (debug)
402                 g_print ("g_spawn_sync: errchannel: READ_FAILED\n");
403               failed = TRUE;
404               break;
405             case READ_EOF:
406               if (debug)
407                 g_print ("g_spawn_sync: errchannel: READ_EOF\n");
408               g_io_channel_unref (errchannel);
409               errchannel = NULL;
410               close_and_invalidate (&errpipe);
411               break;
412             default:
413               if (debug)
414                 g_print ("g_spawn_sync: errchannel: OK\n");
415               break;
416             }
417
418           if (failed)
419             break;
420         }
421     }
422
423   /* These should only be open still if we had an error.  */
424   
425   if (outchannel != NULL)
426     g_io_channel_unref (outchannel);
427   if (errchannel != NULL)
428     g_io_channel_unref (errchannel);
429   if (outpipe >= 0)
430     close_and_invalidate (&outpipe);
431   if (errpipe >= 0)
432     close_and_invalidate (&errpipe);
433   
434   if (failed)
435     {
436       if (outstr)
437         g_string_free (outstr, TRUE);
438       if (errstr)
439         g_string_free (errstr, TRUE);
440
441       return FALSE;
442     }
443   else
444     {
445       if (exit_status)
446         *exit_status = status;
447       
448       if (standard_output)        
449         *standard_output = g_string_free (outstr, FALSE);
450
451       if (standard_error)
452         *standard_error = g_string_free (errstr, FALSE);
453
454       return TRUE;
455     }
456 }
457
458 /**
459  * g_spawn_async_with_pipes:
460  * @working_directory: child's current working directory, or %NULL to inherit parent's
461  * @argv: child's argument vector
462  * @envp: child's environment, or %NULL to inherit parent's
463  * @flags: flags from #GSpawnFlags
464  * @child_setup: function to run in the child just before <function>exec()</function>
465  * @user_data: user data for @child_setup
466  * @child_pid: return location for child process ID, or %NULL
467  * @standard_input: return location for file descriptor to write to child's stdin, or %NULL
468  * @standard_output: return location for file descriptor to read child's stdout, or %NULL
469  * @standard_error: return location for file descriptor to read child's stderr, or %NULL
470  * @error: return location for error
471  *
472  * Executes a child program asynchronously (your program will not
473  * block waiting for the child to exit). The child program is
474  * specified by the only argument that must be provided, @argv. @argv
475  * should be a %NULL-terminated array of strings, to be passed as the
476  * argument vector for the child. The first string in @argv is of
477  * course the name of the program to execute. By default, the name of
478  * the program must be a full path; the <envar>PATH</envar> shell variable will only
479  * be searched if you pass the %G_SPAWN_SEARCH_PATH flag.
480  *
481  * @envp is a %NULL-terminated array of strings, where each string
482  * has the form <literal>KEY=VALUE</literal>. This will become
483  * the child's environment. If @envp is %NULL, the child inherits its
484  * parent's environment.
485  *
486  * @flags should be the bitwise OR of any flags you want to affect the
487  * function's behavior. The %G_SPAWN_DO_NOT_REAP_CHILD means that the
488  * child will not be automatically reaped; you must call 
489  * <function>waitpid()</function> or handle %SIGCHLD yourself, or the 
490  * child will become a zombie. %G_SPAWN_LEAVE_DESCRIPTORS_OPEN means 
491  * that the parent's open file descriptors will be inherited by the child; 
492  * otherwise all descriptors except stdin/stdout/stderr will be closed before
493  * calling <function>exec()</function> in the child. %G_SPAWN_SEARCH_PATH 
494  * means that <literal>argv[0]</literal> need not be an absolute path, it
495  * will be looked for in the user's <envar>PATH</envar>. 
496  * %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output 
497  * will be discarded, instead of going to the same location as the parent's 
498  * standard output. %G_SPAWN_STDERR_TO_DEV_NULL means that the child's 
499  * standard error will be discarded. %G_SPAWN_CHILD_INHERITS_STDIN means that
500  * the child will inherit the parent's standard input (by default,
501  * the child's standard input is attached to /dev/null).
502  *
503  * @child_setup and @user_data are a function and user data to be
504  * called in the child after GLib has performed all the setup it plans
505  * to perform (including creating pipes, closing file descriptors,
506  * etc.) but before calling <function>exec()</function>. That is, @child_setup 
507  * is called just before calling <function>exec()</function> in the child. 
508  * Obviously actions taken in this function will only affect the child, not 
509  * the parent. 
510  *
511  * If non-%NULL, @child_pid will be filled with the child's process
512  * ID. You can use the process ID to send signals to the child, or
513  * to <function>waitpid()</function> if you specified the 
514  * %G_SPAWN_DO_NOT_REAP_CHILD flag.
515  *
516  * If non-%NULL, the @standard_input, @standard_output, @standard_error
517  * locations will be filled with file descriptors for writing to the child's
518  * standard input or reading from its standard output or standard error.
519  * The caller of g_spawn_async_with_pipes() must close these file descriptors
520  * when they are no longer in use. If these parameters are %NULL, the
521  * corresponding pipe won't be created.
522  *
523  * @error can be %NULL to ignore errors, or non-%NULL to report errors.
524  * If an error is set, the function returns %FALSE. Errors
525  * are reported even if they occur in the child (for example if the
526  * executable in <literal>argv[0]</literal> is not found). Typically
527  * the <literal>message</literal> field of returned errors should be displayed
528  * to users. Possible errors are those from the #G_SPAWN_ERROR domain.
529  *
530  * If an error occurs, @child_pid, @standard_input, @standard_output,
531  * and @standard_error will not be filled with valid values.
532  * 
533  * Return value: %TRUE on success, %FALSE if an error was set
534  **/
535 gboolean
536 g_spawn_async_with_pipes (const gchar          *working_directory,
537                           gchar               **argv,
538                           gchar               **envp,
539                           GSpawnFlags           flags,
540                           GSpawnChildSetupFunc  child_setup,
541                           gpointer              user_data,
542                           gint                 *child_pid,
543                           gint                 *standard_input,
544                           gint                 *standard_output,
545                           gint                 *standard_error,
546                           GError              **error)
547 {
548   g_return_val_if_fail (argv != NULL, FALSE);
549   g_return_val_if_fail (standard_output == NULL ||
550                         !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
551   g_return_val_if_fail (standard_error == NULL ||
552                         !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
553   /* can't inherit stdin if we have an input pipe. */
554   g_return_val_if_fail (standard_input == NULL ||
555                         !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
556   
557   return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD),
558                                working_directory,
559                                argv,
560                                envp,
561                                !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
562                                (flags & G_SPAWN_SEARCH_PATH) != 0,
563                                (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
564                                (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
565                                (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
566                                child_setup,
567                                user_data,
568                                standard_input,
569                                standard_output,
570                                standard_error,
571                                NULL,
572                                error);
573 }
574
575 /**
576  * g_spawn_command_line_sync:
577  * @command_line: a command line 
578  * @standard_output: return location for child output
579  * @standard_error: return location for child errors
580  * @exit_status: return location for child exit status
581  * @error: return location for errors
582  *
583  * A simple version of g_spawn_sync() with little-used parameters
584  * removed, taking a command line instead of an argument vector.  See
585  * g_spawn_sync() for full details. @command_line will be parsed by
586  * g_shell_parse_argv(). Unlike g_spawn_sync(), the %G_SPAWN_SEARCH_PATH flag
587  * is enabled. Note that %G_SPAWN_SEARCH_PATH can have security
588  * implications, so consider using g_spawn_sync() directly if
589  * appropriate. Possible errors are those from g_spawn_sync() and those
590  * from g_shell_parse_argv().
591  * 
592  * Return value: %TRUE on success, %FALSE if an error was set
593  **/
594 gboolean
595 g_spawn_command_line_sync (const gchar  *command_line,
596                            gchar       **standard_output,
597                            gchar       **standard_error,
598                            gint         *exit_status,
599                            GError      **error)
600 {
601   gboolean retval;
602   gchar **argv = 0;
603
604   g_return_val_if_fail (command_line != NULL, FALSE);
605   
606   if (!g_shell_parse_argv (command_line,
607                            NULL, &argv,
608                            error))
609     return FALSE;
610   
611   retval = g_spawn_sync (NULL,
612                          argv,
613                          NULL,
614                          G_SPAWN_SEARCH_PATH,
615                          NULL,
616                          NULL,
617                          standard_output,
618                          standard_error,
619                          exit_status,
620                          error);
621   g_strfreev (argv);
622
623   return retval;
624 }
625
626 /**
627  * g_spawn_command_line_async:
628  * @command_line: a command line
629  * @error: return location for errors
630  * 
631  * A simple version of g_spawn_async() that parses a command line with
632  * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a
633  * command line in the background. Unlike g_spawn_async(), the
634  * %G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
635  * that %G_SPAWN_SEARCH_PATH can have security implications, so
636  * consider using g_spawn_async() directly if appropriate. Possible
637  * errors are those from g_shell_parse_argv() and g_spawn_async().
638  * 
639  * Return value: %TRUE on success, %FALSE if error is set.
640  **/
641 gboolean
642 g_spawn_command_line_async (const gchar *command_line,
643                             GError     **error)
644 {
645   gboolean retval;
646   gchar **argv = 0;
647
648   g_return_val_if_fail (command_line != NULL, FALSE);
649
650   if (!g_shell_parse_argv (command_line,
651                            NULL, &argv,
652                            error))
653     return FALSE;
654   
655   retval = g_spawn_async (NULL,
656                           argv,
657                           NULL,
658                           G_SPAWN_SEARCH_PATH,
659                           NULL,
660                           NULL,
661                           NULL,
662                           error);
663   g_strfreev (argv);
664
665   return retval;
666 }
667
668 static gint
669 do_exec (gboolean              dont_wait,
670          gint                  child_err_report_fd,
671          gint                  stdin_fd,
672          gint                  stdout_fd,
673          gint                  stderr_fd,
674          const gchar          *working_directory,
675          gchar               **argv,
676          gchar               **envp,
677          gboolean              close_descriptors,
678          gboolean              search_path,
679          gboolean              stdout_to_null,
680          gboolean              stderr_to_null,
681          gboolean              child_inherits_stdin,
682          GSpawnChildSetupFunc  child_setup,
683          gpointer              user_data)
684 {
685   gchar **new_argv;
686   gchar args[ARG_COUNT][10];
687   gint i;
688   int argc = 0;
689
690   SETUP_DEBUG();
691
692   while (argv[argc])
693     ++argc;
694
695   new_argv = g_new (gchar *, argc + 1 + ARG_COUNT);
696
697   new_argv[0] = "gspawn-win32-helper";
698   sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_fd);
699   new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
700
701   if (stdin_fd >= 0)
702     {
703       sprintf (args[ARG_STDIN], "%d", stdin_fd);
704       new_argv[ARG_STDIN] = args[ARG_STDIN];
705     }
706   else if (child_inherits_stdin)
707     {
708       /* Let stdin be alone */
709       new_argv[ARG_STDIN] = "-";
710     }
711   else
712     {
713       /* Keep process from blocking on a read of stdin */
714       new_argv[ARG_STDIN] = "z";
715     }
716
717   if (stdout_fd >= 0)
718     {
719       sprintf (args[ARG_STDOUT], "%d", stdout_fd);
720       new_argv[ARG_STDOUT] = args[ARG_STDOUT];
721     }
722   else if (stdout_to_null)
723     {
724       new_argv[ARG_STDOUT] = "z";
725     }
726   else
727     {
728       new_argv[ARG_STDOUT] = "-";
729     }
730
731   if (stderr_fd >= 0)
732     {
733       sprintf (args[ARG_STDERR], "%d", stderr_fd);
734       new_argv[ARG_STDERR] = args[ARG_STDERR];
735     }
736   else if (stderr_to_null)
737     {
738       new_argv[ARG_STDERR] = "z";
739     }
740   else
741     {
742       new_argv[ARG_STDERR] = "-";
743     }
744
745   if (working_directory && *working_directory)
746     new_argv[ARG_WORKING_DIRECTORY] = working_directory;
747   else
748     new_argv[ARG_WORKING_DIRECTORY] = "-";
749
750   if (close_descriptors)
751     new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
752   else
753     new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
754
755   if (search_path)
756     new_argv[ARG_USE_PATH] = "y";
757   else
758     new_argv[ARG_USE_PATH] = "-";
759
760   if (dont_wait)
761     new_argv[ARG_WAIT] = "-";
762   else
763     new_argv[ARG_WAIT] = "w";
764
765   for (i = 0; i <= argc; i++)
766     new_argv[ARG_PROGRAM + i] = argv[i];
767
768   /* Call user function just before we execute the helper program,
769    * which executes the program. Dunno what's the usefulness of this.
770    * A child setup function used on Unix probably isn't of much use
771    * as such on Win32, anyhow
772    */
773   if (child_setup)
774     {
775       (* child_setup) (user_data);
776     }
777
778   if (debug)
779     {
780       g_print ("calling gspawn-win32-helper with argv:\n");
781       for (i = 0; i < argc + 1 + ARG_COUNT; i++)
782         g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL"));
783     }
784   
785   if (envp != NULL)
786     /* Let's hope envp hasn't mucked with PATH so that
787      * gspawn-win32-helper.exe isn't found.
788      */
789     spawnvpe (P_NOWAIT, "gspawn-win32-helper", new_argv, envp);
790   else
791     spawnvp (P_NOWAIT, "gspawn-win32-helper", new_argv);
792
793   /* FIXME: What if gspawn-win32-helper.exe isn't found? */
794
795   /* Close the child_err_report_fd and the other process's ends of the
796    * pipes in this process, otherwise the reader will never get
797    * EOF.
798    */
799   close (child_err_report_fd);
800   if (stdin_fd >= 0)
801     close (stdin_fd);
802   if (stdout_fd >= 0)
803     close (stdout_fd);
804   if (stderr_fd >= 0)
805     close (stderr_fd);
806
807   g_free (new_argv);
808
809   return 0;
810 }
811
812 static gboolean
813 read_ints (int      fd,
814            gint*    buf,
815            gint     n_ints_in_buf,
816            gint    *n_ints_read,
817            GError **error)
818 {
819   gint bytes = 0;
820   
821   while (bytes < sizeof(gint)*n_ints_in_buf)
822     {
823       gint chunk;
824
825       if (debug)
826         g_print ("%s:read_ints: trying to read %d bytes from pipe...\n",
827                  __FILE__,
828                  sizeof(gint)*n_ints_in_buf - bytes);
829
830       chunk = read (fd, ((gchar*)buf) + bytes,
831                     sizeof(gint)*n_ints_in_buf - bytes);
832
833       if (debug)
834         g_print ("... got %d bytes\n", chunk);
835           
836       if (chunk < 0)
837         {
838           /* Some weird shit happened, bail out */
839               
840           g_set_error (error,
841                        G_SPAWN_ERROR,
842                        G_SPAWN_ERROR_FAILED,
843                        _("Failed to read from child pipe (%s)"),
844                        g_strerror (errno));
845
846           return FALSE;
847         }
848       else if (chunk == 0)
849         break; /* EOF */
850       else
851         bytes += chunk;
852     }
853
854   *n_ints_read = bytes/sizeof(gint);
855
856   return TRUE;
857 }
858
859 static gboolean
860 fork_exec_with_pipes (gboolean              dont_wait,
861                       const gchar          *working_directory,
862                       gchar               **argv,
863                       gchar               **envp,
864                       gboolean              close_descriptors,
865                       gboolean              search_path,
866                       gboolean              stdout_to_null,
867                       gboolean              stderr_to_null,
868                       gboolean              child_inherits_stdin,
869                       GSpawnChildSetupFunc  child_setup,
870                       gpointer              user_data,
871                       gint                 *standard_input,
872                       gint                 *standard_output,
873                       gint                 *standard_error,
874                       gint                 *exit_status,
875                       GError              **error)     
876 {
877   gint stdin_pipe[2] = { -1, -1 };
878   gint stdout_pipe[2] = { -1, -1 };
879   gint stderr_pipe[2] = { -1, -1 };
880   gint child_err_report_pipe[2] = { -1, -1 };
881   gint status;
882   gint buf[2];
883   gint n_ints = 0;
884   
885   if (!make_pipe (child_err_report_pipe, error))
886     return FALSE;
887
888   if (standard_input && !make_pipe (stdin_pipe, error))
889     goto cleanup_and_fail;
890   
891   if (standard_output && !make_pipe (stdout_pipe, error))
892     goto cleanup_and_fail;
893
894   if (standard_error && !make_pipe (stderr_pipe, error))
895     goto cleanup_and_fail;
896
897   status = do_exec (dont_wait,
898                     child_err_report_pipe[1],
899                     stdin_pipe[0],
900                     stdout_pipe[1],
901                     stderr_pipe[1],
902                     working_directory,
903                     argv,
904                     envp,
905                     close_descriptors,
906                     search_path,
907                     stdout_to_null,
908                     stderr_to_null,
909                     child_inherits_stdin,
910                     child_setup,
911                     user_data);
912       
913   if (!read_ints (child_err_report_pipe[0],
914                   buf, 2, &n_ints,
915                   error))
916     goto cleanup_and_fail;
917         
918   if (n_ints == 2)
919     {
920       /* Error from the child. */
921       
922       switch (buf[0])
923         {
924         case CHILD_NO_ERROR:
925           break;
926           
927         case CHILD_CHDIR_FAILED:
928           g_set_error (error,
929                        G_SPAWN_ERROR,
930                        G_SPAWN_ERROR_CHDIR,
931                        _("Failed to change to directory '%s' (%s)"),
932                        working_directory,
933                        g_strerror (buf[1]));
934           goto cleanup_and_fail;
935           
936         case CHILD_SPAWN_FAILED:
937           g_set_error (error,
938                        G_SPAWN_ERROR,
939                        G_SPAWN_ERROR_FAILED,
940                        _("Failed to execute child process (%s)"),
941                        g_strerror (buf[1]));
942           goto cleanup_and_fail;
943         }
944     }
945
946   /* Success against all odds! return the information */
947       
948   if (standard_input)
949     *standard_input = stdin_pipe[1];
950   if (standard_output)
951     *standard_output = stdout_pipe[0];
952   if (standard_error)
953     *standard_error = stderr_pipe[0];
954   if (exit_status)
955     *exit_status = status;
956   
957   return TRUE;
958
959  cleanup_and_fail:
960   close_and_invalidate (&child_err_report_pipe[0]);
961   close_and_invalidate (&child_err_report_pipe[1]);
962   close_and_invalidate (&stdin_pipe[0]);
963   close_and_invalidate (&stdin_pipe[1]);
964   close_and_invalidate (&stdout_pipe[0]);
965   close_and_invalidate (&stdout_pipe[1]);
966   close_and_invalidate (&stderr_pipe[0]);
967   close_and_invalidate (&stderr_pipe[1]);
968
969   return FALSE;
970 }
971
972 static gboolean
973 make_pipe (gint     p[2],
974            GError **error)
975 {
976   if (pipe (p) < 0)
977     {
978       g_set_error (error,
979                    G_SPAWN_ERROR,
980                    G_SPAWN_ERROR_FAILED,
981                    _("Failed to create pipe for communicating with child process (%s)"),
982                    g_strerror (errno));
983       return FALSE;
984     }
985   else
986     return TRUE;
987 }
988
989 #endif /* !GSPAWN_HELPER */