2 * spawn.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2013 Dimitar Toshkov Zhekov <dimitar(dot)zhekov(at)gmail(dot)com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 /* An ongoing effort to improve the tool spawning situation under Windows.
23 * - There is no g_shell_parse_argv() for windows. It's not hard to write one,
24 * but the command line recreated by mscvrt may be wrong.
25 * - GLib converts the argument vector to UNICODE. For non-UTF8 arguments,
26 * the result is often "Invalid string in argument vector at %d: %s: Invalid
27 * byte sequence in conversion input" (YMMV). Our tools (make, grep, gcc, ...)
28 * are "ANSI", so converting to UNICODE and then back only causes problems.
29 * - For various reasons, GLib uses an intermediate program to start children
30 * (see gspawn-win32.c), the result being that the grandchildren output (such
31 * as make -> gcc) is not captured.
32 * - With non-blocking pipes, the g_io_add_watch() callbacks are never invoked,
33 * while with blocking pipes, g_io_channel_read_line() blocks.
34 * - Some other problems are explained in separate comments below.
36 * Even under Unix, using g_io_channel_read_line() is not a good idea, since it may
37 * buffer lines of unlimited length.
39 * This module does not depend on Geany when compiled for testing (-DSPAWN_TEST).
52 # include "win32defines.h"
53 # include <ctype.h> /* isspace() */
54 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
55 # include <io.h> /* _open_osfhandle, _close */
57 #else /* G_OS_WIN32 */
59 #endif /* G_OS_WIN32 */
63 # define GEANY_API_SYMBOL
69 /* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more
70 balanced than 4095 + 1. May be different on the latest Windows/glib? */
71 # define DEFAULT_IO_LENGTH 2048
73 # define DEFAULT_IO_LENGTH 4096
76 #define G_IO_FAILURE (G_IO_ERR | G_IO_HUP | G_IO_NVAL) /* always used together */
80 * Checks whether a command line is syntactically valid and extracts the program name from it.
82 * See @c spawn_check_command() for details.
84 * @param command_line the command line to check and get the program name from.
85 * @param error return location for error.
87 * @return allocated string with the program name on success, @c NULL on error.
89 static gchar
*spawn_get_program_name(const gchar
*command_line
, GError
**error
)
94 gboolean open_quote
= FALSE
;
95 const gchar
*s
, *arguments
;
97 g_return_val_if_fail(command_line
!= NULL
, FALSE
);
99 while (*command_line
&& strchr(" \t\r\n", *command_line
))
104 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_EMPTY_STRING
,
105 /* TL note: from glib */
106 _("Text was empty (or contained only whitespace)"));
110 /* To prevent Windows from doing something weird, we want to be 100% sure that the
111 character after the program name is a delimiter, so we allow space and tab only. */
113 if (*command_line
== '"')
116 /* Windows allows "foo.exe, but we may have extra arguments */
117 if ((s
= strchr(command_line
, '"')) == NULL
)
119 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
120 /* TL note: from glib */
121 _("Text ended before matching quote was found for %c."
122 " (The text was '%s')"), '"', command_line
);
126 if (!strchr(" \t", s
[1])) /* strchr() catches s[1] == '\0' */
128 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
129 _("A quoted Windows program name must be entirely inside the quotes"));
135 const gchar
*quote
= strchr(command_line
, '"');
137 /* strchr() catches *s == '\0', and the for body is empty */
138 for (s
= command_line
; !strchr(" \t", *s
); s
++);
140 if (quote
&& quote
< s
)
142 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
143 _("A quoted Windows program name must be entirely inside the quotes"));
148 program
= g_strndup(command_line
, s
- command_line
);
149 arguments
= s
+ (*s
== '"');
151 for (s
= arguments
; *s
; s
++)
157 for (slash
= s
; slash
> arguments
&& slash
[-1] == '\\'; slash
--);
158 if ((s
- slash
) % 2 == 0)
165 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
166 /* TL note: from glib */
167 _("Text ended before matching quote was found for %c."
168 " (The text was '%s')"), '"', command_line
);
172 #else /* G_OS_WIN32 */
176 if (!g_shell_parse_argv(command_line
, &argc
, &argv
, error
))
179 /* empty string results in parse error, so argv[0] is not NULL */
180 program
= g_strdup(argv
[0]);
182 #endif /* G_OS_WIN32 */
189 * Checks whether a command line is valid.
191 * Checks if @a command_line is syntactically valid.
194 * - any leading spaces, tabs and new lines are skipped
195 * - an empty command is invalid
197 * - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv()
198 * - as a consequence, an unqouted # at the start of an argument comments to the end of line
200 * - leading carriage returns are skipped too
201 * - a quoted program name must be entirely inside the quotes. No "C:\Foo\Bar".pdf or
202 * "C:\Foo\Bar".bat, which would be executed by Windows as C:\Foo\Bar.exe
203 * - an unquoted program name may not contain spaces. Foo Bar Qux will not be considered
204 * "Foo Bar.exe" Qux or "Foo Bar Qux.exe", depending on what executables exist, as
205 * Windows normally does.
206 * - the program name must be separated from the arguments by at least one space or tab
207 * - the standard Windows quoting and escaping rules are used: double quote is escaped with
208 * backslash, and any literal backslashes before a double quote must be duplicated.
210 * If @a execute is TRUE, also checks, using @c g_find_program_in_path(), if the program
211 * specified in @a command_line exists and is executable.
213 * @param command_line the command line to check.
214 * @param execute whether to check if the command line is really executable.
215 * @param error return location for error.
217 * @return @c TRUE on success, @c FALSE on error.
222 gboolean
spawn_check_command(const gchar
*command_line
, gboolean execute
, GError
**error
)
224 gchar
*program
= spawn_get_program_name(command_line
, error
);
231 gchar
*executable
= g_find_program_in_path(program
);
235 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_FAILED
, /* or SPAWN error? */
236 _("Program '%s' not found"), program
);
252 * @param pid id of the process to kill.
253 * @param error return location for error.
255 * On Unix, sends a SIGTERM to the process.
257 * On Windows, terminates the process with exit code 255 (used sometimes as "generic"
258 * error code, or for programs terminated with Ctrl+C / Ctrl+Break).
260 * @return @c TRUE on success, @c FALSE on error.
265 gboolean
spawn_kill_process(GPid pid
, GError
**error
)
268 if (!TerminateProcess(pid
, 255))
270 gchar
*message
= g_win32_error_message(GetLastError());
272 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
,
273 _("TerminateProcess() failed: %s"), message
);
278 if (kill(pid
, SIGTERM
))
280 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, "%s", g_strerror(errno
));
289 static gchar
*spawn_create_process_with_pipes(char *command_line
, const char *working_directory
,
290 void *environment
, HANDLE
*hprocess
, int *stdin_fd
, int *stdout_fd
, int *stderr_fd
)
292 enum { WRITE_STDIN
, READ_STDOUT
, READ_STDERR
, READ_STDIN
, WRITE_STDOUT
, WRITE_STDERR
};
294 PROCESS_INFORMATION process
;
295 HANDLE hpipe
[6] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
296 int *fd
[3] = { stdin_fd
, stdout_fd
, stderr_fd
};
297 const char *failed
; /* failed WIN32/CRTL function, if any */
298 gchar
*message
= NULL
; /* glib WIN32/CTRL error message */
299 gchar
*failure
= NULL
; /* full error text */
303 ZeroMemory(&startup
, sizeof startup
);
304 startup
.cb
= sizeof startup
;
305 pipe_io
= stdin_fd
|| stdout_fd
|| stderr_fd
;
309 startup
.dwFlags
|= STARTF_USESTDHANDLES
;
311 /* not all programs accept mixed NULL and non-NULL hStd*, so we create all */
312 for (i
= 0; i
< 3; i
++)
314 static int pindex
[3][2] = { { READ_STDIN
, WRITE_STDIN
},
315 { READ_STDOUT
, WRITE_STDOUT
}, { READ_STDERR
, WRITE_STDERR
} };
317 if (!CreatePipe(&hpipe
[pindex
[i
][0]], &hpipe
[pindex
[i
][1]], NULL
, 0))
319 hpipe
[pindex
[i
][0]] = hpipe
[pindex
[i
][1]] = NULL
;
320 failed
= "CreatePipe";
326 static int mode
[3] = { _O_WRONLY
, _O_RDONLY
, _O_RDONLY
};
328 if ((*fd
[i
] = _open_osfhandle((intptr_t) hpipe
[i
], mode
[i
])) == -1)
330 failed
= "_open_osfhandle";
331 message
= g_strdup(g_strerror(errno
));
335 else if (!CloseHandle(hpipe
[i
]))
337 failed
= "CloseHandle";
341 if (!SetHandleInformation(hpipe
[i
+ 3], HANDLE_FLAG_INHERIT
,
342 HANDLE_FLAG_INHERIT
))
344 failed
= "SetHandleInformation";
350 startup
.hStdInput
= hpipe
[READ_STDIN
];
351 startup
.hStdOutput
= hpipe
[WRITE_STDOUT
];
352 startup
.hStdError
= hpipe
[WRITE_STDERR
];
354 if (!CreateProcess(NULL
, command_line
, NULL
, NULL
, TRUE
, pipe_io
? CREATE_NO_WINDOW
: 0,
355 environment
, working_directory
, &startup
, &process
))
357 failed
= "CreateProcess";
358 /* further errors will not be reported */
363 CloseHandle(process
.hThread
); /* we don't need this */
366 *hprocess
= process
.hProcess
;
368 CloseHandle(process
.hProcess
);
375 message
= g_win32_error_message(GetLastError());
377 failure
= g_strdup_printf("%s() failed: %s", failed
, message
);
383 for (i
= 0; i
< 3; i
++)
387 if (fd
[i
] && *fd
[i
] != -1)
390 CloseHandle(hpipe
[i
]);
394 CloseHandle(hpipe
[i
+ 3]);
402 static void spawn_append_argument(GString
*command
, const char *text
)
407 g_string_append_c(command
, ' ');
409 for (s
= text
; *s
; s
++)
411 /* g_ascii_isspace() fails for '\v', and locale spaces (if any) will do no harm */
412 if (*s
== '"' || isspace(*s
))
417 g_string_append(command
, text
);
420 g_string_append_c(command
, '"');
422 for (s
= text
; *s
; s
++)
426 for (slash
= s
; *slash
== '\\'; slash
++);
430 g_string_append_len(command
, s
, slash
- s
);
432 if (!*slash
|| *slash
== '"')
434 g_string_append_len(command
, s
, slash
- s
);
444 g_string_append_c(command
, '\\');
446 g_string_append_c(command
, *s
);
449 g_string_append_c(command
, '"');
452 #endif /* G_OS_WIN32 */
456 * Executes a child program asynchronously and setups pipes.
458 * This is the low-level spawning function. Please use @c spawn_with_callbacks() unless
459 * you need to setup specific event source(s).
461 * A command line or an argument vector must be passed. If both are present, the argument
462 * vector is appended to the command line. An empty command line is not allowed.
464 * Under Windows, if the child is a console application, and at least one file descriptor is
465 * specified, the new child console (if any) will be hidden.
467 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
469 * @param working_directory child's current working directory, or @c NULL.
470 * @param command_line child program and arguments, or @c NULL.
471 * @param argv child's argument vector, or @c NULL.
472 * @param envp child's environment, or @c NULL.
473 * @param child_pid return location for child process ID, or @c NULL.
474 * @param stdin_fd return location for file descriptor to write to child's stdin, or @c NULL.
475 * @param stdout_fd return location for file descriptor to read child's stdout, or @c NULL.
476 * @param stderr_fd return location for file descriptor to read child's stderr, or @c NULL.
477 * @param error return location for error.
479 * @return @c TRUE on success, @c FALSE on error.
481 static gboolean
spawn_async_with_pipes(const gchar
*working_directory
, const gchar
*command_line
,
482 gchar
**argv
, gchar
**envp
, GPid
*child_pid
, gint
*stdin_fd
, gint
*stdout_fd
,
483 gint
*stderr_fd
, GError
**error
)
485 g_return_val_if_fail(command_line
!= NULL
|| argv
!= NULL
, FALSE
);
494 gchar
*program
= spawn_get_program_name(command_line
, error
);
495 const gchar
*arguments
;
500 command
= g_string_new(NULL
);
501 arguments
= strstr(command_line
, program
) + strlen(program
);
503 if (*arguments
== '"')
505 g_string_append(command
, program
);
510 /* quote the first token, to avoid Windows attemps to run two or more
511 unquoted tokens as a program until an existing file name is found */
512 g_string_printf(command
, "\"%s\"", program
);
515 g_string_append(command
, arguments
);
519 command
= g_string_new(NULL
);
521 environment
= g_array_new(TRUE
, FALSE
, sizeof(char));
523 while (argv
&& *argv
)
524 spawn_append_argument(command
, *argv
++);
527 g_message("full spawn command line: %s\n", command
->str
);
530 while (envp
&& *envp
)
532 g_array_append_vals(environment
, *envp
, strlen(*envp
) + 1);
536 failure
= spawn_create_process_with_pipes(command
->str
, working_directory
,
537 envp
? environment
->data
: NULL
, child_pid
, stdin_fd
, stdout_fd
, stderr_fd
);
539 g_string_free(command
, TRUE
);
540 g_array_free(environment
, TRUE
);
544 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, "%s", failure
);
550 #else /* G_OS_WIN32 */
560 if (!g_shell_parse_argv(command_line
, &cl_argc
, &cl_argv
, error
))
564 for (argc
= 0; argv
[argc
]; argc
++);
566 full_argv
= g_renew(gchar
*, cl_argv
, cl_argc
+ argc
+ 1);
567 memcpy(full_argv
+ cl_argc
, argv
, argc
* sizeof(gchar
*));
568 full_argv
[cl_argc
+ argc
] = NULL
;
573 spawned
= g_spawn_async_with_pipes(working_directory
, full_argv
, envp
,
574 G_SPAWN_SEARCH_PATH
| (child_pid
? G_SPAWN_DO_NOT_REAP_CHILD
: 0), NULL
, NULL
,
575 child_pid
, stdin_fd
, stdout_fd
, stderr_fd
, error
);
577 if (full_argv
!= argv
)
579 full_argv
[cl_argc
] = NULL
;
580 g_strfreev(full_argv
);
584 #endif /* G_OS_WIN32 */
589 * Executes a child asynchronously.
591 * A command line or an argument vector must be passed. If both are present, the argument
592 * vector is appended to the command line. An empty command line is not allowed.
594 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
596 * @param working_directory child's current working directory, or @c NULL.
597 * @param command_line child program and arguments, or @c NULL.
598 * @param argv child's argument vector, or @c NULL.
599 * @param envp child's environment, or @c NULL.
600 * @param child_pid return location for child process ID, or @c NULL.
601 * @param error return location for error.
603 * @return @c TRUE on success, @c FALSE on error.
608 gboolean
spawn_async(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
609 gchar
**envp
, GPid
*child_pid
, GError
**error
)
611 return spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, child_pid
,
612 NULL
, NULL
, NULL
, error
);
617 * Spawn with callbacks - general event sequence:
619 * - Launch the child.
620 * - Setup any I/O callbacks and a child watch callback.
621 * - On sync execution, run a main loop.
622 * - Wait for the child to terminate.
623 * - Check for active I/O sources. If any, add a timeout source to watch them, they should
624 * become inactive real soon now that the child is dead. Otherwise, finalize immediately.
625 * - In the timeout source: check for active I/O sources and finalize if none.
628 typedef struct _SpawnChannelData
630 GIOChannel
*channel
; /* NULL if not created / already destroyed */
637 /* stdout/stderr only */
638 GString
*buffer
; /* NULL if recursive */
639 GString
*line_buffer
; /* NULL if char buffered */
644 static void spawn_destroy_cb(gpointer data
)
646 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
648 g_io_channel_shutdown(sc
->channel
, FALSE
, NULL
);
652 g_string_free(sc
->buffer
, TRUE
);
655 g_string_free(sc
->line_buffer
, TRUE
);
659 static gboolean
spawn_write_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
661 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
663 if (!sc
->cb
.write(channel
, condition
, sc
->cb_data
))
666 return !(condition
& G_IO_FAILURE
);
670 static gboolean
spawn_read_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
672 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
673 GString
*line_buffer
= sc
->line_buffer
;
674 GString
*buffer
= sc
->buffer
? sc
->buffer
: g_string_sized_new(sc
->max_length
);
675 GIOCondition input_cond
= condition
& (G_IO_IN
| G_IO_PRI
);
676 GIOCondition failure_cond
= condition
& G_IO_FAILURE
;
678 * - Normally, read only once. With IO watches, our data processing must be immediate,
679 * which may give the child time to emit more data, and a read loop may combine it into
680 * large stdout and stderr portions. Under Windows, looping blocks.
681 * - On failure, read in a loop. It won't block now, there will be no more data, and the
682 * IO watch is not guaranteed to be called again (under Windows this is the last call).
691 gsize n
= line_buffer
->len
;
693 while ((status
= g_io_channel_read_chars(channel
, line_buffer
->str
+ n
,
694 DEFAULT_IO_LENGTH
, &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
696 g_string_set_size(line_buffer
, n
+ chars_read
);
698 while (n
< line_buffer
->len
)
702 if (n
== sc
->max_length
)
704 else if (strchr("\n", line_buffer
->str
[n
])) /* '\n' or '\0' */
706 else if (n
< line_buffer
->len
- 1 && line_buffer
->str
[n
] == '\r')
707 line_len
= n
+ 1 + (line_buffer
->str
[n
+ 1] == '\n');
713 g_string_append_len(buffer
, line_buffer
->str
, line_len
);
714 g_string_erase(line_buffer
, 0, line_len
);
715 /* input only, failures are reported separately below */
716 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
717 g_string_truncate(buffer
, 0);
728 while ((status
= g_io_channel_read_chars(channel
, buffer
->str
, sc
->max_length
,
729 &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
731 g_string_set_size(buffer
, chars_read
);
732 /* input only, failures are reported separately below */
733 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
740 /* Under OSX, after child death, the read watches receive input conditions instead
741 of error conditions, so we convert the termination statuses into conditions.
742 Should not hurt the other OS. */
743 if (status
== G_IO_STATUS_ERROR
)
744 failure_cond
|= G_IO_ERR
;
745 else if (status
== G_IO_STATUS_EOF
)
746 failure_cond
|= G_IO_HUP
;
749 if (failure_cond
) /* we must signal the callback */
751 if (line_buffer
&& line_buffer
->len
) /* flush the line buffer */
753 g_string_append_len(buffer
, line_buffer
->str
, line_buffer
->len
);
754 /* all data may be from a previous call */
756 input_cond
= G_IO_IN
;
761 g_string_truncate(buffer
, 0);
764 sc
->cb
.read(buffer
, input_cond
| failure_cond
, sc
->cb_data
);
767 if (buffer
!= sc
->buffer
)
768 g_string_free(buffer
, TRUE
);
770 return !failure_cond
;
774 typedef struct _SpawnWatcherData
776 SpawnChannelData sc
[3]; /* stdin, stdout, stderr */
777 GChildWatchFunc exit_cb
;
781 GMainContext
*main_context
; /* NULL if async execution */
782 GMainLoop
*main_loop
; /* NULL if async execution */
786 static void spawn_finalize(SpawnWatcherData
*sw
)
789 sw
->exit_cb(sw
->pid
, sw
->exit_status
, sw
->exit_data
);
793 g_main_loop_quit(sw
->main_loop
);
794 g_main_loop_unref(sw
->main_loop
);
797 g_spawn_close_pid(sw
->pid
);
798 g_slice_free(SpawnWatcherData
, sw
);
802 static gboolean
spawn_timeout_cb(gpointer data
)
804 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
807 for (i
= 0; i
< 3; i
++)
808 if (sw
->sc
[i
].channel
)
816 static void spawn_watch_cb(GPid pid
, gint status
, gpointer data
)
818 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
822 sw
->exit_status
= status
;
824 for (i
= 0; i
< 3; i
++)
826 if (sw
->sc
[i
].channel
)
828 GSource
*source
= g_timeout_source_new(50);
830 g_source_set_callback(source
, spawn_timeout_cb
, data
, NULL
);
831 g_source_attach(source
, sw
->main_context
);
832 g_source_unref(source
);
842 * Executes a child program and setups callbacks.
844 * A command line or an argument vector must be passed. If both are present, the argument
845 * vector is appended to the command line. An empty command line is not allowed.
847 * The synchronous execution may not be combined with recursive callbacks.
849 * In line buffered mode, the child input is broken on '\n', "\r\n", '\r', '\0' and max length.
851 * All I/O callbacks are guaranteed to be invoked at least once with @c G_IO_ERR, @c G_IO_HUP
852 * or @c G_IO_NVAL set (except for a @a stdin_cb which returns @c FALSE before that). For the
853 * non-recursive callbacks, this is guaranteed to be the last call, and may be used to free any
854 * resources associated with the callback.
856 * The @a stdin_cb may write to @c channel only once per invocation, only if @c G_IO_OUT is
857 * set, and only a non-zero number of characters.
859 * @c stdout_cb and @c stderr_cb may modify the received strings in any way, but must not
862 * The default max lengths are 24K for line buffered stdout, 8K for line buffered stderr,
863 * 4K for unbuffered input under Unix, and 2K for unbuffered input under Windows.
865 * @c exit_cb is always invoked last, after all I/O callbacks.
867 * The @a child_pid will be closed automatically, after @a exit_cb is invoked.
869 * @param working_directory child's current working directory, or @c NULL.
870 * @param command_line child program and arguments, or @c NULL.
871 * @param argv child's argument vector, or @c NULL.
872 * @param envp child's environment, or @c NULL.
873 * @param spawn_flags flags from SpawnFlags.
874 * @param stdin_cb callback to send data to childs's stdin, or @c NULL.
875 * @param stdin_data data to pass to @a stdin_cb.
876 * @param stdout_cb callback to receive child's stdout, or @c NULL.
877 * @param stdout_data data to pass to @a stdout_cb.
878 * @param stdout_max_length maximum data length to pass to stdout_cb, @c 0 = default.
879 * @param stderr_cb callback to receive child's stderr, or @c NULL.
880 * @param stderr_data data to pass to @a stderr_cb.
881 * @param stderr_max_length maximum data length to pass to stderr_cb, @c 0 = default.
882 * @param exit_cb callback to invoke when the child exits, or @c NULL.
883 * @param exit_data data to pass to @a exit_cb.
884 * @param child_pid return location for child process ID, or @c NULL.
885 * @param error return location for error.
887 * @return @c TRUE on success, @c FALSE on error.
892 gboolean
spawn_with_callbacks(const gchar
*working_directory
, const gchar
*command_line
,
893 gchar
**argv
, gchar
**envp
, SpawnFlags spawn_flags
, GIOFunc stdin_cb
, gpointer stdin_data
,
894 SpawnReadFunc stdout_cb
, gpointer stdout_data
, gsize stdout_max_length
,
895 SpawnReadFunc stderr_cb
, gpointer stderr_data
, gsize stderr_max_length
,
896 GChildWatchFunc exit_cb
, gpointer exit_data
, GPid
*child_pid
, GError
**error
)
899 int pipe
[3] = { -1, -1, -1 };
901 g_return_val_if_fail(!(spawn_flags
& SPAWN_RECURSIVE
) || !(spawn_flags
& SPAWN_SYNC
),
904 if (spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, &pid
,
905 stdin_cb
? &pipe
[0] : NULL
, stdout_cb
? &pipe
[1] : NULL
,
906 stderr_cb
? &pipe
[2] : NULL
, error
))
908 SpawnWatcherData
*sw
= g_slice_new0(SpawnWatcherData
);
909 gpointer cb_data
[3] = { stdin_data
, stdout_data
, stderr_data
};
913 sw
->main_context
= spawn_flags
& SPAWN_SYNC
? g_main_context_new() : NULL
;
918 for (i
= 0; i
< 3; i
++)
920 SpawnChannelData
*sc
= &sw
->sc
[i
];
921 GIOCondition condition
;
922 GSourceFunc callback
;
928 sc
->channel
= g_io_channel_win32_new_fd(pipe
[i
]);
930 sc
->channel
= g_io_channel_unix_new(pipe
[i
]);
931 g_io_channel_set_flags(sc
->channel
, G_IO_FLAG_NONBLOCK
, NULL
);
933 g_io_channel_set_encoding(sc
->channel
, NULL
, NULL
);
934 /* we have our own buffers, and GIO buffering blocks under Windows */
935 g_io_channel_set_buffered(sc
->channel
, FALSE
);
936 sc
->cb_data
= cb_data
[i
];
940 sc
->cb
.write
= stdin_cb
;
941 condition
= G_IO_OUT
| G_IO_FAILURE
;
942 callback
= (GSourceFunc
) spawn_write_cb
;
946 gboolean line_buffered
= !(spawn_flags
&
947 ((SPAWN_STDOUT_UNBUFFERED
>> 1) << i
));
949 condition
= G_IO_IN
| G_IO_PRI
| G_IO_FAILURE
;
950 callback
= (GSourceFunc
) spawn_read_cb
;
954 sc
->cb
.read
= stdout_cb
;
955 sc
->max_length
= stdout_max_length
? stdout_max_length
:
956 line_buffered
? 24576 : DEFAULT_IO_LENGTH
;
960 sc
->cb
.read
= stderr_cb
;
961 sc
->max_length
= stderr_max_length
? stderr_max_length
:
962 line_buffered
? 8192 : DEFAULT_IO_LENGTH
;
967 sc
->line_buffer
= g_string_sized_new(sc
->max_length
+
972 source
= g_io_create_watch(sc
->channel
, condition
);
973 g_io_channel_unref(sc
->channel
);
975 if (spawn_flags
& (SPAWN_STDIN_RECURSIVE
<< i
))
976 g_source_set_can_recurse(source
, TRUE
);
977 else if (i
) /* to avoid new string on each call */
978 sc
->buffer
= g_string_sized_new(sc
->max_length
);
980 g_source_set_callback(source
, callback
, sc
, spawn_destroy_cb
);
981 g_source_attach(source
, sw
->main_context
);
982 g_source_unref(source
);
985 sw
->exit_cb
= exit_cb
;
986 sw
->exit_data
= exit_data
;
987 source
= g_child_watch_source_new(pid
);
988 g_source_set_callback(source
, (GSourceFunc
) spawn_watch_cb
, sw
, NULL
);
989 g_source_attach(source
, sw
->main_context
);
990 g_source_unref(source
);
992 if (spawn_flags
& SPAWN_SYNC
)
994 sw
->main_loop
= g_main_loop_new(sw
->main_context
, FALSE
);
995 g_main_context_unref(sw
->main_context
);
996 g_main_loop_run(sw
->main_loop
);
1007 * Writes (a portion of) the data pointed by @a data->ptr to the @a channel.
1009 * If @c G_IO_OUT in @a condition is set, and the @a data->size is > 0, attempts to write
1010 * @a data->ptr (or a portion of it, depending on the size) to the @a channel. On success,
1011 * increases ptr and decreases size with the number of characters written.
1013 * This function may converted to @c GIOFunc and passed to @c spawn_with_callbacks() as
1014 * @c stdin_cb, together with a @c SpawnWriteData for @c stdin_data. As with any other
1015 * callback data, make sure that @c stdin_data exists while the child is being executed.
1016 * (For example, on asynchronous execution, you can allocate the data in the heap, and free
1017 * it in your @c spawn_with_callbacks() @c exit_cb callback.)
1019 * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error,
1020 * @c FALSE otherwise.
1025 gboolean
spawn_write_data(GIOChannel
*channel
, GIOCondition condition
, SpawnWriteData
*data
)
1027 if ((condition
& G_IO_OUT
) && data
->size
)
1029 gsize chars_written
= 0;
1031 g_io_channel_write_chars(channel
, data
->ptr
, data
->size
< DEFAULT_IO_LENGTH
?
1032 data
->size
: DEFAULT_IO_LENGTH
, &chars_written
, NULL
);
1034 /* "This can be nonzero even if the return value is not G_IO_STATUS_NORMAL." */
1037 data
->ptr
+= chars_written
;
1038 data
->size
-= chars_written
;
1042 return data
->size
> 0 && !(condition
& G_IO_FAILURE
);
1046 static void spawn_append_gstring_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1048 if (condition
& (G_IO_IN
| G_IO_PRI
))
1049 g_string_append_len((GString
*) data
, string
->str
, string
->len
);
1053 static void spawn_get_exit_status_cb(G_GNUC_UNUSED GPid pid
, gint status
, gpointer exit_status
)
1055 *(gint
*) exit_status
= status
;
1060 * Executes a child synchronously.
1062 * A command line or an argument vector must be passed. If both are present, the argument
1063 * vector is appended to the command line. An empty command line is not allowed.
1065 * The @a stdin_data is sent to the child with @c spawn_write_data().
1067 * All output from the child, including the nul characters, is stored in @a stdout_data and
1068 * @a stderr_data (if non-NULL). Any existing data in these strings will be erased.
1070 * @param working_directory child's current working directory, or @c NULL.
1071 * @param command_line child program and arguments, or @c NULL.
1072 * @param argv child's argument vector, or @c NULL.
1073 * @param envp child's environment, or @c NULL.
1074 * @param stdin_data data to send to childs's stdin, or @c NULL.
1075 * @param stdout_data GString location to receive the child's stdout, or NULL.
1076 * @param stderr_data GString location to receive the child's stderr, or NULL.
1077 * @param exit_status return location for the child exit code, or NULL.
1078 * @param error return location for error.
1080 * @return @c TRUE on success, @c FALSE on error.
1085 gboolean
spawn_sync(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
1086 gchar
**envp
, SpawnWriteData
*stdin_data
, GString
*stdout_data
, GString
*stderr_data
,
1087 gint
*exit_status
, GError
**error
)
1089 g_string_truncate(stdout_data
, 0);
1090 g_string_truncate(stderr_data
, 0);
1092 return spawn_with_callbacks(working_directory
, command_line
, argv
, envp
, SPAWN_SYNC
|
1093 SPAWN_UNBUFFERED
, stdin_data
? (GIOFunc
) spawn_write_data
: NULL
, stdin_data
,
1094 stdout_data
? spawn_append_gstring_cb
: NULL
, stdout_data
, 0,
1095 stderr_data
? spawn_append_gstring_cb
: NULL
, stderr_data
, 0,
1096 exit_status
? spawn_get_exit_status_cb
: NULL
, exit_status
, NULL
, error
);
1100 /* tests, not part of the API */
1105 static gboolean
read_line(const char *prompt
, char *buffer
, size_t size
)
1107 fputs(prompt
, stderr
);
1110 if (fgets(buffer
, size
, stdin
))
1112 char *s
= strchr(buffer
, '\n');
1122 static GString
*read_string(const char *prompt
)
1124 char buffer
[0x1000]; /* larger portions for spawn < file */
1125 GString
*string
= g_string_sized_new(sizeof buffer
);
1127 while (read_line(prompt
, buffer
, sizeof buffer
))
1130 g_string_append_c(string
, '\n');
1132 g_string_append(string
, buffer
);
1137 g_string_free(string
, TRUE
);
1145 static void print_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1147 if (condition
& (G_IO_IN
| G_IO_PRI
))
1151 printf("%s: ", (const gchar
*) data
);
1152 /*fputs(string->str, stdout);*/
1153 for (i
= 0; i
< string
->len
; i
++)
1155 unsigned char c
= (unsigned char) string
->str
[i
];
1156 printf(c
>= ' ' && c
< 0x80 ? "%c" : "\\x%02x", c
);
1163 static void print_status(gint status
)
1165 fputs("finished, ", stderr
);
1167 if (WIFEXITED(status
))
1168 fprintf(stderr
, "exit code %d\n", WEXITSTATUS(status
));
1170 fputs("abnormal termination\n", stderr
);
1174 static void exit_cb(GPid pid
, gint status
, G_GNUC_UNUSED gpointer data
)
1176 fprintf(stderr
, "process %u ", (guint
) pid
);
1177 print_status(status
);
1181 static void watch_cb(GPid pid
, gint status
, gpointer data
)
1183 g_spawn_close_pid(pid
);
1184 exit_cb(pid
, status
, NULL
);
1185 g_main_loop_quit((GMainLoop
*) data
);
1189 int main(int argc
, char **argv
)
1195 fputs("usage: spawn <test-type>\n", stderr
);
1199 test_type
= argv
[1];
1201 if (!strcmp(test_type
, "syntax") || !strcmp(test_type
, "syntexec"))
1203 char command_line
[0x100];
1205 while (read_line("command line: ", command_line
, sizeof command_line
))
1207 GError
*error
= NULL
;
1209 if (spawn_check_command(command_line
, argv
[1][4] == 'e', &error
))
1210 fputs("valid\n", stderr
);
1213 fprintf(stderr
, "error: %s\n", error
->message
);
1214 g_error_free(error
);
1218 else if (!strcmp(test_type
, "execute"))
1220 char command_line
[0x100];
1222 while (read_line("command line: ", command_line
, sizeof command_line
))
1224 char working_directory
[0x100];
1225 char args
[4][0x100];
1226 char envs
[4][0x100];
1227 char *argv
[] = { args
[0], args
[1], args
[2], args
[3], NULL
};
1228 char *envp
[] = { envs
[0], envs
[1], envs
[2], envs
[3], NULL
};
1231 GError
*error
= NULL
;
1233 read_line("working directory: ", working_directory
, sizeof working_directory
);
1235 fputs("up to 4 arguments\n", stderr
);
1236 for (i
= 0; i
< 4 && read_line("argument: ", args
[i
], sizeof args
[i
]); i
++);
1239 fputs("up to 4 variables, or empty line for parent environment\n", stderr
);
1240 for (i
= 0; i
< 4 && read_line("variable: ", envs
[i
], sizeof envs
[i
]); i
++);
1243 if (spawn_async_with_pipes(*working_directory
? working_directory
: NULL
,
1244 *command_line
? command_line
: NULL
, argv
, i
? envp
: NULL
, &pid
, NULL
,
1245 NULL
, NULL
, &error
))
1247 GMainLoop
*loop
= g_main_loop_new(NULL
, TRUE
);
1249 g_child_watch_add(pid
, watch_cb
, loop
);
1250 g_main_loop_run(loop
);
1251 g_main_loop_unref(loop
);
1255 fprintf(stderr
, "error: %s\n", error
->message
);
1256 g_error_free(error
);
1260 else if (!strcmp(test_type
, "redirect") || !strcmp(test_type
, "redinput"))
1262 char command_line
[0x100];
1263 gboolean output
= test_type
[4] == 'r';
1265 while (read_line("command line: ", command_line
, sizeof command_line
))
1267 GString
*stdin_text
= read_string("text to send: ");
1268 SpawnWriteData stdin_data
;
1269 GError
*error
= NULL
;
1273 stdin_data
.ptr
= stdin_text
->str
;
1274 stdin_data
.size
= stdin_text
->len
;
1277 if (!spawn_with_callbacks(NULL
, command_line
, NULL
, NULL
, SPAWN_SYNC
,
1278 stdin_text
? (GIOFunc
) spawn_write_data
: NULL
, &stdin_data
,
1279 output
? print_cb
: NULL
, "stdout", 0, output
? print_cb
: NULL
,
1280 "stderr", 0, exit_cb
, NULL
, NULL
, &error
))
1282 fprintf(stderr
, "error: %s\n", error
->message
);
1283 g_error_free(error
);
1287 g_string_free(stdin_text
, TRUE
);
1290 else if (!strcmp(test_type
, "capture"))
1292 char command_line
[0x100];
1294 while (read_line("command line: ", command_line
, sizeof command_line
))
1296 GString
*stdin_text
= read_string("text to send: ");
1297 SpawnWriteData stdin_data
= { NULL
, 0 };
1298 GString
*stdout_data
= g_string_sized_new(0x10000); /* may grow */
1299 GString
*stderr_data
= g_string_sized_new(0x1000); /* may grow */
1301 GError
*error
= NULL
;
1305 stdin_data
.ptr
= stdin_text
->str
;
1306 stdin_data
.size
= stdin_text
->len
;
1309 if (spawn_sync(NULL
, command_line
, NULL
, NULL
, &stdin_data
, stdout_data
,
1310 stderr_data
, &exit_status
, &error
))
1312 printf("stdout: %s\n", stdout_data
->str
);
1313 printf("stderr: %s\n", stderr_data
->str
);
1314 print_status(exit_status
);
1318 fprintf(stderr
, "error: %s\n", error
->message
);
1319 g_error_free(error
);
1323 g_string_free(stdin_text
, TRUE
);
1325 g_string_free(stdout_data
, TRUE
);
1326 g_string_free(stderr_data
, TRUE
);
1331 fprintf(stderr
, "spawn: unknown test type '%s'", argv
[1]);
1337 #endif /* SPAWN_TEST */