Remove obsolete GTK compatibility code
[geany-mirror.git] / src / spawn.c
blob169e14dc08cb94defb254530347153c3144c035d
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 "win32defines.h" /* should always come before any system headers */
52 #include <errno.h>
53 #include <string.h>
55 #include "spawn.h"
57 #ifdef G_OS_WIN32
58 # include <ctype.h> /* isspace() */
59 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
60 # include <io.h> /* _open_osfhandle, _close */
61 # include <windows.h>
62 #else /* G_OS_WIN32 */
63 # include <signal.h>
64 #endif /* G_OS_WIN32 */
66 #ifdef SPAWN_TEST
67 # define _
68 # define GEANY_API_SYMBOL
69 #else
70 # include "support.h"
71 #endif
73 #ifdef G_OS_WIN32
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
77 #else
78 # define DEFAULT_IO_LENGTH 4096
79 #endif
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)
96 gchar *program;
98 #ifdef G_OS_WIN32
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))
105 command_line++;
107 if (!*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)"));
112 return FALSE;
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 == '"')
120 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);
128 return FALSE;
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"));
135 return FALSE;
138 else
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"));
149 return FALSE;
153 program = g_strndup(command_line, s - command_line);
154 arguments = s + (*s == '"');
156 for (s = arguments; *s; s++)
158 if (*s == '"')
160 const char *slash;
162 for (slash = s; slash > arguments && slash[-1] == '\\'; slash--);
163 if ((s - slash) % 2 == 0)
164 open_quote ^= TRUE;
168 if (open_quote)
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);
174 g_free(program);
175 return FALSE;
177 #else /* G_OS_WIN32 */
178 int argc;
179 char **argv;
181 if (!g_shell_parse_argv(command_line, &argc, &argv, error))
182 return FALSE;
184 /* empty string results in parse error, so argv[0] is not NULL */
185 program = g_strdup(argv[0]);
186 g_strfreev(argv);
187 #endif /* G_OS_WIN32 */
189 return program;
194 * Checks whether a command line is valid.
196 * Checks if @a command_line is syntactically valid.
198 * All OS:
199 * - any leading spaces, tabs and new lines are skipped
200 * - an empty command is invalid
201 * Unix:
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
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 * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error,
1025 * @c FALSE otherwise.
1027 * @since 1.25
1029 GEANY_API_SYMBOL
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." */
1040 if (chars_written)
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.
1087 * @since 1.25
1089 GEANY_API_SYMBOL
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 */
1106 #ifdef SPAWN_TEST
1107 #include <stdio.h>
1110 static gboolean read_line(const char *prompt, char *buffer, size_t size)
1112 fputs(prompt, stderr);
1113 *buffer = '\0';
1115 if (fgets(buffer, size, stdin))
1117 char *s = strchr(buffer, '\n');
1119 if (s)
1120 *s = '\0';
1123 return *buffer;
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))
1134 if (string->len)
1135 g_string_append_c(string, '\n');
1137 g_string_append(string, buffer);
1140 if (!string->len)
1142 g_string_free(string, TRUE);
1143 string = NULL;
1146 return string;
1150 static void print_cb(GString *string, GIOCondition condition, gpointer data)
1152 if (condition & (G_IO_IN | G_IO_PRI))
1154 gsize i;
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);
1163 putchar('\n');
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));
1174 else
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)
1196 char *test_type;
1198 if (argc != 2)
1200 fputs("usage: spawn <test-type>\n", stderr);
1201 return 1;
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);
1216 else
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 };
1234 int i;
1235 GPid pid;
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++);
1242 argv[i] = NULL;
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++);
1246 envp[i] = NULL;
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);
1258 else
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;
1276 if (stdin_text)
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);
1291 if (stdin_text)
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 */
1305 gint exit_status;
1306 GError *error = NULL;
1308 if (stdin_text)
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);
1321 else
1323 fprintf(stderr, "error: %s\n", error->message);
1324 g_error_free(error);
1327 if (stdin_text)
1328 g_string_free(stdin_text, TRUE);
1330 g_string_free(stdout_data, TRUE);
1331 g_string_free(stderr_data, TRUE);
1334 else
1336 fprintf(stderr, "spawn: unknown test type '%s'", argv[1]);
1337 return 1;
1340 return 0;
1342 #endif /* SPAWN_TEST */