Fix a few typos in NEWS
[geany-mirror.git] / src / spawn.c
blob3dd7f996d0d120a794d6fd1f975ec1fe29766933
1 /*
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.
22 * In particular:
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).
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif
46 #include <errno.h>
47 #include <string.h>
49 #include "spawn.h"
51 #ifdef G_OS_WIN32
52 # include "win32defines.h"
53 # include <ctype.h> /* isspace() */
54 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
55 # include <io.h> /* _open_osfhandle, _close */
56 # include <windows.h>
57 #else /* G_OS_WIN32 */
58 # include <signal.h>
59 #endif /* G_OS_WIN32 */
61 #ifdef SPAWN_TEST
62 # define _
63 # define GEANY_API_SYMBOL
64 #else
65 # include "support.h"
66 #endif
68 #ifdef G_OS_WIN32
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
72 #else
73 # define DEFAULT_IO_LENGTH 4096
74 #endif
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)
91 gchar *program;
93 #ifdef G_OS_WIN32
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))
100 command_line++;
102 if (!*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)"));
107 return FALSE;
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 == '"')
115 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);
123 return FALSE;
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"));
130 return FALSE;
133 else
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"));
144 return FALSE;
148 program = g_strndup(command_line, s - command_line);
149 arguments = s + (*s == '"');
151 for (s = arguments; *s; s++)
153 if (*s == '"')
155 const char *slash;
157 for (slash = s; slash > arguments && slash[-1] == '\\'; slash--);
158 if ((s - slash) % 2 == 0)
159 open_quote ^= TRUE;
163 if (open_quote)
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);
169 g_free(program);
170 return FALSE;
172 #else /* G_OS_WIN32 */
173 int argc;
174 char **argv;
176 if (!g_shell_parse_argv(command_line, &argc, &argv, error))
177 return FALSE;
179 /* empty string results in parse error, so argv[0] is not NULL */
180 program = g_strdup(argv[0]);
181 g_strfreev(argv);
182 #endif /* G_OS_WIN32 */
184 return program;
189 * Checks whether a command line is valid.
191 * Checks if @a command_line is syntactically valid.
193 * All OS:
194 * - any leading spaces, tabs and new lines are skipped
195 * - an empty command is invalid
196 * Unix:
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
199 * Windows:
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.
219 * @since 1.25
221 GEANY_API_SYMBOL
222 gboolean spawn_check_command(const gchar *command_line, gboolean execute, GError **error)
224 gchar *program = spawn_get_program_name(command_line, error);
226 if (!program)
227 return FALSE;
229 if (execute)
231 gchar *executable = g_find_program_in_path(program);
233 if (!executable)
235 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_FAILED, /* or SPAWN error? */
236 _("Program '%s' not found"), program);
237 g_free(program);
238 return FALSE;
241 g_free(executable);
244 g_free(program);
245 return TRUE;
250 * Kills a process.
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.
262 * @since 1.25
264 GEANY_API_SYMBOL
265 gboolean spawn_kill_process(GPid pid, GError **error)
267 #ifdef G_OS_WIN32
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);
274 g_free(message);
275 return FALSE;
277 #else
278 if (kill(pid, SIGTERM))
280 g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, "%s", g_strerror(errno));
281 return FALSE;
283 #endif
284 return TRUE;
288 #ifdef G_OS_WIN32
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 };
293 STARTUPINFO startup;
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 */
300 gboolean pipe_io;
301 int i;
303 ZeroMemory(&startup, sizeof startup);
304 startup.cb = sizeof startup;
305 pipe_io = stdin_fd || stdout_fd || stderr_fd;
307 if (pipe_io)
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";
321 goto leave;
324 if (fd[i])
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));
332 goto leave;
335 else if (!CloseHandle(hpipe[i]))
337 failed = "CloseHandle";
338 goto leave;
341 if (!SetHandleInformation(hpipe[i + 3], HANDLE_FLAG_INHERIT,
342 HANDLE_FLAG_INHERIT))
344 failed = "SetHandleInformation";
345 goto leave;
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 */
360 else
362 failed = NULL;
363 CloseHandle(process.hThread); /* we don't need this */
365 if (hprocess)
366 *hprocess = process.hProcess;
367 else
368 CloseHandle(process.hProcess);
371 leave:
372 if (failed)
374 if (!message)
375 message = g_win32_error_message(GetLastError());
377 failure = g_strdup_printf("%s() failed: %s", failed, message);
378 g_free(message);
381 if (pipe_io)
383 for (i = 0; i < 3; i++)
385 if (failed)
387 if (fd[i] && *fd[i] != -1)
388 _close(*fd[i]);
389 else if (hpipe[i])
390 CloseHandle(hpipe[i]);
393 if (hpipe[i + 3])
394 CloseHandle(hpipe[i + 3]);
398 return failure;
402 static void spawn_append_argument(GString *command, const char *text)
404 const char *s;
406 if (command->len)
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))
413 break;
416 if (*text && !*s)
417 g_string_append(command, text);
418 else
420 g_string_append_c(command, '"');
422 for (s = text; *s; s++)
424 const char *slash;
426 for (slash = s; *slash == '\\'; slash++);
428 if (slash > s)
430 g_string_append_len(command, s, slash - s);
432 if (!*slash || *slash == '"')
434 g_string_append_len(command, s, slash - s);
436 if (!*slash)
437 break;
440 s = slash;
443 if (*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);
487 #ifdef G_OS_WIN32
488 GString *command;
489 GArray *environment;
490 gchar *failure;
492 if (command_line)
494 gchar *program = spawn_get_program_name(command_line, error);
495 const gchar *arguments;
497 if (!program)
498 return FALSE;
500 command = g_string_new(NULL);
501 arguments = strstr(command_line, program) + strlen(program);
503 if (*arguments == '"')
505 g_string_append(command, program);
506 arguments++;
508 else
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);
516 g_free(program);
518 else
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++);
526 #ifdef SPAWN_TEST
527 g_message("full spawn command line: %s\n", command->str);
528 #endif
530 while (envp && *envp)
532 g_array_append_vals(environment, *envp, strlen(*envp) + 1);
533 envp++;
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);
542 if (failure)
544 g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, "%s", failure);
545 g_free(failure);
546 return FALSE;
549 return TRUE;
550 #else /* G_OS_WIN32 */
551 int cl_argc;
552 char **full_argv;
553 gboolean spawned;
555 if (command_line)
557 int argc = 0;
558 char **cl_argv;
560 if (!g_shell_parse_argv(command_line, &cl_argc, &cl_argv, error))
561 return FALSE;
563 if (argv)
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;
570 else
571 full_argv = argv;
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);
583 return spawned;
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.
605 * @since 1.25
607 GEANY_API_SYMBOL
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 */
631 union
633 GIOFunc write;
634 SpawnReadFunc read;
635 } cb;
636 gpointer cb_data;
637 /* stdout/stderr only */
638 GString *buffer; /* NULL if recursive */
639 GString *line_buffer; /* NULL if char buffered */
640 gsize max_length;
641 } SpawnChannelData;
644 static void spawn_destroy_cb(gpointer data)
646 SpawnChannelData *sc = (SpawnChannelData *) data;
648 g_io_channel_shutdown(sc->channel, FALSE, NULL);
649 sc->channel = NULL;
651 if (sc->buffer)
652 g_string_free(sc->buffer, TRUE);
654 if (sc->line_buffer)
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))
664 return FALSE;
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).
684 if (input_cond)
686 gsize chars_read;
687 GIOStatus status;
689 if (line_buffer)
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)
700 gsize line_len = 0;
702 if (n == sc->max_length)
703 line_len = n;
704 else if (strchr("\n", line_buffer->str[n])) /* '\n' or '\0' */
705 line_len = n + 1;
706 else if (n < line_buffer->len - 1 && line_buffer->str[n] == '\r')
707 line_len = n + 1 + (line_buffer->str[n + 1] == '\n');
709 if (!line_len)
710 n++;
711 else
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);
718 n = 0;
722 if (!failure_cond)
723 break;
726 else
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);
735 if (!failure_cond)
736 break;
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 */
755 if (!input_cond)
756 input_cond = G_IO_IN;
758 else
760 input_cond = 0;
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;
778 gpointer exit_data;
779 GPid pid;
780 gint exit_status;
781 GMainContext *main_context; /* NULL if async execution */
782 GMainLoop *main_loop; /* NULL if async execution */
783 } SpawnWatcherData;
786 static void spawn_finalize(SpawnWatcherData *sw)
788 if (sw->exit_cb)
789 sw->exit_cb(sw->pid, sw->exit_status, sw->exit_data);
791 if (sw->main_loop)
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;
805 int i;
807 for (i = 0; i < 3; i++)
808 if (sw->sc[i].channel)
809 return TRUE;
811 spawn_finalize(sw);
812 return FALSE;
816 static void spawn_watch_cb(GPid pid, gint status, gpointer data)
818 SpawnWatcherData *sw = (SpawnWatcherData *) data;
819 int i;
821 sw->pid = pid;
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);
833 return;
837 spawn_finalize(sw);
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
860 * free them.
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.
889 * @since 1.25
891 GEANY_API_SYMBOL
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)
898 GPid pid;
899 int pipe[3] = { -1, -1, -1 };
901 g_return_val_if_fail(!(spawn_flags & SPAWN_RECURSIVE) || !(spawn_flags & SPAWN_SYNC),
902 FALSE);
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 };
910 GSource *source;
911 int i;
913 sw->main_context = spawn_flags & SPAWN_SYNC ? g_main_context_new() : NULL;
915 if (child_pid)
916 *child_pid = pid;
918 for (i = 0; i < 3; i++)
920 SpawnChannelData *sc = &sw->sc[i];
921 GIOCondition condition;
922 GSourceFunc callback;
924 if (pipe[i] == -1)
925 continue;
927 #ifdef G_OS_WIN32
928 sc->channel = g_io_channel_win32_new_fd(pipe[i]);
929 #else
930 sc->channel = g_io_channel_unix_new(pipe[i]);
931 g_io_channel_set_flags(sc->channel, G_IO_FLAG_NONBLOCK, NULL);
932 #endif
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];
938 if (i == 0)
940 sc->cb.write = stdin_cb;
941 condition = G_IO_OUT | G_IO_FAILURE;
942 callback = (GSourceFunc) spawn_write_cb;
944 else
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;
952 if (i == 1)
954 sc->cb.read = stdout_cb;
955 sc->max_length = stdout_max_length ? stdout_max_length :
956 line_buffered ? 24576 : DEFAULT_IO_LENGTH;
958 else
960 sc->cb.read = stderr_cb;
961 sc->max_length = stderr_max_length ? stderr_max_length :
962 line_buffered ? 8192 : DEFAULT_IO_LENGTH;
965 if (line_buffered)
967 sc->line_buffer = g_string_sized_new(sc->max_length +
968 DEFAULT_IO_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);
999 return TRUE;
1002 return FALSE;
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.
1022 * @since 1.25
1024 GEANY_API_SYMBOL
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." */
1035 if (chars_written)
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.
1082 * @since 1.25
1084 GEANY_API_SYMBOL
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 */
1101 #ifdef SPAWN_TEST
1102 #include <stdio.h>
1105 static gboolean read_line(const char *prompt, char *buffer, size_t size)
1107 fputs(prompt, stderr);
1108 *buffer = '\0';
1110 if (fgets(buffer, size, stdin))
1112 char *s = strchr(buffer, '\n');
1114 if (s)
1115 *s = '\0';
1118 return *buffer;
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))
1129 if (string->len)
1130 g_string_append_c(string, '\n');
1132 g_string_append(string, buffer);
1135 if (!string->len)
1137 g_string_free(string, TRUE);
1138 string = NULL;
1141 return string;
1145 static void print_cb(GString *string, GIOCondition condition, gpointer data)
1147 if (condition & (G_IO_IN | G_IO_PRI))
1149 gsize i;
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);
1158 putchar('\n');
1163 static void print_status(gint status)
1165 fputs("finished, ", stderr);
1167 if (WIFEXITED(status))
1168 fprintf(stderr, "exit code %d\n", WEXITSTATUS(status));
1169 else
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)
1191 char *test_type;
1193 if (argc != 2)
1195 fputs("usage: spawn <test-type>\n", stderr);
1196 return 1;
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);
1211 else
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 };
1229 int i;
1230 GPid pid;
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++);
1237 argv[i] = NULL;
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++);
1241 envp[i] = NULL;
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);
1253 else
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;
1271 if (stdin_text)
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);
1286 if (stdin_text)
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 */
1300 gint exit_status;
1301 GError *error = NULL;
1303 if (stdin_text)
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);
1316 else
1318 fprintf(stderr, "error: %s\n", error->message);
1319 g_error_free(error);
1322 if (stdin_text)
1323 g_string_free(stdin_text, TRUE);
1325 g_string_free(stdout_data, TRUE);
1326 g_string_free(stderr_data, TRUE);
1329 else
1331 fprintf(stderr, "spawn: unknown test type '%s'", argv[1]);
1332 return 1;
1335 return 0;
1337 #endif /* SPAWN_TEST */