1 /* gspawn-win32.c - Process launching on Win32
3 * Copyright 2000 Red Hat, Inc.
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.
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.
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.
22 * Implementation details on Win32.
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.)
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.
37 /* Define this to get some logging all the time */
38 /* #define G_SPAWN_WIN32_DEBUG */
57 #ifdef G_SPAWN_WIN32_DEBUG
59 #define SETUP_DEBUG() /* empty */
62 static int debug = -1;
63 #define SETUP_DEBUG() \
68 if (getenv ("G_SPAWN_WIN32_DEBUG") != NULL) \
85 ARG_CHILD_ERR_REPORT = 1,
89 ARG_WORKING_DIRECTORY,
90 ARG_CLOSE_DESCRIPTORS,
94 ARG_COUNT = ARG_PROGRAM
99 static gboolean make_pipe (gint p[2],
101 static gboolean fork_exec_with_pipes (gboolean dont_wait,
102 const gchar *working_directory,
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,
112 gint *standard_input,
113 gint *standard_output,
114 gint *standard_error,
119 g_spawn_error_quark (void)
121 static GQuark quark = 0;
123 quark = g_quark_from_static_string ("g-exec-error-quark");
128 g_spawn_async (const gchar *working_directory,
132 GSpawnChildSetupFunc child_setup,
137 g_return_val_if_fail (argv != NULL, FALSE);
139 return g_spawn_async_with_pipes (working_directory,
149 /* Avoids a danger in threaded situations (calling close()
150 * on a file descriptor twice, and another thread has
151 * re-opened it since the first close)
154 close_and_invalidate (gint *fd)
166 READ_FAILED = 0, /* FALSE */
172 read_data (GString *str,
173 GIOChannel *iochannel,
182 giostatus = g_io_channel_read_chars (iochannel, buf, sizeof (buf), &bytes, NULL);
188 g_string_append_len (str, buf, bytes);
191 else if (giostatus == G_IO_STATUS_AGAIN)
193 else if (giostatus == G_IO_STATUS_ERROR)
198 _("Failed to read data from child process"));
207 g_spawn_sync (const gchar *working_directory,
211 GSpawnChildSetupFunc child_setup,
213 gchar **standard_output,
214 gchar **standard_error,
220 GIOChannel *outchannel = NULL;
221 GIOChannel *errchannel = NULL;
222 GPollFD outfd, errfd;
228 GString *outstr = NULL;
229 GString *errstr = NULL;
233 g_return_val_if_fail (argv != NULL, FALSE);
234 g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
235 g_return_val_if_fail (standard_output == NULL ||
236 !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
237 g_return_val_if_fail (standard_error == NULL ||
238 !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
240 /* Just to ensure segfaults if callers try to use
241 * these when an error is reported.
244 *standard_output = NULL;
247 *standard_error = NULL;
249 if (!fork_exec_with_pipes (FALSE,
253 !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
254 (flags & G_SPAWN_SEARCH_PATH) != 0,
255 (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
256 (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
257 (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
261 standard_output ? &outpipe : NULL,
262 standard_error ? &errpipe : NULL,
267 /* Read data from child. */
273 outstr = g_string_new ("");
274 outchannel = g_io_channel_win32_new_fd (outpipe);
275 g_io_channel_set_encoding (outchannel, NULL, NULL);
276 g_io_channel_win32_make_pollfd (outchannel,
277 G_IO_IN | G_IO_ERR | G_IO_HUP,
283 errstr = g_string_new ("");
284 errchannel = g_io_channel_win32_new_fd (errpipe);
285 g_io_channel_set_encoding (errchannel, NULL, NULL);
286 g_io_channel_win32_make_pollfd (errchannel,
287 G_IO_IN | G_IO_ERR | G_IO_HUP,
291 /* Read data until we get EOF on both pipes. */
311 g_print ("%s:g_spawn_sync: calling g_io_channel_win32_poll, nfds=%d\n",
314 ret = g_io_channel_win32_poll (fds, nfds, -1);
323 _("Unexpected error in g_io_channel_win32_poll() reading data from a child process"));
328 if (outpipe >= 0 && (fds[outindex].revents & G_IO_IN))
330 switch (read_data (outstr, outchannel, error))
334 g_print ("g_spawn_sync: outchannel: READ_FAILED\n");
339 g_print ("g_spawn_sync: outchannel: READ_EOF\n");
340 g_io_channel_unref (outchannel);
342 close_and_invalidate (&outpipe);
346 g_print ("g_spawn_sync: outchannel: OK\n");
354 if (errpipe >= 0 && (fds[errindex].revents & G_IO_IN))
356 switch (read_data (errstr, errchannel, error))
360 g_print ("g_spawn_sync: errchannel: READ_FAILED\n");
365 g_print ("g_spawn_sync: errchannel: READ_EOF\n");
366 g_io_channel_unref (errchannel);
368 close_and_invalidate (&errpipe);
372 g_print ("g_spawn_sync: errchannel: OK\n");
381 /* These should only be open still if we had an error. */
383 if (outchannel != NULL)
384 g_io_channel_unref (outchannel);
385 if (errchannel != NULL)
386 g_io_channel_unref (errchannel);
388 close_and_invalidate (&outpipe);
390 close_and_invalidate (&errpipe);
395 g_string_free (outstr, TRUE);
397 g_string_free (errstr, TRUE);
404 *exit_status = status;
407 *standard_output = g_string_free (outstr, FALSE);
410 *standard_error = g_string_free (errstr, FALSE);
417 g_spawn_async_with_pipes (const gchar *working_directory,
421 GSpawnChildSetupFunc child_setup,
424 gint *standard_input,
425 gint *standard_output,
426 gint *standard_error,
429 g_return_val_if_fail (argv != NULL, FALSE);
430 g_return_val_if_fail (standard_output == NULL ||
431 !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
432 g_return_val_if_fail (standard_error == NULL ||
433 !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
434 /* can't inherit stdin if we have an input pipe. */
435 g_return_val_if_fail (standard_input == NULL ||
436 !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
438 return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD),
442 !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
443 (flags & G_SPAWN_SEARCH_PATH) != 0,
444 (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
445 (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
446 (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
457 g_spawn_command_line_sync (const gchar *command_line,
458 gchar **standard_output,
459 gchar **standard_error,
466 g_return_val_if_fail (command_line != NULL, FALSE);
468 if (!g_shell_parse_argv (command_line,
473 retval = g_spawn_sync (NULL,
489 g_spawn_command_line_async (const gchar *command_line,
495 g_return_val_if_fail (command_line != NULL, FALSE);
497 if (!g_shell_parse_argv (command_line,
502 retval = g_spawn_async (NULL,
516 do_exec (gboolean dont_wait,
517 gint child_err_report_fd,
521 const gchar *working_directory,
524 gboolean close_descriptors,
525 gboolean search_path,
526 gboolean stdout_to_null,
527 gboolean stderr_to_null,
528 gboolean child_inherits_stdin,
529 GSpawnChildSetupFunc child_setup,
533 gchar args[ARG_COUNT][10];
542 new_argv = g_new (gchar *, argc + 1 + ARG_COUNT);
544 new_argv[0] = "gspawn-win32-helper";
545 sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_fd);
546 new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
550 sprintf (args[ARG_STDIN], "%d", stdin_fd);
551 new_argv[ARG_STDIN] = args[ARG_STDIN];
553 else if (child_inherits_stdin)
555 /* Let stdin be alone */
556 new_argv[ARG_STDIN] = "-";
560 /* Keep process from blocking on a read of stdin */
561 new_argv[ARG_STDIN] = "z";
566 sprintf (args[ARG_STDOUT], "%d", stdout_fd);
567 new_argv[ARG_STDOUT] = args[ARG_STDOUT];
569 else if (stdout_to_null)
571 new_argv[ARG_STDOUT] = "z";
575 new_argv[ARG_STDOUT] = "-";
580 sprintf (args[ARG_STDERR], "%d", stderr_fd);
581 new_argv[ARG_STDERR] = args[ARG_STDERR];
583 else if (stderr_to_null)
585 new_argv[ARG_STDERR] = "z";
589 new_argv[ARG_STDERR] = "-";
592 if (working_directory && *working_directory)
593 new_argv[ARG_WORKING_DIRECTORY] = working_directory;
595 new_argv[ARG_WORKING_DIRECTORY] = "-";
597 if (close_descriptors)
598 new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
600 new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
603 new_argv[ARG_USE_PATH] = "y";
605 new_argv[ARG_USE_PATH] = "-";
608 new_argv[ARG_WAIT] = "-";
610 new_argv[ARG_WAIT] = "w";
612 for (i = 0; i <= argc; i++)
613 new_argv[ARG_PROGRAM + i] = argv[i];
615 /* Call user function just before we execute the helper program,
616 * which executes the program. Dunno what's the usefulness of this.
617 * A child setup function used on Unix probably isn't of much use
618 * as such on Win32, anyhow
622 (* child_setup) (user_data);
627 g_print ("calling gspawn-win32-helper with argv:\n");
628 for (i = 0; i < argc + 1 + ARG_COUNT; i++)
629 g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL"));
633 /* Let's hope envp hasn't mucked with PATH so that
634 * gspawn-win32-helper.exe isn't found.
636 spawnvpe (P_NOWAIT, "gspawn-win32-helper", new_argv, envp);
638 spawnvp (P_NOWAIT, "gspawn-win32-helper", new_argv);
640 /* FIXME: What if gspawn-win32-helper.exe isn't found? */
642 /* Close the child_err_report_fd and the other process's ends of the
643 * pipes in this process, otherwise the reader will never get
646 close (child_err_report_fd);
668 while (bytes < sizeof(gint)*n_ints_in_buf)
673 g_print ("%s:read_ints: trying to read %d bytes from pipe...\n",
675 sizeof(gint)*n_ints_in_buf - bytes);
677 chunk = read (fd, ((gchar*)buf) + bytes,
678 sizeof(gint)*n_ints_in_buf - bytes);
681 g_print ("... got %d bytes\n", chunk);
685 /* Some weird shit happened, bail out */
689 G_SPAWN_ERROR_FAILED,
690 _("Failed to read from child pipe (%s)"),
701 *n_ints_read = bytes/sizeof(gint);
707 fork_exec_with_pipes (gboolean dont_wait,
708 const gchar *working_directory,
711 gboolean close_descriptors,
712 gboolean search_path,
713 gboolean stdout_to_null,
714 gboolean stderr_to_null,
715 gboolean child_inherits_stdin,
716 GSpawnChildSetupFunc child_setup,
718 gint *standard_input,
719 gint *standard_output,
720 gint *standard_error,
724 gint stdin_pipe[2] = { -1, -1 };
725 gint stdout_pipe[2] = { -1, -1 };
726 gint stderr_pipe[2] = { -1, -1 };
727 gint child_err_report_pipe[2] = { -1, -1 };
732 if (!make_pipe (child_err_report_pipe, error))
735 if (standard_input && !make_pipe (stdin_pipe, error))
736 goto cleanup_and_fail;
738 if (standard_output && !make_pipe (stdout_pipe, error))
739 goto cleanup_and_fail;
741 if (standard_error && !make_pipe (stderr_pipe, error))
742 goto cleanup_and_fail;
744 status = do_exec (dont_wait,
745 child_err_report_pipe[1],
756 child_inherits_stdin,
760 if (!read_ints (child_err_report_pipe[0],
763 goto cleanup_and_fail;
767 /* Error from the child. */
774 case CHILD_CHDIR_FAILED:
778 _("Failed to change to directory '%s' (%s)"),
780 g_strerror (buf[1]));
781 goto cleanup_and_fail;
783 case CHILD_SPAWN_FAILED:
786 G_SPAWN_ERROR_FAILED,
787 _("Failed to execute child process (%s)"),
788 g_strerror (buf[1]));
789 goto cleanup_and_fail;
793 /* Success against all odds! return the information */
796 *standard_input = stdin_pipe[1];
798 *standard_output = stdout_pipe[0];
800 *standard_error = stderr_pipe[0];
802 *exit_status = status;
807 close_and_invalidate (&child_err_report_pipe[0]);
808 close_and_invalidate (&child_err_report_pipe[1]);
809 close_and_invalidate (&stdin_pipe[0]);
810 close_and_invalidate (&stdin_pipe[1]);
811 close_and_invalidate (&stdout_pipe[0]);
812 close_and_invalidate (&stdout_pipe[1]);
813 close_and_invalidate (&stderr_pipe[0]);
814 close_and_invalidate (&stderr_pipe[1]);
820 make_pipe (gint p[2],
827 G_SPAWN_ERROR_FAILED,
828 _("Failed to create pipe for communicating with child process (%s)"),
836 #endif /* !GSPAWN_HELPER */