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).
43 * Portable and convenient process spawning and communication.
50 #include "win32defines.h" /* should always come before any system headers */
58 # include <ctype.h> /* isspace() */
59 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
60 # include <io.h> /* _open_osfhandle, _close */
62 #else /* G_OS_WIN32 */
64 #endif /* G_OS_WIN32 */
68 # define GEANY_API_SYMBOL
74 /* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more
75 balanced than 4095 + 1. May be different on the latest Windows/glib? */
76 # define DEFAULT_IO_LENGTH 2048
78 # define DEFAULT_IO_LENGTH 4096
81 #define G_IO_FAILURE (G_IO_ERR | G_IO_HUP | G_IO_NVAL) /* always used together */
85 * Checks whether a command line is syntactically valid and extracts the program name from it.
87 * See @c spawn_check_command() for details.
89 * @param command_line the command line to check and get the program name from.
90 * @param error return location for error.
92 * @return allocated string with the program name on success, @c NULL on error.
94 static gchar
*spawn_get_program_name(const gchar
*command_line
, GError
**error
)
99 gboolean open_quote
= FALSE
;
100 const gchar
*s
, *arguments
;
102 g_return_val_if_fail(command_line
!= NULL
, FALSE
);
104 while (*command_line
&& strchr(" \t\r\n", *command_line
))
109 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_EMPTY_STRING
,
110 /* TL note: from glib */
111 _("Text was empty (or contained only whitespace)"));
115 /* To prevent Windows from doing something weird, we want to be 100% sure that the
116 character after the program name is a delimiter, so we allow space and tab only. */
118 if (*command_line
== '"')
121 /* Windows allows "foo.exe, but we may have extra arguments */
122 if ((s
= strchr(command_line
, '"')) == NULL
)
124 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
125 /* TL note: from glib */
126 _("Text ended before matching quote was found for %c."
127 " (The text was '%s')"), '"', command_line
);
131 if (!strchr(" \t", s
[1])) /* strchr() catches s[1] == '\0' */
133 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
134 _("A quoted Windows program name must be entirely inside the quotes"));
140 const gchar
*quote
= strchr(command_line
, '"');
142 /* strchr() catches *s == '\0', and the for body is empty */
143 for (s
= command_line
; !strchr(" \t", *s
); s
++);
145 if (quote
&& quote
< s
)
147 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
148 _("A quoted Windows program name must be entirely inside the quotes"));
153 program
= g_strndup(command_line
, s
- command_line
);
154 arguments
= s
+ (*s
== '"');
156 for (s
= arguments
; *s
; s
++)
162 for (slash
= s
; slash
> arguments
&& slash
[-1] == '\\'; slash
--);
163 if ((s
- slash
) % 2 == 0)
170 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
171 /* TL note: from glib */
172 _("Text ended before matching quote was found for %c."
173 " (The text was '%s')"), '"', command_line
);
177 #else /* G_OS_WIN32 */
181 if (!g_shell_parse_argv(command_line
, &argc
, &argv
, error
))
184 /* empty string results in parse error, so argv[0] is not NULL */
185 program
= g_strdup(argv
[0]);
187 #endif /* G_OS_WIN32 */
194 * Checks whether a command line is valid.
196 * Checks if @a command_line is syntactically valid.
199 * - any leading spaces, tabs and new lines are skipped
200 * - an empty command is invalid
202 * - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv()
203 * - as a consequence, an unqouted # at the start of an argument comments to the end of line
205 * - leading carriage returns are skipped too
206 * - a quoted program name must be entirely inside the quotes. No "C:\Foo\Bar".pdf or
207 * "C:\Foo\Bar".bat, which would be executed by Windows as C:\Foo\Bar.exe
208 * - an unquoted program name may not contain spaces. Foo Bar Qux will not be considered
209 * "Foo Bar.exe" Qux or "Foo Bar Qux.exe", depending on what executables exist, as
210 * Windows normally does.
211 * - the program name must be separated from the arguments by at least one space or tab
212 * - the standard Windows quoting and escaping rules are used: double quote is escaped with
213 * backslash, and any literal backslashes before a double quote must be duplicated.
215 * If @a execute is TRUE, also checks, using @c g_find_program_in_path(), if the program
216 * specified in @a command_line exists and is executable.
218 * @param command_line the command line to check.
219 * @param execute whether to check if the command line is really executable.
220 * @param error return location for error.
222 * @return @c TRUE on success, @c FALSE on error.
227 gboolean
spawn_check_command(const gchar
*command_line
, gboolean execute
, GError
**error
)
229 gchar
*program
= spawn_get_program_name(command_line
, error
);
236 gchar
*executable
= g_find_program_in_path(program
);
240 g_set_error(error
, G_SHELL_ERROR
, G_SHELL_ERROR_FAILED
, /* or SPAWN error? */
241 _("Program '%s' not found"), program
);
257 * @param pid id of the process to kill.
258 * @param error return location for error.
260 * On Unix, sends a SIGTERM to the process.
262 * On Windows, terminates the process with exit code 255 (used sometimes as "generic"
263 * error code, or for programs terminated with Ctrl+C / Ctrl+Break).
265 * @return @c TRUE on success, @c FALSE on error.
270 gboolean
spawn_kill_process(GPid pid
, GError
**error
)
273 if (!TerminateProcess(pid
, 255))
275 gchar
*message
= g_win32_error_message(GetLastError());
277 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
,
278 _("TerminateProcess() failed: %s"), message
);
283 if (kill(pid
, SIGTERM
))
285 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, "%s", g_strerror(errno
));
294 static gchar
*spawn_create_process_with_pipes(char *command_line
, const char *working_directory
,
295 void *environment
, HANDLE
*hprocess
, int *stdin_fd
, int *stdout_fd
, int *stderr_fd
)
297 enum { WRITE_STDIN
, READ_STDOUT
, READ_STDERR
, READ_STDIN
, WRITE_STDOUT
, WRITE_STDERR
};
299 PROCESS_INFORMATION process
;
300 HANDLE hpipe
[6] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
301 int *fd
[3] = { stdin_fd
, stdout_fd
, stderr_fd
};
302 const char *failed
; /* failed WIN32/CRTL function, if any */
303 gchar
*message
= NULL
; /* glib WIN32/CTRL error message */
304 gchar
*failure
= NULL
; /* full error text */
308 ZeroMemory(&startup
, sizeof startup
);
309 startup
.cb
= sizeof startup
;
310 pipe_io
= stdin_fd
|| stdout_fd
|| stderr_fd
;
314 startup
.dwFlags
|= STARTF_USESTDHANDLES
;
316 /* not all programs accept mixed NULL and non-NULL hStd*, so we create all */
317 for (i
= 0; i
< 3; i
++)
319 static int pindex
[3][2] = { { READ_STDIN
, WRITE_STDIN
},
320 { READ_STDOUT
, WRITE_STDOUT
}, { READ_STDERR
, WRITE_STDERR
} };
322 if (!CreatePipe(&hpipe
[pindex
[i
][0]], &hpipe
[pindex
[i
][1]], NULL
, 0))
324 hpipe
[pindex
[i
][0]] = hpipe
[pindex
[i
][1]] = NULL
;
325 failed
= "CreatePipe";
331 static int mode
[3] = { _O_WRONLY
, _O_RDONLY
, _O_RDONLY
};
333 if ((*fd
[i
] = _open_osfhandle((intptr_t) hpipe
[i
], mode
[i
])) == -1)
335 failed
= "_open_osfhandle";
336 message
= g_strdup(g_strerror(errno
));
340 else if (!CloseHandle(hpipe
[i
]))
342 failed
= "CloseHandle";
346 if (!SetHandleInformation(hpipe
[i
+ 3], HANDLE_FLAG_INHERIT
,
347 HANDLE_FLAG_INHERIT
))
349 failed
= "SetHandleInformation";
355 startup
.hStdInput
= hpipe
[READ_STDIN
];
356 startup
.hStdOutput
= hpipe
[WRITE_STDOUT
];
357 startup
.hStdError
= hpipe
[WRITE_STDERR
];
359 if (!CreateProcess(NULL
, command_line
, NULL
, NULL
, TRUE
, pipe_io
? CREATE_NO_WINDOW
: 0,
360 environment
, working_directory
, &startup
, &process
))
362 failed
= "CreateProcess";
363 /* further errors will not be reported */
368 CloseHandle(process
.hThread
); /* we don't need this */
371 *hprocess
= process
.hProcess
;
373 CloseHandle(process
.hProcess
);
380 message
= g_win32_error_message(GetLastError());
382 failure
= g_strdup_printf("%s() failed: %s", failed
, message
);
388 for (i
= 0; i
< 3; i
++)
392 if (fd
[i
] && *fd
[i
] != -1)
395 CloseHandle(hpipe
[i
]);
399 CloseHandle(hpipe
[i
+ 3]);
407 static void spawn_append_argument(GString
*command
, const char *text
)
412 g_string_append_c(command
, ' ');
414 for (s
= text
; *s
; s
++)
416 /* g_ascii_isspace() fails for '\v', and locale spaces (if any) will do no harm */
417 if (*s
== '"' || isspace(*s
))
422 g_string_append(command
, text
);
425 g_string_append_c(command
, '"');
427 for (s
= text
; *s
; s
++)
431 for (slash
= s
; *slash
== '\\'; slash
++);
435 g_string_append_len(command
, s
, slash
- s
);
437 if (!*slash
|| *slash
== '"')
439 g_string_append_len(command
, s
, slash
- s
);
449 g_string_append_c(command
, '\\');
451 g_string_append_c(command
, *s
);
454 g_string_append_c(command
, '"');
457 #endif /* G_OS_WIN32 */
461 * Executes a child program asynchronously and setups pipes.
463 * This is the low-level spawning function. Please use @c spawn_with_callbacks() unless
464 * you need to setup specific event source(s).
466 * A command line or an argument vector must be passed. If both are present, the argument
467 * vector is appended to the command line. An empty command line is not allowed.
469 * Under Windows, if the child is a console application, and at least one file descriptor is
470 * specified, the new child console (if any) will be hidden.
472 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
474 * @param working_directory child's current working directory, or @c NULL.
475 * @param command_line child program and arguments, or @c NULL.
476 * @param argv child's argument vector, or @c NULL.
477 * @param envp child's environment, or @c NULL.
478 * @param child_pid return location for child process ID, or @c NULL.
479 * @param stdin_fd return location for file descriptor to write to child's stdin, or @c NULL.
480 * @param stdout_fd return location for file descriptor to read child's stdout, or @c NULL.
481 * @param stderr_fd return location for file descriptor to read child's stderr, or @c NULL.
482 * @param error return location for error.
484 * @return @c TRUE on success, @c FALSE on error.
486 static gboolean
spawn_async_with_pipes(const gchar
*working_directory
, const gchar
*command_line
,
487 gchar
**argv
, gchar
**envp
, GPid
*child_pid
, gint
*stdin_fd
, gint
*stdout_fd
,
488 gint
*stderr_fd
, GError
**error
)
490 g_return_val_if_fail(command_line
!= NULL
|| argv
!= NULL
, FALSE
);
499 gchar
*program
= spawn_get_program_name(command_line
, error
);
500 const gchar
*arguments
;
505 command
= g_string_new(NULL
);
506 arguments
= strstr(command_line
, program
) + strlen(program
);
508 if (*arguments
== '"')
510 g_string_append(command
, program
);
515 /* quote the first token, to avoid Windows attemps to run two or more
516 unquoted tokens as a program until an existing file name is found */
517 g_string_printf(command
, "\"%s\"", program
);
520 g_string_append(command
, arguments
);
524 command
= g_string_new(NULL
);
526 environment
= g_array_new(TRUE
, FALSE
, sizeof(char));
528 while (argv
&& *argv
)
529 spawn_append_argument(command
, *argv
++);
532 g_message("full spawn command line: %s\n", command
->str
);
535 while (envp
&& *envp
)
537 g_array_append_vals(environment
, *envp
, strlen(*envp
) + 1);
541 failure
= spawn_create_process_with_pipes(command
->str
, working_directory
,
542 envp
? environment
->data
: NULL
, child_pid
, stdin_fd
, stdout_fd
, stderr_fd
);
544 g_string_free(command
, TRUE
);
545 g_array_free(environment
, TRUE
);
549 g_set_error(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, "%s", failure
);
555 #else /* G_OS_WIN32 */
565 if (!g_shell_parse_argv(command_line
, &cl_argc
, &cl_argv
, error
))
569 for (argc
= 0; argv
[argc
]; argc
++);
571 full_argv
= g_renew(gchar
*, cl_argv
, cl_argc
+ argc
+ 1);
572 memcpy(full_argv
+ cl_argc
, argv
, argc
* sizeof(gchar
*));
573 full_argv
[cl_argc
+ argc
] = NULL
;
578 spawned
= g_spawn_async_with_pipes(working_directory
, full_argv
, envp
,
579 G_SPAWN_SEARCH_PATH
| (child_pid
? G_SPAWN_DO_NOT_REAP_CHILD
: 0), NULL
, NULL
,
580 child_pid
, stdin_fd
, stdout_fd
, stderr_fd
, error
);
582 if (full_argv
!= argv
)
584 full_argv
[cl_argc
] = NULL
;
585 g_strfreev(full_argv
);
589 #endif /* G_OS_WIN32 */
594 * Executes a child asynchronously.
596 * A command line or an argument vector must be passed. If both are present, the argument
597 * vector is appended to the command line. An empty command line is not allowed.
599 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
601 * @param working_directory child's current working directory, or @c NULL.
602 * @param command_line child program and arguments, or @c NULL.
603 * @param argv child's argument vector, or @c NULL.
604 * @param envp child's environment, or @c NULL.
605 * @param child_pid return location for child process ID, or @c NULL.
606 * @param error return location for error.
608 * @return @c TRUE on success, @c FALSE on error.
613 gboolean
spawn_async(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
614 gchar
**envp
, GPid
*child_pid
, GError
**error
)
616 return spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, child_pid
,
617 NULL
, NULL
, NULL
, error
);
622 * Spawn with callbacks - general event sequence:
624 * - Launch the child.
625 * - Setup any I/O callbacks and a child watch callback.
626 * - On sync execution, run a main loop.
627 * - Wait for the child to terminate.
628 * - Check for active I/O sources. If any, add a timeout source to watch them, they should
629 * become inactive real soon now that the child is dead. Otherwise, finalize immediately.
630 * - In the timeout source: check for active I/O sources and finalize if none.
633 typedef struct _SpawnChannelData
635 GIOChannel
*channel
; /* NULL if not created / already destroyed */
642 /* stdout/stderr only */
643 GString
*buffer
; /* NULL if recursive */
644 GString
*line_buffer
; /* NULL if char buffered */
649 static void spawn_destroy_cb(gpointer data
)
651 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
653 g_io_channel_shutdown(sc
->channel
, FALSE
, NULL
);
657 g_string_free(sc
->buffer
, TRUE
);
660 g_string_free(sc
->line_buffer
, TRUE
);
664 static gboolean
spawn_write_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
666 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
668 if (!sc
->cb
.write(channel
, condition
, sc
->cb_data
))
671 return !(condition
& G_IO_FAILURE
);
675 static gboolean
spawn_read_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
677 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
678 GString
*line_buffer
= sc
->line_buffer
;
679 GString
*buffer
= sc
->buffer
? sc
->buffer
: g_string_sized_new(sc
->max_length
);
680 GIOCondition input_cond
= condition
& (G_IO_IN
| G_IO_PRI
);
681 GIOCondition failure_cond
= condition
& G_IO_FAILURE
;
683 * - Normally, read only once. With IO watches, our data processing must be immediate,
684 * which may give the child time to emit more data, and a read loop may combine it into
685 * large stdout and stderr portions. Under Windows, looping blocks.
686 * - On failure, read in a loop. It won't block now, there will be no more data, and the
687 * IO watch is not guaranteed to be called again (under Windows this is the last call).
696 gsize n
= line_buffer
->len
;
698 while ((status
= g_io_channel_read_chars(channel
, line_buffer
->str
+ n
,
699 DEFAULT_IO_LENGTH
, &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
701 g_string_set_size(line_buffer
, n
+ chars_read
);
703 while (n
< line_buffer
->len
)
707 if (n
== sc
->max_length
)
709 else if (strchr("\n", line_buffer
->str
[n
])) /* '\n' or '\0' */
711 else if (n
< line_buffer
->len
- 1 && line_buffer
->str
[n
] == '\r')
712 line_len
= n
+ 1 + (line_buffer
->str
[n
+ 1] == '\n');
718 g_string_append_len(buffer
, line_buffer
->str
, line_len
);
719 g_string_erase(line_buffer
, 0, line_len
);
720 /* input only, failures are reported separately below */
721 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
722 g_string_truncate(buffer
, 0);
733 while ((status
= g_io_channel_read_chars(channel
, buffer
->str
, sc
->max_length
,
734 &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
736 g_string_set_size(buffer
, chars_read
);
737 /* input only, failures are reported separately below */
738 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
745 /* Under OSX, after child death, the read watches receive input conditions instead
746 of error conditions, so we convert the termination statuses into conditions.
747 Should not hurt the other OS. */
748 if (status
== G_IO_STATUS_ERROR
)
749 failure_cond
|= G_IO_ERR
;
750 else if (status
== G_IO_STATUS_EOF
)
751 failure_cond
|= G_IO_HUP
;
754 if (failure_cond
) /* we must signal the callback */
756 if (line_buffer
&& line_buffer
->len
) /* flush the line buffer */
758 g_string_append_len(buffer
, line_buffer
->str
, line_buffer
->len
);
759 /* all data may be from a previous call */
761 input_cond
= G_IO_IN
;
766 g_string_truncate(buffer
, 0);
769 sc
->cb
.read(buffer
, input_cond
| failure_cond
, sc
->cb_data
);
772 if (buffer
!= sc
->buffer
)
773 g_string_free(buffer
, TRUE
);
775 return !failure_cond
;
779 typedef struct _SpawnWatcherData
781 SpawnChannelData sc
[3]; /* stdin, stdout, stderr */
782 GChildWatchFunc exit_cb
;
786 GMainContext
*main_context
; /* NULL if async execution */
787 GMainLoop
*main_loop
; /* NULL if async execution */
791 static void spawn_finalize(SpawnWatcherData
*sw
)
794 sw
->exit_cb(sw
->pid
, sw
->exit_status
, sw
->exit_data
);
798 g_main_loop_quit(sw
->main_loop
);
799 g_main_loop_unref(sw
->main_loop
);
802 g_spawn_close_pid(sw
->pid
);
803 g_slice_free(SpawnWatcherData
, sw
);
807 static gboolean
spawn_timeout_cb(gpointer data
)
809 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
812 for (i
= 0; i
< 3; i
++)
813 if (sw
->sc
[i
].channel
)
821 static void spawn_watch_cb(GPid pid
, gint status
, gpointer data
)
823 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
827 sw
->exit_status
= status
;
829 for (i
= 0; i
< 3; i
++)
831 if (sw
->sc
[i
].channel
)
833 GSource
*source
= g_timeout_source_new(50);
835 g_source_set_callback(source
, spawn_timeout_cb
, data
, NULL
);
836 g_source_attach(source
, sw
->main_context
);
837 g_source_unref(source
);
847 * Executes a child program and setups callbacks.
849 * A command line or an argument vector must be passed. If both are present, the argument
850 * vector is appended to the command line. An empty command line is not allowed.
852 * The synchronous execution may not be combined with recursive callbacks.
854 * In line buffered mode, the child input is broken on '\n', "\r\n", '\r', '\0' and max length.
856 * All I/O callbacks are guaranteed to be invoked at least once with @c G_IO_ERR, @c G_IO_HUP
857 * or @c G_IO_NVAL set (except for a @a stdin_cb which returns @c FALSE before that). For the
858 * non-recursive callbacks, this is guaranteed to be the last call, and may be used to free any
859 * resources associated with the callback.
861 * The @a stdin_cb may write to @c channel only once per invocation, only if @c G_IO_OUT is
862 * set, and only a non-zero number of characters.
864 * @c stdout_cb and @c stderr_cb may modify the received strings in any way, but must not
867 * The default max lengths are 24K for line buffered stdout, 8K for line buffered stderr,
868 * 4K for unbuffered input under Unix, and 2K for unbuffered input under Windows.
870 * @c exit_cb is always invoked last, after all I/O callbacks.
872 * The @a child_pid will be closed automatically, after @a exit_cb is invoked.
874 * @param working_directory child's current working directory, or @c NULL.
875 * @param command_line child program and arguments, or @c NULL.
876 * @param argv child's argument vector, or @c NULL.
877 * @param envp child's environment, or @c NULL.
878 * @param spawn_flags flags from SpawnFlags.
879 * @param stdin_cb callback to send data to childs's stdin, or @c NULL.
880 * @param stdin_data data to pass to @a stdin_cb.
881 * @param stdout_cb callback to receive child's stdout, or @c NULL.
882 * @param stdout_data data to pass to @a stdout_cb.
883 * @param stdout_max_length maximum data length to pass to stdout_cb, @c 0 = default.
884 * @param stderr_cb callback to receive child's stderr, or @c NULL.
885 * @param stderr_data data to pass to @a stderr_cb.
886 * @param stderr_max_length maximum data length to pass to stderr_cb, @c 0 = default.
887 * @param exit_cb callback to invoke when the child exits, or @c NULL.
888 * @param exit_data data to pass to @a exit_cb.
889 * @param child_pid return location for child process ID, or @c NULL.
890 * @param error return location for error.
892 * @return @c TRUE on success, @c FALSE on error.
897 gboolean
spawn_with_callbacks(const gchar
*working_directory
, const gchar
*command_line
,
898 gchar
**argv
, gchar
**envp
, SpawnFlags spawn_flags
, GIOFunc stdin_cb
, gpointer stdin_data
,
899 SpawnReadFunc stdout_cb
, gpointer stdout_data
, gsize stdout_max_length
,
900 SpawnReadFunc stderr_cb
, gpointer stderr_data
, gsize stderr_max_length
,
901 GChildWatchFunc exit_cb
, gpointer exit_data
, GPid
*child_pid
, GError
**error
)
904 int pipe
[3] = { -1, -1, -1 };
906 g_return_val_if_fail(!(spawn_flags
& SPAWN_RECURSIVE
) || !(spawn_flags
& SPAWN_SYNC
),
909 if (spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, &pid
,
910 stdin_cb
? &pipe
[0] : NULL
, stdout_cb
? &pipe
[1] : NULL
,
911 stderr_cb
? &pipe
[2] : NULL
, error
))
913 SpawnWatcherData
*sw
= g_slice_new0(SpawnWatcherData
);
914 gpointer cb_data
[3] = { stdin_data
, stdout_data
, stderr_data
};
918 sw
->main_context
= spawn_flags
& SPAWN_SYNC
? g_main_context_new() : NULL
;
923 for (i
= 0; i
< 3; i
++)
925 SpawnChannelData
*sc
= &sw
->sc
[i
];
926 GIOCondition condition
;
927 GSourceFunc callback
;
933 sc
->channel
= g_io_channel_win32_new_fd(pipe
[i
]);
935 sc
->channel
= g_io_channel_unix_new(pipe
[i
]);
936 g_io_channel_set_flags(sc
->channel
, G_IO_FLAG_NONBLOCK
, NULL
);
938 g_io_channel_set_encoding(sc
->channel
, NULL
, NULL
);
939 /* we have our own buffers, and GIO buffering blocks under Windows */
940 g_io_channel_set_buffered(sc
->channel
, FALSE
);
941 sc
->cb_data
= cb_data
[i
];
945 sc
->cb
.write
= stdin_cb
;
946 condition
= G_IO_OUT
| G_IO_FAILURE
;
947 callback
= (GSourceFunc
) spawn_write_cb
;
951 gboolean line_buffered
= !(spawn_flags
&
952 ((SPAWN_STDOUT_UNBUFFERED
>> 1) << i
));
954 condition
= G_IO_IN
| G_IO_PRI
| G_IO_FAILURE
;
955 callback
= (GSourceFunc
) spawn_read_cb
;
959 sc
->cb
.read
= stdout_cb
;
960 sc
->max_length
= stdout_max_length
? stdout_max_length
:
961 line_buffered
? 24576 : DEFAULT_IO_LENGTH
;
965 sc
->cb
.read
= stderr_cb
;
966 sc
->max_length
= stderr_max_length
? stderr_max_length
:
967 line_buffered
? 8192 : DEFAULT_IO_LENGTH
;
972 sc
->line_buffer
= g_string_sized_new(sc
->max_length
+
977 source
= g_io_create_watch(sc
->channel
, condition
);
978 g_io_channel_unref(sc
->channel
);
980 if (spawn_flags
& (SPAWN_STDIN_RECURSIVE
<< i
))
981 g_source_set_can_recurse(source
, TRUE
);
982 else if (i
) /* to avoid new string on each call */
983 sc
->buffer
= g_string_sized_new(sc
->max_length
);
985 g_source_set_callback(source
, callback
, sc
, spawn_destroy_cb
);
986 g_source_attach(source
, sw
->main_context
);
987 g_source_unref(source
);
990 sw
->exit_cb
= exit_cb
;
991 sw
->exit_data
= exit_data
;
992 source
= g_child_watch_source_new(pid
);
993 g_source_set_callback(source
, (GSourceFunc
) spawn_watch_cb
, sw
, NULL
);
994 g_source_attach(source
, sw
->main_context
);
995 g_source_unref(source
);
997 if (spawn_flags
& SPAWN_SYNC
)
999 sw
->main_loop
= g_main_loop_new(sw
->main_context
, FALSE
);
1000 g_main_context_unref(sw
->main_context
);
1001 g_main_loop_run(sw
->main_loop
);
1012 * Writes (a portion of) the data pointed by @a data->ptr to the @a channel.
1014 * If @c G_IO_OUT in @a condition is set, and the @a data->size is > 0, attempts to write
1015 * @a data->ptr (or a portion of it, depending on the size) to the @a channel. On success,
1016 * increases ptr and decreases size with the number of characters written.
1018 * This function may converted to @c GIOFunc and passed to @c spawn_with_callbacks() as
1019 * @c stdin_cb, together with a @c SpawnWriteData for @c stdin_data. As with any other
1020 * callback data, make sure that @c stdin_data exists while the child is being executed.
1021 * (For example, on asynchronous execution, you can allocate the data in the heap, and free
1022 * it in your @c spawn_with_callbacks() @c exit_cb callback.)
1024 * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error,
1025 * @c FALSE otherwise.
1030 gboolean
spawn_write_data(GIOChannel
*channel
, GIOCondition condition
, SpawnWriteData
*data
)
1032 if ((condition
& G_IO_OUT
) && data
->size
)
1034 gsize chars_written
= 0;
1036 g_io_channel_write_chars(channel
, data
->ptr
, data
->size
< DEFAULT_IO_LENGTH
?
1037 data
->size
: DEFAULT_IO_LENGTH
, &chars_written
, NULL
);
1039 /* "This can be nonzero even if the return value is not G_IO_STATUS_NORMAL." */
1042 data
->ptr
+= chars_written
;
1043 data
->size
-= chars_written
;
1047 return data
->size
> 0 && !(condition
& G_IO_FAILURE
);
1051 static void spawn_append_gstring_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1053 if (condition
& (G_IO_IN
| G_IO_PRI
))
1054 g_string_append_len((GString
*) data
, string
->str
, string
->len
);
1058 static void spawn_get_exit_status_cb(G_GNUC_UNUSED GPid pid
, gint status
, gpointer exit_status
)
1060 *(gint
*) exit_status
= status
;
1065 * Executes a child synchronously.
1067 * A command line or an argument vector must be passed. If both are present, the argument
1068 * vector is appended to the command line. An empty command line is not allowed.
1070 * The @a stdin_data is sent to the child with @c spawn_write_data().
1072 * All output from the child, including the nul characters, is stored in @a stdout_data and
1073 * @a stderr_data (if non-NULL). Any existing data in these strings will be erased.
1075 * @param working_directory child's current working directory, or @c NULL.
1076 * @param command_line child program and arguments, or @c NULL.
1077 * @param argv child's argument vector, or @c NULL.
1078 * @param envp child's environment, or @c NULL.
1079 * @param stdin_data data to send to childs's stdin, or @c NULL.
1080 * @param stdout_data GString location to receive the child's stdout, or NULL.
1081 * @param stderr_data GString location to receive the child's stderr, or NULL.
1082 * @param exit_status return location for the child exit code, or NULL.
1083 * @param error return location for error.
1085 * @return @c TRUE on success, @c FALSE on error.
1090 gboolean
spawn_sync(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
1091 gchar
**envp
, SpawnWriteData
*stdin_data
, GString
*stdout_data
, GString
*stderr_data
,
1092 gint
*exit_status
, GError
**error
)
1094 g_string_truncate(stdout_data
, 0);
1095 g_string_truncate(stderr_data
, 0);
1097 return spawn_with_callbacks(working_directory
, command_line
, argv
, envp
, SPAWN_SYNC
|
1098 SPAWN_UNBUFFERED
, stdin_data
? (GIOFunc
) spawn_write_data
: NULL
, stdin_data
,
1099 stdout_data
? spawn_append_gstring_cb
: NULL
, stdout_data
, 0,
1100 stderr_data
? spawn_append_gstring_cb
: NULL
, stderr_data
, 0,
1101 exit_status
? spawn_get_exit_status_cb
: NULL
, exit_status
, NULL
, error
);
1105 /* tests, not part of the API */
1110 static gboolean
read_line(const char *prompt
, char *buffer
, size_t size
)
1112 fputs(prompt
, stderr
);
1115 if (fgets(buffer
, size
, stdin
))
1117 char *s
= strchr(buffer
, '\n');
1127 static GString
*read_string(const char *prompt
)
1129 char buffer
[0x1000]; /* larger portions for spawn < file */
1130 GString
*string
= g_string_sized_new(sizeof buffer
);
1132 while (read_line(prompt
, buffer
, sizeof buffer
))
1135 g_string_append_c(string
, '\n');
1137 g_string_append(string
, buffer
);
1142 g_string_free(string
, TRUE
);
1150 static void print_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1152 if (condition
& (G_IO_IN
| G_IO_PRI
))
1156 printf("%s: ", (const gchar
*) data
);
1157 /*fputs(string->str, stdout);*/
1158 for (i
= 0; i
< string
->len
; i
++)
1160 unsigned char c
= (unsigned char) string
->str
[i
];
1161 printf(c
>= ' ' && c
< 0x80 ? "%c" : "\\x%02x", c
);
1168 static void print_status(gint status
)
1170 fputs("finished, ", stderr
);
1172 if (SPAWN_WIFEXITED(status
))
1173 fprintf(stderr
, "exit code %d\n", SPAWN_WEXITSTATUS(status
));
1175 fputs("abnormal termination\n", stderr
);
1179 static void exit_cb(GPid pid
, gint status
, G_GNUC_UNUSED gpointer data
)
1181 fprintf(stderr
, "process %u ", (guint
) pid
);
1182 print_status(status
);
1186 static void watch_cb(GPid pid
, gint status
, gpointer data
)
1188 g_spawn_close_pid(pid
);
1189 exit_cb(pid
, status
, NULL
);
1190 g_main_loop_quit((GMainLoop
*) data
);
1194 int main(int argc
, char **argv
)
1200 fputs("usage: spawn <test-type>\n", stderr
);
1204 test_type
= argv
[1];
1206 if (!strcmp(test_type
, "syntax") || !strcmp(test_type
, "syntexec"))
1208 char command_line
[0x100];
1210 while (read_line("command line: ", command_line
, sizeof command_line
))
1212 GError
*error
= NULL
;
1214 if (spawn_check_command(command_line
, argv
[1][4] == 'e', &error
))
1215 fputs("valid\n", stderr
);
1218 fprintf(stderr
, "error: %s\n", error
->message
);
1219 g_error_free(error
);
1223 else if (!strcmp(test_type
, "execute"))
1225 char command_line
[0x100];
1227 while (read_line("command line: ", command_line
, sizeof command_line
))
1229 char working_directory
[0x100];
1230 char args
[4][0x100];
1231 char envs
[4][0x100];
1232 char *argv
[] = { args
[0], args
[1], args
[2], args
[3], NULL
};
1233 char *envp
[] = { envs
[0], envs
[1], envs
[2], envs
[3], NULL
};
1236 GError
*error
= NULL
;
1238 read_line("working directory: ", working_directory
, sizeof working_directory
);
1240 fputs("up to 4 arguments\n", stderr
);
1241 for (i
= 0; i
< 4 && read_line("argument: ", args
[i
], sizeof args
[i
]); i
++);
1244 fputs("up to 4 variables, or empty line for parent environment\n", stderr
);
1245 for (i
= 0; i
< 4 && read_line("variable: ", envs
[i
], sizeof envs
[i
]); i
++);
1248 if (spawn_async_with_pipes(*working_directory
? working_directory
: NULL
,
1249 *command_line
? command_line
: NULL
, argv
, i
? envp
: NULL
, &pid
, NULL
,
1250 NULL
, NULL
, &error
))
1252 GMainLoop
*loop
= g_main_loop_new(NULL
, TRUE
);
1254 g_child_watch_add(pid
, watch_cb
, loop
);
1255 g_main_loop_run(loop
);
1256 g_main_loop_unref(loop
);
1260 fprintf(stderr
, "error: %s\n", error
->message
);
1261 g_error_free(error
);
1265 else if (!strcmp(test_type
, "redirect") || !strcmp(test_type
, "redinput"))
1267 char command_line
[0x100];
1268 gboolean output
= test_type
[4] == 'r';
1270 while (read_line("command line: ", command_line
, sizeof command_line
))
1272 GString
*stdin_text
= read_string("text to send: ");
1273 SpawnWriteData stdin_data
;
1274 GError
*error
= NULL
;
1278 stdin_data
.ptr
= stdin_text
->str
;
1279 stdin_data
.size
= stdin_text
->len
;
1282 if (!spawn_with_callbacks(NULL
, command_line
, NULL
, NULL
, SPAWN_SYNC
,
1283 stdin_text
? (GIOFunc
) spawn_write_data
: NULL
, &stdin_data
,
1284 output
? print_cb
: NULL
, "stdout", 0, output
? print_cb
: NULL
,
1285 "stderr", 0, exit_cb
, NULL
, NULL
, &error
))
1287 fprintf(stderr
, "error: %s\n", error
->message
);
1288 g_error_free(error
);
1292 g_string_free(stdin_text
, TRUE
);
1295 else if (!strcmp(test_type
, "capture"))
1297 char command_line
[0x100];
1299 while (read_line("command line: ", command_line
, sizeof command_line
))
1301 GString
*stdin_text
= read_string("text to send: ");
1302 SpawnWriteData stdin_data
= { NULL
, 0 };
1303 GString
*stdout_data
= g_string_sized_new(0x10000); /* may grow */
1304 GString
*stderr_data
= g_string_sized_new(0x1000); /* may grow */
1306 GError
*error
= NULL
;
1310 stdin_data
.ptr
= stdin_text
->str
;
1311 stdin_data
.size
= stdin_text
->len
;
1314 if (spawn_sync(NULL
, command_line
, NULL
, NULL
, &stdin_data
, stdout_data
,
1315 stderr_data
, &exit_status
, &error
))
1317 printf("stdout: %s\n", stdout_data
->str
);
1318 printf("stderr: %s\n", stderr_data
->str
);
1319 print_status(exit_status
);
1323 fprintf(stderr
, "error: %s\n", error
->message
);
1324 g_error_free(error
);
1328 g_string_free(stdin_text
, TRUE
);
1330 g_string_free(stdout_data
, TRUE
);
1331 g_string_free(stderr_data
, TRUE
);
1336 fprintf(stderr
, "spawn: unknown test type '%s'", argv
[1]);
1342 #endif /* SPAWN_TEST */