Bump API version for new plugin entry points (oops)
[geany-mirror.git] / src / spawn.c
blobbff20f8a111f182c900c11b761d0b50b873f1c93
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 /** @file spawn.h
43 * Portable and convenient process spawning and communication.
46 #ifdef HAVE_CONFIG_H
47 # include "config.h"
48 #endif
50 #include <errno.h>
51 #include <string.h>
53 #include "spawn.h"
55 #ifdef G_OS_WIN32
56 # include <ctype.h> /* isspace() */
57 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
58 # include <io.h> /* _open_osfhandle, _close */
59 # include <windows.h>
60 #else /* G_OS_WIN32 */
61 # include <signal.h>
62 #endif /* G_OS_WIN32 */
64 #ifdef SPAWN_TEST
65 # define _
66 # define GEANY_API_SYMBOL
67 #else
68 # include "support.h"
69 #endif
71 #ifdef G_OS_WIN32
72 /* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more
73 balanced than 4095 + 1. May be different on the latest Windows/glib? */
74 # define DEFAULT_IO_LENGTH 2048
75 #else
76 # define DEFAULT_IO_LENGTH 4096
77 #endif
79 #define G_IO_FAILURE (G_IO_ERR | G_IO_HUP | G_IO_NVAL) /* always used together */
83 * Checks whether a command line is syntactically valid and extracts the program name from it.
85 * See @c spawn_check_command() for details.
87 * @param command_line the command line to check and get the program name from.
88 * @param error return location for error.
90 * @return allocated string with the program name on success, @c NULL on error.
92 static gchar *spawn_get_program_name(const gchar *command_line, GError **error)
94 gchar *program;
96 #ifdef G_OS_WIN32
97 gboolean open_quote = FALSE;
98 const gchar *s, *arguments;
100 g_return_val_if_fail(command_line != NULL, FALSE);
102 while (*command_line && strchr(" \t\r\n", *command_line))
103 command_line++;
105 if (!*command_line)
107 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_EMPTY_STRING,
108 /* TL note: from glib */
109 _("Text was empty (or contained only whitespace)"));
110 return FALSE;
113 /* To prevent Windows from doing something weird, we want to be 100% sure that the
114 character after the program name is a delimiter, so we allow space and tab only. */
116 if (*command_line == '"')
118 command_line++;
119 /* Windows allows "foo.exe, but we may have extra arguments */
120 if ((s = strchr(command_line, '"')) == NULL)
122 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING,
123 /* TL note: from glib */
124 _("Text ended before matching quote was found for %c."
125 " (The text was '%s')"), '"', command_line);
126 return FALSE;
129 if (!strchr(" \t", s[1])) /* strchr() catches s[1] == '\0' */
131 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING,
132 _("A quoted Windows program name must be entirely inside the quotes"));
133 return FALSE;
136 else
138 const gchar *quote = strchr(command_line, '"');
140 /* strchr() catches *s == '\0', and the for body is empty */
141 for (s = command_line; !strchr(" \t", *s); s++);
143 if (quote && quote < s)
145 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING,
146 _("A quoted Windows program name must be entirely inside the quotes"));
147 return FALSE;
151 program = g_strndup(command_line, s - command_line);
152 arguments = s + (*s == '"');
154 for (s = arguments; *s; s++)
156 if (*s == '"')
158 const char *slash;
160 for (slash = s; slash > arguments && slash[-1] == '\\'; slash--);
161 if ((s - slash) % 2 == 0)
162 open_quote ^= TRUE;
166 if (open_quote)
168 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_BAD_QUOTING,
169 /* TL note: from glib */
170 _("Text ended before matching quote was found for %c."
171 " (The text was '%s')"), '"', command_line);
172 g_free(program);
173 return FALSE;
175 #else /* G_OS_WIN32 */
176 int argc;
177 char **argv;
179 if (!g_shell_parse_argv(command_line, &argc, &argv, error))
180 return FALSE;
182 /* empty string results in parse error, so argv[0] is not NULL */
183 program = g_strdup(argv[0]);
184 g_strfreev(argv);
185 #endif /* G_OS_WIN32 */
187 return program;
192 * Checks whether a command line is valid.
194 * Checks if @a command_line is syntactically valid.
196 * All OS:
197 * - any leading spaces, tabs and new lines are skipped
198 * - an empty command is invalid
200 * Unix:
201 * - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv()
202 * - as a consequence, an unqouted # at the start of an argument comments to the end of line
204 * Windows:
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.
224 * @since 1.25
226 GEANY_API_SYMBOL
227 gboolean spawn_check_command(const gchar *command_line, gboolean execute, GError **error)
229 gchar *program = spawn_get_program_name(command_line, error);
231 if (!program)
232 return FALSE;
234 if (execute)
236 gchar *executable = g_find_program_in_path(program);
238 if (!executable)
240 g_set_error(error, G_SHELL_ERROR, G_SHELL_ERROR_FAILED, /* or SPAWN error? */
241 _("Program '%s' not found"), program);
242 g_free(program);
243 return FALSE;
246 g_free(executable);
249 g_free(program);
250 return TRUE;
255 * Kills a process.
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.
267 * @since 1.25
269 GEANY_API_SYMBOL
270 gboolean spawn_kill_process(GPid pid, GError **error)
272 #ifdef G_OS_WIN32
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);
279 g_free(message);
280 return FALSE;
282 #else
283 if (kill(pid, SIGTERM))
285 g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, "%s", g_strerror(errno));
286 return FALSE;
288 #endif
289 return TRUE;
293 #ifdef G_OS_WIN32
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 };
298 STARTUPINFO startup;
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 */
305 gboolean pipe_io;
306 int i;
308 ZeroMemory(&startup, sizeof startup);
309 startup.cb = sizeof startup;
310 pipe_io = stdin_fd || stdout_fd || stderr_fd;
312 if (pipe_io)
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";
326 goto leave;
329 if (fd[i])
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));
337 goto leave;
340 else if (!CloseHandle(hpipe[i]))
342 failed = "CloseHandle";
343 goto leave;
346 if (!SetHandleInformation(hpipe[i + 3], HANDLE_FLAG_INHERIT,
347 HANDLE_FLAG_INHERIT))
349 failed = "SetHandleInformation";
350 goto leave;
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 */
365 else
367 failed = NULL;
368 CloseHandle(process.hThread); /* we don't need this */
370 if (hprocess)
371 *hprocess = process.hProcess;
372 else
373 CloseHandle(process.hProcess);
376 leave:
377 if (failed)
379 if (!message)
380 message = g_win32_error_message(GetLastError());
382 failure = g_strdup_printf("%s() failed: %s", failed, message);
383 g_free(message);
386 if (pipe_io)
388 for (i = 0; i < 3; i++)
390 if (failed)
392 if (fd[i] && *fd[i] != -1)
393 _close(*fd[i]);
394 else if (hpipe[i])
395 CloseHandle(hpipe[i]);
398 if (hpipe[i + 3])
399 CloseHandle(hpipe[i + 3]);
403 return failure;
407 static void spawn_append_argument(GString *command, const char *text)
409 const char *s;
411 if (command->len)
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))
418 break;
421 if (*text && !*s)
422 g_string_append(command, text);
423 else
425 g_string_append_c(command, '"');
427 for (s = text; *s; s++)
429 const char *slash;
431 for (slash = s; *slash == '\\'; slash++);
433 if (slash > s)
435 g_string_append_len(command, s, slash - s);
437 if (!*slash || *slash == '"')
439 g_string_append_len(command, s, slash - s);
441 if (!*slash)
442 break;
445 s = slash;
448 if (*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);
492 #ifdef G_OS_WIN32
493 GString *command;
494 GArray *environment;
495 gchar *failure;
497 if (command_line)
499 gchar *program = spawn_get_program_name(command_line, error);
500 const gchar *arguments;
502 if (!program)
503 return FALSE;
505 command = g_string_new(NULL);
506 arguments = strstr(command_line, program) + strlen(program);
508 if (*arguments == '"')
510 g_string_append(command, program);
511 arguments++;
513 else
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);
521 g_free(program);
523 else
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++);
531 #ifdef SPAWN_TEST
532 g_message("full spawn command line: %s\n", command->str);
533 #endif
535 while (envp && *envp)
537 g_array_append_vals(environment, *envp, strlen(*envp) + 1);
538 envp++;
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);
547 if (failure)
549 g_set_error(error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, "%s", failure);
550 g_free(failure);
551 return FALSE;
554 return TRUE;
555 #else /* G_OS_WIN32 */
556 int cl_argc;
557 char **full_argv;
558 gboolean spawned;
560 if (command_line)
562 int argc = 0;
563 char **cl_argv;
565 if (!g_shell_parse_argv(command_line, &cl_argc, &cl_argv, error))
566 return FALSE;
568 if (argv)
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;
575 else
576 full_argv = argv;
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);
588 return spawned;
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.
610 * @since 1.25
612 GEANY_API_SYMBOL
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 */
636 union
638 GIOFunc write;
639 SpawnReadFunc read;
640 } cb;
641 gpointer cb_data;
642 /* stdout/stderr only */
643 GString *buffer; /* NULL if recursive */
644 GString *line_buffer; /* NULL if char buffered */
645 gsize max_length;
646 } SpawnChannelData;
649 static void spawn_destroy_cb(gpointer data)
651 SpawnChannelData *sc = (SpawnChannelData *) data;
653 g_io_channel_shutdown(sc->channel, FALSE, NULL);
654 sc->channel = NULL;
656 if (sc->buffer)
657 g_string_free(sc->buffer, TRUE);
659 if (sc->line_buffer)
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))
669 return FALSE;
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).
689 if (input_cond)
691 gsize chars_read;
692 GIOStatus status;
694 if (line_buffer)
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)
705 gsize line_len = 0;
707 if (n == sc->max_length)
708 line_len = n;
709 else if (strchr("\n", line_buffer->str[n])) /* '\n' or '\0' */
710 line_len = n + 1;
711 else if (n < line_buffer->len - 1 && line_buffer->str[n] == '\r')
712 line_len = n + 1 + (line_buffer->str[n + 1] == '\n');
714 if (!line_len)
715 n++;
716 else
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);
723 n = 0;
727 if (!failure_cond)
728 break;
731 else
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);
740 if (!failure_cond)
741 break;
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 */
760 if (!input_cond)
761 input_cond = G_IO_IN;
763 else
765 input_cond = 0;
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;
783 gpointer exit_data;
784 GPid pid;
785 gint exit_status;
786 GMainContext *main_context; /* NULL if async execution */
787 GMainLoop *main_loop; /* NULL if async execution */
788 } SpawnWatcherData;
791 static void spawn_finalize(SpawnWatcherData *sw)
793 if (sw->exit_cb)
794 sw->exit_cb(sw->pid, sw->exit_status, sw->exit_data);
796 if (sw->main_loop)
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;
810 int i;
812 for (i = 0; i < 3; i++)
813 if (sw->sc[i].channel)
814 return TRUE;
816 spawn_finalize(sw);
817 return FALSE;
821 static void spawn_watch_cb(GPid pid, gint status, gpointer data)
823 SpawnWatcherData *sw = (SpawnWatcherData *) data;
824 int i;
826 sw->pid = pid;
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);
838 return;
842 spawn_finalize(sw);
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
865 * free them.
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.
894 * @since 1.25
896 GEANY_API_SYMBOL
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)
903 GPid pid;
904 int pipe[3] = { -1, -1, -1 };
906 g_return_val_if_fail(!(spawn_flags & SPAWN_RECURSIVE) || !(spawn_flags & SPAWN_SYNC),
907 FALSE);
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 };
915 GSource *source;
916 int i;
918 sw->main_context = spawn_flags & SPAWN_SYNC ? g_main_context_new() : NULL;
920 if (child_pid)
921 *child_pid = pid;
923 for (i = 0; i < 3; i++)
925 SpawnChannelData *sc = &sw->sc[i];
926 GIOCondition condition;
927 GSourceFunc callback;
929 if (pipe[i] == -1)
930 continue;
932 #ifdef G_OS_WIN32
933 sc->channel = g_io_channel_win32_new_fd(pipe[i]);
934 #else
935 sc->channel = g_io_channel_unix_new(pipe[i]);
936 g_io_channel_set_flags(sc->channel, G_IO_FLAG_NONBLOCK, NULL);
937 #endif
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];
943 if (i == 0)
945 sc->cb.write = stdin_cb;
946 condition = G_IO_OUT | G_IO_FAILURE;
947 callback = (GSourceFunc) spawn_write_cb;
949 else
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;
957 if (i == 1)
959 sc->cb.read = stdout_cb;
960 sc->max_length = stdout_max_length ? stdout_max_length :
961 line_buffered ? 24576 : DEFAULT_IO_LENGTH;
963 else
965 sc->cb.read = stderr_cb;
966 sc->max_length = stderr_max_length ? stderr_max_length :
967 line_buffered ? 8192 : DEFAULT_IO_LENGTH;
970 if (line_buffered)
972 sc->line_buffer = g_string_sized_new(sc->max_length +
973 DEFAULT_IO_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);
1004 return TRUE;
1007 return FALSE;
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 * @param channel the channel to write data to.
1025 * @param condition condition to check for @c G_IO_OUT.
1026 * @param data @c SpawnWriteData to write to @a channel.
1028 * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error,
1029 * @c FALSE otherwise.
1031 * @since 1.25
1033 GEANY_API_SYMBOL
1034 gboolean spawn_write_data(GIOChannel *channel, GIOCondition condition, SpawnWriteData *data)
1036 if ((condition & G_IO_OUT) && data->size)
1038 gsize chars_written = 0;
1040 g_io_channel_write_chars(channel, data->ptr, data->size < DEFAULT_IO_LENGTH ?
1041 data->size : DEFAULT_IO_LENGTH, &chars_written, NULL);
1043 /* "This can be nonzero even if the return value is not G_IO_STATUS_NORMAL." */
1044 if (chars_written)
1046 data->ptr += chars_written;
1047 data->size -= chars_written;
1051 return data->size > 0 && !(condition & G_IO_FAILURE);
1055 static void spawn_append_gstring_cb(GString *string, GIOCondition condition, gpointer data)
1057 if (condition & (G_IO_IN | G_IO_PRI))
1058 g_string_append_len((GString *) data, string->str, string->len);
1062 static void spawn_get_exit_status_cb(G_GNUC_UNUSED GPid pid, gint status, gpointer exit_status)
1064 *(gint *) exit_status = status;
1069 * Executes a child synchronously.
1071 * A command line or an argument vector must be passed. If both are present, the argument
1072 * vector is appended to the command line. An empty command line is not allowed.
1074 * The @a stdin_data is sent to the child with @c spawn_write_data().
1076 * All output from the child, including the nul characters, is stored in @a stdout_data and
1077 * @a stderr_data (if non-NULL). Any existing data in these strings will be erased.
1079 * @param working_directory child's current working directory, or @c NULL.
1080 * @param command_line child program and arguments, or @c NULL.
1081 * @param argv child's argument vector, or @c NULL.
1082 * @param envp child's environment, or @c NULL.
1083 * @param stdin_data data to send to childs's stdin, or @c NULL.
1084 * @param stdout_data GString location to receive the child's stdout, or NULL.
1085 * @param stderr_data GString location to receive the child's stderr, or NULL.
1086 * @param exit_status return location for the child exit code, or NULL.
1087 * @param error return location for error.
1089 * @return @c TRUE on success, @c FALSE on error.
1091 * @since 1.25
1093 GEANY_API_SYMBOL
1094 gboolean spawn_sync(const gchar *working_directory, const gchar *command_line, gchar **argv,
1095 gchar **envp, SpawnWriteData *stdin_data, GString *stdout_data, GString *stderr_data,
1096 gint *exit_status, GError **error)
1098 g_string_truncate(stdout_data, 0);
1099 g_string_truncate(stderr_data, 0);
1101 return spawn_with_callbacks(working_directory, command_line, argv, envp, SPAWN_SYNC |
1102 SPAWN_UNBUFFERED, stdin_data ? (GIOFunc) spawn_write_data : NULL, stdin_data,
1103 stdout_data ? spawn_append_gstring_cb : NULL, stdout_data, 0,
1104 stderr_data ? spawn_append_gstring_cb : NULL, stderr_data, 0,
1105 exit_status ? spawn_get_exit_status_cb : NULL, exit_status, NULL, error);
1109 /* tests, not part of the API */
1110 #ifdef SPAWN_TEST
1111 #include <stdio.h>
1114 static gboolean read_line(const char *prompt, char *buffer, size_t size)
1116 fputs(prompt, stderr);
1117 *buffer = '\0';
1119 if (fgets(buffer, size, stdin))
1121 char *s = strchr(buffer, '\n');
1123 if (s)
1124 *s = '\0';
1127 return *buffer;
1131 static GString *read_string(const char *prompt)
1133 char buffer[0x1000]; /* larger portions for spawn < file */
1134 GString *string = g_string_sized_new(sizeof buffer);
1136 while (read_line(prompt, buffer, sizeof buffer))
1138 if (string->len)
1139 g_string_append_c(string, '\n');
1141 g_string_append(string, buffer);
1144 if (!string->len)
1146 g_string_free(string, TRUE);
1147 string = NULL;
1150 return string;
1154 static void print_cb(GString *string, GIOCondition condition, gpointer data)
1156 if (condition & (G_IO_IN | G_IO_PRI))
1158 gsize i;
1160 printf("%s: ", (const gchar *) data);
1161 /*fputs(string->str, stdout);*/
1162 for (i = 0; i < string->len; i++)
1164 unsigned char c = (unsigned char) string->str[i];
1165 printf(c >= ' ' && c < 0x80 ? "%c" : "\\x%02x", c);
1167 putchar('\n');
1172 static void print_status(gint status)
1174 fputs("finished, ", stderr);
1176 if (SPAWN_WIFEXITED(status))
1177 fprintf(stderr, "exit code %d\n", SPAWN_WEXITSTATUS(status));
1178 else
1179 fputs("abnormal termination\n", stderr);
1183 static void exit_cb(GPid pid, gint status, G_GNUC_UNUSED gpointer data)
1185 fprintf(stderr, "process %u ", (guint) pid);
1186 print_status(status);
1190 static void watch_cb(GPid pid, gint status, gpointer data)
1192 g_spawn_close_pid(pid);
1193 exit_cb(pid, status, NULL);
1194 g_main_loop_quit((GMainLoop *) data);
1198 int main(int argc, char **argv)
1200 char *test_type;
1202 if (argc != 2)
1204 fputs("usage: spawn <test-type>\n", stderr);
1205 return 1;
1208 test_type = argv[1];
1210 if (!strcmp(test_type, "syntax") || !strcmp(test_type, "syntexec"))
1212 char command_line[0x100];
1214 while (read_line("command line: ", command_line, sizeof command_line))
1216 GError *error = NULL;
1218 if (spawn_check_command(command_line, argv[1][4] == 'e', &error))
1219 fputs("valid\n", stderr);
1220 else
1222 fprintf(stderr, "error: %s\n", error->message);
1223 g_error_free(error);
1227 else if (!strcmp(test_type, "execute"))
1229 char command_line[0x100];
1231 while (read_line("command line: ", command_line, sizeof command_line))
1233 char working_directory[0x100];
1234 char args[4][0x100];
1235 char envs[4][0x100];
1236 char *argv[] = { args[0], args[1], args[2], args[3], NULL };
1237 char *envp[] = { envs[0], envs[1], envs[2], envs[3], NULL };
1238 int i;
1239 GPid pid;
1240 GError *error = NULL;
1242 read_line("working directory: ", working_directory, sizeof working_directory);
1244 fputs("up to 4 arguments\n", stderr);
1245 for (i = 0; i < 4 && read_line("argument: ", args[i], sizeof args[i]); i++);
1246 argv[i] = NULL;
1248 fputs("up to 4 variables, or empty line for parent environment\n", stderr);
1249 for (i = 0; i < 4 && read_line("variable: ", envs[i], sizeof envs[i]); i++);
1250 envp[i] = NULL;
1252 if (spawn_async_with_pipes(*working_directory ? working_directory : NULL,
1253 *command_line ? command_line : NULL, argv, i ? envp : NULL, &pid, NULL,
1254 NULL, NULL, &error))
1256 GMainLoop *loop = g_main_loop_new(NULL, TRUE);
1258 g_child_watch_add(pid, watch_cb, loop);
1259 g_main_loop_run(loop);
1260 g_main_loop_unref(loop);
1262 else
1264 fprintf(stderr, "error: %s\n", error->message);
1265 g_error_free(error);
1269 else if (!strcmp(test_type, "redirect") || !strcmp(test_type, "redinput"))
1271 char command_line[0x100];
1272 gboolean output = test_type[4] == 'r';
1274 while (read_line("command line: ", command_line, sizeof command_line))
1276 GString *stdin_text = read_string("text to send: ");
1277 SpawnWriteData stdin_data;
1278 GError *error = NULL;
1280 if (stdin_text)
1282 stdin_data.ptr = stdin_text->str;
1283 stdin_data.size = stdin_text->len;
1286 if (!spawn_with_callbacks(NULL, command_line, NULL, NULL, SPAWN_SYNC,
1287 stdin_text ? (GIOFunc) spawn_write_data : NULL, &stdin_data,
1288 output ? print_cb : NULL, "stdout", 0, output ? print_cb : NULL,
1289 "stderr", 0, exit_cb, NULL, NULL, &error))
1291 fprintf(stderr, "error: %s\n", error->message);
1292 g_error_free(error);
1295 if (stdin_text)
1296 g_string_free(stdin_text, TRUE);
1299 else if (!strcmp(test_type, "capture"))
1301 char command_line[0x100];
1303 while (read_line("command line: ", command_line, sizeof command_line))
1305 GString *stdin_text = read_string("text to send: ");
1306 SpawnWriteData stdin_data = { NULL, 0 };
1307 GString *stdout_data = g_string_sized_new(0x10000); /* may grow */
1308 GString *stderr_data = g_string_sized_new(0x1000); /* may grow */
1309 gint exit_status;
1310 GError *error = NULL;
1312 if (stdin_text)
1314 stdin_data.ptr = stdin_text->str;
1315 stdin_data.size = stdin_text->len;
1318 if (spawn_sync(NULL, command_line, NULL, NULL, &stdin_data, stdout_data,
1319 stderr_data, &exit_status, &error))
1321 printf("stdout: %s\n", stdout_data->str);
1322 printf("stderr: %s\n", stderr_data->str);
1323 print_status(exit_status);
1325 else
1327 fprintf(stderr, "error: %s\n", error->message);
1328 g_error_free(error);
1331 if (stdin_text)
1332 g_string_free(stdin_text, TRUE);
1334 g_string_free(stdout_data, TRUE);
1335 g_string_free(stderr_data, TRUE);
1338 else
1340 fprintf(stderr, "spawn: unknown test type '%s'", argv[1]);
1341 return 1;
1344 return 0;
1346 #endif /* SPAWN_TEST */