2 * spawn.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2013 Dimitar Toshkov Zhekov <dimitar(dot)zhekov(at)gmail(dot)com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 /* An ongoing effort to improve the tool spawning situation under Windows.
23 * - There is no g_shell_parse_argv() for windows. It's not hard to write one,
24 * but the command line recreated by mscvrt may be wrong.
25 * - GLib converts the argument vector to UNICODE. For non-UTF8 arguments,
26 * the result is often "Invalid string in argument vector at %d: %s: Invalid
27 * byte sequence in conversion input" (YMMV). Our tools (make, grep, gcc, ...)
28 * are "ANSI", so converting to UNICODE and then back only causes problems.
29 * - For various reasons, GLib uses an intermediate program to start children
30 * (see gspawn-win32.c), the result being that the grandchildren output (such
31 * as make -> gcc) is not captured.
32 * - With non-blocking pipes, the g_io_add_watch() callbacks are never invoked,
33 * while with blocking pipes, g_io_channel_read_line() blocks.
34 * - Some other problems are explained in separate comments below.
36 * Even under Unix, using g_io_channel_read_line() is not a good idea, since it may
37 * buffer lines of unlimited length.
39 * This module does not depend on Geany when compiled for testing (-DSPAWN_TEST).
43 * Portable and convenient process spawning and communication.
56 # include <ctype.h> /* isspace() */
57 # include <fcntl.h> /* _O_RDONLY, _O_WRONLY */
58 # include <io.h> /* _open_osfhandle, _close */
60 #else /* G_OS_WIN32 */
62 #endif /* G_OS_WIN32 */
66 # define GEANY_API_SYMBOL
71 #if ! GLIB_CHECK_VERSION(2, 31, 20) && ! defined(G_SPAWN_ERROR_TOO_BIG)
72 # define G_SPAWN_ERROR_TOO_BIG G_SPAWN_ERROR_2BIG
76 /* Each 4KB under Windows seem to come in 2 portions, so 2K + 2K is more
77 balanced than 4095 + 1. May be different on the latest Windows/glib? */
78 # define DEFAULT_IO_LENGTH 2048
80 # define DEFAULT_IO_LENGTH 4096
82 /* helper function that cuts glib citing of the original text on bad quoting: it may be long,
83 and only the caller knows whether it's UTF-8. Thought we lose the ' or " failed info. */
84 static gboolean
spawn_parse_argv(const gchar
*command_line
, gint
*argcp
, gchar
***argvp
,
87 GError
*gerror
= NULL
;
89 if (g_shell_parse_argv(command_line
, argcp
, argvp
, &gerror
))
92 g_set_error_literal(error
, gerror
->domain
, gerror
->code
,
93 gerror
->code
== G_SHELL_ERROR_BAD_QUOTING
?
94 _("Text ended before matching quote was found") : gerror
->message
);
100 #define G_IO_FAILURE (G_IO_ERR | G_IO_HUP | G_IO_NVAL) /* always used together */
104 * Checks whether a command line is syntactically valid and extracts the program name from it.
106 * See @c spawn_check_command() for details.
108 * @param command_line the command line to check and get the program name from.
109 * @param error return location for error.
111 * @return allocated string with the program name on success, @c NULL on error.
113 static gchar
*spawn_get_program_name(const gchar
*command_line
, GError
**error
)
118 gboolean open_quote
= FALSE
;
119 const gchar
*s
, *arguments
;
121 g_return_val_if_fail(command_line
!= NULL
, FALSE
);
123 while (*command_line
&& strchr(" \t\r\n", *command_line
))
128 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_EMPTY_STRING
,
129 /* TL note: from glib */
130 _("Text was empty (or contained only whitespace)"));
134 /* To prevent Windows from doing something weird, we want to be 100% sure that the
135 character after the program name is a delimiter, so we allow space and tab only. */
137 if (*command_line
== '"')
140 /* Windows allows "foo.exe, but we may have extra arguments */
141 if ((s
= strchr(command_line
, '"')) == NULL
)
143 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
144 _("Text ended before matching quote was found"));
148 if (!strchr(" \t", s
[1])) /* strchr() catches s[1] == '\0' */
150 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
151 _("A quoted Windows program name must be entirely inside the quotes"));
157 const gchar
*quote
= strchr(command_line
, '"');
159 /* strchr() catches *s == '\0', and the for body is empty */
160 for (s
= command_line
; !strchr(" \t", *s
); s
++);
162 if (quote
&& quote
< s
)
164 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
165 _("A quoted Windows program name must be entirely inside the quotes"));
170 program
= g_strndup(command_line
, s
- command_line
);
171 arguments
= s
+ (*s
== '"');
173 for (s
= arguments
; *s
; s
++)
179 for (slash
= s
; slash
> arguments
&& slash
[-1] == '\\'; slash
--);
180 if ((s
- slash
) % 2 == 0)
187 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_BAD_QUOTING
,
188 _("Text ended before matching quote was found"));
192 #else /* G_OS_WIN32 */
196 if (!spawn_parse_argv(command_line
, &argc
, &argv
, error
))
199 /* empty string results in parse error, so argv[0] is not NULL */
200 program
= g_strdup(argv
[0]);
202 #endif /* G_OS_WIN32 */
209 * Checks whether a command line is valid.
211 * Checks if @a command_line is syntactically valid.
214 * - any leading spaces, tabs and new lines are skipped
215 * - an empty command is invalid
218 * - the standard shell quoting and escaping rules are used, see @c g_shell_parse_argv()
219 * - as a consequence, an unqouted # at the start of an argument comments to the end of line
222 * - leading carriage returns are skipped too
223 * - a quoted program name must be entirely inside the quotes. No "C:\Foo\Bar".pdf or
224 * "C:\Foo\Bar".bat, which would be executed by Windows as `C:\Foo\Bar.exe`
225 * - an unquoted program name may not contain spaces. `Foo Bar Qux` will not be considered
226 * `"Foo Bar.exe" Qux` or `"Foo Bar Qux.exe"`, depending on what executables exist, as
227 * Windows normally does.
228 * - the program name must be separated from the arguments by at least one space or tab
229 * - the standard Windows quoting and escaping rules are used: double quote is escaped with
230 * backslash, and any literal backslashes before a double quote must be duplicated.
232 * If @a execute is TRUE, also checks, using @c g_find_program_in_path(), if the program
233 * specified in @a command_line exists and is executable.
235 * @param command_line the command line to check.
236 * @param execute whether to check if the command line is really executable.
237 * @param error return location for error.
239 * @return @c TRUE on success, @c FALSE on error.
244 gboolean
spawn_check_command(const gchar
*command_line
, gboolean execute
, GError
**error
)
246 gchar
*program
= spawn_get_program_name(command_line
, error
);
253 gchar
*executable
= g_find_program_in_path(program
);
257 g_set_error_literal(error
, G_SHELL_ERROR
, G_SHELL_ERROR_FAILED
,
258 _("Program not found"));
274 * @param pid id of the process to kill.
275 * @param error return location for error.
277 * On Unix, sends a SIGTERM to the process.
279 * On Windows, terminates the process with exit code 255 (used sometimes as "generic"
280 * error code, or for programs terminated with Ctrl+C / Ctrl+Break).
282 * @return @c TRUE on success, @c FALSE on error.
287 gboolean
spawn_kill_process(GPid pid
, GError
**error
)
290 if (!TerminateProcess(pid
, 255))
292 gchar
*message
= g_win32_error_message(GetLastError());
294 g_set_error_literal(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, message
);
299 if (kill(pid
, SIGTERM
))
301 g_set_error_literal(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, g_strerror(errno
));
310 static gchar
*spawn_create_process_with_pipes(char *command_line
, const char *working_directory
,
311 void *environment
, HANDLE
*hprocess
, int *stdin_fd
, int *stdout_fd
, int *stderr_fd
)
313 enum { WRITE_STDIN
, READ_STDOUT
, READ_STDERR
, READ_STDIN
, WRITE_STDOUT
, WRITE_STDERR
};
315 PROCESS_INFORMATION process
;
316 HANDLE hpipe
[6] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
317 int *fd
[3] = { stdin_fd
, stdout_fd
, stderr_fd
};
318 const char *failed
; /* failed WIN32/CRTL function, if any */
319 gchar
*message
= NULL
; /* glib WIN32/CTRL error message */
320 gchar
*failure
= NULL
; /* full error text */
324 ZeroMemory(&startup
, sizeof startup
);
325 startup
.cb
= sizeof startup
;
326 pipe_io
= stdin_fd
|| stdout_fd
|| stderr_fd
;
330 startup
.dwFlags
|= STARTF_USESTDHANDLES
;
332 /* not all programs accept mixed NULL and non-NULL hStd*, so we create all */
333 for (i
= 0; i
< 3; i
++)
335 static int pindex
[3][2] = { { READ_STDIN
, WRITE_STDIN
},
336 { READ_STDOUT
, WRITE_STDOUT
}, { READ_STDERR
, WRITE_STDERR
} };
338 if (!CreatePipe(&hpipe
[pindex
[i
][0]], &hpipe
[pindex
[i
][1]], NULL
, 0))
340 hpipe
[pindex
[i
][0]] = hpipe
[pindex
[i
][1]] = NULL
;
341 failed
= "create pipe";
347 static int mode
[3] = { _O_WRONLY
, _O_RDONLY
, _O_RDONLY
};
349 if ((*fd
[i
] = _open_osfhandle((intptr_t) hpipe
[i
], mode
[i
])) == -1)
351 failed
= "convert pipe handle to file descriptor";
352 message
= g_strdup(g_strerror(errno
));
356 else if (!CloseHandle(hpipe
[i
]))
358 failed
= "close pipe";
362 if (!SetHandleInformation(hpipe
[i
+ 3], HANDLE_FLAG_INHERIT
,
363 HANDLE_FLAG_INHERIT
))
365 failed
= "set pipe handle to inheritable";
371 startup
.hStdInput
= hpipe
[READ_STDIN
];
372 startup
.hStdOutput
= hpipe
[WRITE_STDOUT
];
373 startup
.hStdError
= hpipe
[WRITE_STDERR
];
375 if (!CreateProcess(NULL
, command_line
, NULL
, NULL
, TRUE
, pipe_io
? CREATE_NO_WINDOW
: 0,
376 environment
, working_directory
, &startup
, &process
))
378 failed
= ""; /* report the message only */
379 /* further errors will not be reported */
384 CloseHandle(process
.hThread
); /* we don't need this */
387 *hprocess
= process
.hProcess
;
389 CloseHandle(process
.hProcess
);
399 message
= g_win32_error_message(GetLastError());
400 len
= strlen(message
);
402 /* unlike g_strerror(), the g_win32_error messages may include a final '.' */
403 if (len
> 0 && message
[len
- 1] == '.')
404 message
[len
- 1] = '\0';
411 failure
= g_strdup_printf("Failed to %s (%s)", failed
, message
);
418 for (i
= 0; i
< 3; i
++)
422 if (fd
[i
] && *fd
[i
] != -1)
425 CloseHandle(hpipe
[i
]);
429 CloseHandle(hpipe
[i
+ 3]);
437 static void spawn_append_argument(GString
*command
, const char *text
)
442 g_string_append_c(command
, ' ');
444 for (s
= text
; *s
; s
++)
446 /* g_ascii_isspace() fails for '\v', and locale spaces (if any) will do no harm */
447 if (*s
== '"' || isspace(*s
))
452 g_string_append(command
, text
);
455 g_string_append_c(command
, '"');
457 for (s
= text
; *s
; s
++)
461 for (slash
= s
; *slash
== '\\'; slash
++);
465 g_string_append_len(command
, s
, slash
- s
);
467 if (!*slash
|| *slash
== '"')
469 g_string_append_len(command
, s
, slash
- s
);
479 g_string_append_c(command
, '\\');
481 g_string_append_c(command
, *s
);
484 g_string_append_c(command
, '"');
487 #endif /* G_OS_WIN32 */
491 * Executes a child program asynchronously and setups pipes.
493 * This is the low-level spawning function. Please use @c spawn_with_callbacks() unless
494 * you need to setup specific event source(s).
496 * A command line or an argument vector must be passed. If both are present, the argument
497 * vector is appended to the command line. An empty command line is not allowed.
499 * Under Windows, if the child is a console application, and at least one file descriptor is
500 * specified, the new child console (if any) will be hidden.
502 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
504 * @param working_directory child's current working directory, or @c NULL.
505 * @param command_line child program and arguments, or @c NULL.
506 * @param argv child's argument vector, or @c NULL.
507 * @param envp child's environment, or @c NULL.
508 * @param child_pid return location for child process ID, or @c NULL.
509 * @param stdin_fd return location for file descriptor to write to child's stdin, or @c NULL.
510 * @param stdout_fd return location for file descriptor to read child's stdout, or @c NULL.
511 * @param stderr_fd return location for file descriptor to read child's stderr, or @c NULL.
512 * @param error return location for error.
514 * @return @c TRUE on success, @c FALSE on error.
516 static gboolean
spawn_async_with_pipes(const gchar
*working_directory
, const gchar
*command_line
,
517 gchar
**argv
, gchar
**envp
, GPid
*child_pid
, gint
*stdin_fd
, gint
*stdout_fd
,
518 gint
*stderr_fd
, GError
**error
)
520 g_return_val_if_fail(command_line
!= NULL
|| argv
!= NULL
, FALSE
);
529 gchar
*program
= spawn_get_program_name(command_line
, error
);
530 const gchar
*arguments
;
535 command
= g_string_new(NULL
);
536 arguments
= strstr(command_line
, program
) + strlen(program
);
538 if (*arguments
== '"')
540 g_string_append(command
, program
);
545 /* quote the first token, to avoid Windows attemps to run two or more
546 unquoted tokens as a program until an existing file name is found */
547 g_string_printf(command
, "\"%s\"", program
);
550 g_string_append(command
, arguments
);
554 command
= g_string_new(NULL
);
556 environment
= g_array_new(TRUE
, FALSE
, sizeof(char));
558 while (argv
&& *argv
)
559 spawn_append_argument(command
, *argv
++);
562 g_message("full spawn command line: %s\n", command
->str
);
565 while (envp
&& *envp
)
567 g_array_append_vals(environment
, *envp
, strlen(*envp
) + 1);
571 failure
= spawn_create_process_with_pipes(command
->str
, working_directory
,
572 envp
? environment
->data
: NULL
, child_pid
, stdin_fd
, stdout_fd
, stderr_fd
);
574 g_string_free(command
, TRUE
);
575 g_array_free(environment
, TRUE
);
579 g_set_error_literal(error
, G_SPAWN_ERROR
, G_SPAWN_ERROR_FAILED
, failure
);
585 #else /* G_OS_WIN32 */
589 GError
*gerror
= NULL
;
596 if (!spawn_parse_argv(command_line
, &cl_argc
, &cl_argv
, error
))
600 for (argc
= 0; argv
[argc
]; argc
++);
602 full_argv
= g_renew(gchar
*, cl_argv
, cl_argc
+ argc
+ 1);
603 memcpy(full_argv
+ cl_argc
, argv
, argc
* sizeof(gchar
*));
604 full_argv
[cl_argc
+ argc
] = NULL
;
609 spawned
= g_spawn_async_with_pipes(working_directory
, full_argv
, envp
,
610 G_SPAWN_SEARCH_PATH
| (child_pid
? G_SPAWN_DO_NOT_REAP_CHILD
: 0), NULL
, NULL
,
611 child_pid
, stdin_fd
, stdout_fd
, stderr_fd
, &gerror
);
616 const gchar
*message
= gerror
->message
;
618 /* try to cut glib citing of the program name or working directory: they may be long,
619 and only the caller knows whether they're UTF-8. We lose the exact chdir error. */
620 switch (gerror
->code
)
623 case G_SPAWN_ERROR_ACCES
: en
= EACCES
; break;
626 case G_SPAWN_ERROR_PERM
: en
= EPERM
; break;
629 case G_SPAWN_ERROR_TOO_BIG
: en
= E2BIG
; break;
632 case G_SPAWN_ERROR_NOEXEC
: en
= ENOEXEC
; break;
635 case G_SPAWN_ERROR_NAMETOOLONG
: en
= ENAMETOOLONG
; break;
638 case G_SPAWN_ERROR_NOENT
: en
= ENOENT
; break;
641 case G_SPAWN_ERROR_NOMEM
: en
= ENOMEM
; break;
644 case G_SPAWN_ERROR_NOTDIR
: en
= ENOTDIR
; break;
647 case G_SPAWN_ERROR_LOOP
: en
= ELOOP
; break;
650 case G_SPAWN_ERROR_TXTBUSY
: en
= ETXTBUSY
; break;
653 case G_SPAWN_ERROR_IO
: en
= EIO
; break;
656 case G_SPAWN_ERROR_NFILE
: en
= ENFILE
; break;
659 case G_SPAWN_ERROR_MFILE
: en
= EMFILE
; break;
662 case G_SPAWN_ERROR_INVAL
: en
= EINVAL
; break;
665 case G_SPAWN_ERROR_ISDIR
: en
= EISDIR
; break;
668 case G_SPAWN_ERROR_LIBBAD
: en
= ELIBBAD
; break;
670 case G_SPAWN_ERROR_CHDIR
:
672 message
= _("Failed to change to the working directory");
675 case G_SPAWN_ERROR_FAILED
:
677 message
= _("Unknown error executing child process");
683 message
= g_strerror(en
);
685 g_set_error_literal(error
, gerror
->domain
, gerror
->code
, message
);
686 g_error_free(gerror
);
689 if (full_argv
!= argv
)
691 full_argv
[cl_argc
] = NULL
;
692 g_strfreev(full_argv
);
696 #endif /* G_OS_WIN32 */
701 * Executes a child asynchronously.
703 * A command line or an argument vector must be passed. If both are present, the argument
704 * vector is appended to the command line. An empty command line is not allowed.
706 * If a @a child_pid is passed, it's your responsibility to invoke @c g_spawn_close_pid().
708 * @param working_directory child's current working directory, or @c NULL.
709 * @param command_line child program and arguments, or @c NULL.
710 * @param argv child's argument vector, or @c NULL.
711 * @param envp child's environment, or @c NULL.
712 * @param child_pid return location for child process ID, or @c NULL.
713 * @param error return location for error.
715 * @return @c TRUE on success, @c FALSE on error.
720 gboolean
spawn_async(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
721 gchar
**envp
, GPid
*child_pid
, GError
**error
)
723 return spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, child_pid
,
724 NULL
, NULL
, NULL
, error
);
729 * Spawn with callbacks - general event sequence:
731 * - Launch the child.
732 * - Setup any I/O callbacks and a child watch callback.
733 * - On sync execution, run a main loop.
734 * - Wait for the child to terminate.
735 * - Check for active I/O sources. If any, add a timeout source to watch them, they should
736 * become inactive real soon now that the child is dead. Otherwise, finalize immediately.
737 * - In the timeout source: check for active I/O sources and finalize if none.
740 typedef struct _SpawnChannelData
742 GIOChannel
*channel
; /* NULL if not created / already destroyed */
749 /* stdout/stderr only */
750 GString
*buffer
; /* NULL if recursive */
751 GString
*line_buffer
; /* NULL if char buffered */
756 static void spawn_destroy_cb(gpointer data
)
758 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
760 g_io_channel_shutdown(sc
->channel
, FALSE
, NULL
);
764 g_string_free(sc
->buffer
, TRUE
);
767 g_string_free(sc
->line_buffer
, TRUE
);
771 static gboolean
spawn_write_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
773 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
775 if (!sc
->cb
.write(channel
, condition
, sc
->cb_data
))
778 return !(condition
& G_IO_FAILURE
);
782 static gboolean
spawn_read_cb(GIOChannel
*channel
, GIOCondition condition
, gpointer data
)
784 SpawnChannelData
*sc
= (SpawnChannelData
*) data
;
785 GString
*line_buffer
= sc
->line_buffer
;
786 GString
*buffer
= sc
->buffer
? sc
->buffer
: g_string_sized_new(sc
->max_length
);
787 GIOCondition input_cond
= condition
& (G_IO_IN
| G_IO_PRI
);
788 GIOCondition failure_cond
= condition
& G_IO_FAILURE
;
790 * - Normally, read only once. With IO watches, our data processing must be immediate,
791 * which may give the child time to emit more data, and a read loop may combine it into
792 * large stdout and stderr portions. Under Windows, looping blocks.
793 * - On failure, read in a loop. It won't block now, there will be no more data, and the
794 * IO watch is not guaranteed to be called again (under Windows this is the last call).
803 gsize n
= line_buffer
->len
;
805 while ((status
= g_io_channel_read_chars(channel
, line_buffer
->str
+ n
,
806 DEFAULT_IO_LENGTH
, &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
808 g_string_set_size(line_buffer
, n
+ chars_read
);
810 while (n
< line_buffer
->len
)
814 if (n
== sc
->max_length
)
816 else if (strchr("\n", line_buffer
->str
[n
])) /* '\n' or '\0' */
818 else if (n
< line_buffer
->len
- 1 && line_buffer
->str
[n
] == '\r')
819 line_len
= n
+ 1 + (line_buffer
->str
[n
+ 1] == '\n');
825 g_string_append_len(buffer
, line_buffer
->str
, line_len
);
826 g_string_erase(line_buffer
, 0, line_len
);
827 /* input only, failures are reported separately below */
828 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
829 g_string_truncate(buffer
, 0);
840 while ((status
= g_io_channel_read_chars(channel
, buffer
->str
, sc
->max_length
,
841 &chars_read
, NULL
)) == G_IO_STATUS_NORMAL
)
843 g_string_set_size(buffer
, chars_read
);
844 /* input only, failures are reported separately below */
845 sc
->cb
.read(buffer
, input_cond
, sc
->cb_data
);
852 /* Under OSX, after child death, the read watches receive input conditions instead
853 of error conditions, so we convert the termination statuses into conditions.
854 Should not hurt the other OS. */
855 if (status
== G_IO_STATUS_ERROR
)
856 failure_cond
|= G_IO_ERR
;
857 else if (status
== G_IO_STATUS_EOF
)
858 failure_cond
|= G_IO_HUP
;
861 if (failure_cond
) /* we must signal the callback */
863 if (line_buffer
&& line_buffer
->len
) /* flush the line buffer */
865 g_string_append_len(buffer
, line_buffer
->str
, line_buffer
->len
);
866 /* all data may be from a previous call */
868 input_cond
= G_IO_IN
;
873 g_string_truncate(buffer
, 0);
876 sc
->cb
.read(buffer
, input_cond
| failure_cond
, sc
->cb_data
);
879 if (buffer
!= sc
->buffer
)
880 g_string_free(buffer
, TRUE
);
882 return !failure_cond
;
886 typedef struct _SpawnWatcherData
888 SpawnChannelData sc
[3]; /* stdin, stdout, stderr */
889 GChildWatchFunc exit_cb
;
893 GMainContext
*main_context
; /* NULL if async execution */
894 GMainLoop
*main_loop
; /* NULL if async execution */
898 static void spawn_finalize(SpawnWatcherData
*sw
)
901 sw
->exit_cb(sw
->pid
, sw
->exit_status
, sw
->exit_data
);
905 g_main_loop_quit(sw
->main_loop
);
906 g_main_loop_unref(sw
->main_loop
);
909 g_spawn_close_pid(sw
->pid
);
910 g_slice_free(SpawnWatcherData
, sw
);
914 static gboolean
spawn_timeout_cb(gpointer data
)
916 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
919 for (i
= 0; i
< 3; i
++)
920 if (sw
->sc
[i
].channel
)
928 static void spawn_watch_cb(GPid pid
, gint status
, gpointer data
)
930 SpawnWatcherData
*sw
= (SpawnWatcherData
*) data
;
934 sw
->exit_status
= status
;
936 for (i
= 0; i
< 3; i
++)
938 if (sw
->sc
[i
].channel
)
940 GSource
*source
= g_timeout_source_new(50);
942 g_source_set_callback(source
, spawn_timeout_cb
, data
, NULL
);
943 g_source_attach(source
, sw
->main_context
);
944 g_source_unref(source
);
954 * Executes a child program and setups callbacks.
956 * A command line or an argument vector must be passed. If both are present, the argument
957 * vector is appended to the command line. An empty command line is not allowed.
959 * The synchronous execution may not be combined with recursive callbacks.
961 * In line buffered mode, the child input is broken on `\n`, `\r\n`, `\r`, `\0` and max length.
963 * All I/O callbacks are guaranteed to be invoked at least once with @c G_IO_ERR, @c G_IO_HUP
964 * or @c G_IO_NVAL set (except for a @a stdin_cb which returns @c FALSE before that). For the
965 * non-recursive callbacks, this is guaranteed to be the last call, and may be used to free any
966 * resources associated with the callback.
968 * The @a stdin_cb may write to @c channel only once per invocation, only if @c G_IO_OUT is
969 * set, and only a non-zero number of characters.
971 * @c stdout_cb and @c stderr_cb may modify the received strings in any way, but must not
974 * The default max lengths are 24K for line buffered stdout, 8K for line buffered stderr,
975 * 4K for unbuffered input under Unix, and 2K for unbuffered input under Windows.
977 * @c exit_cb is always invoked last, after all I/O callbacks.
979 * The @a child_pid will be closed automatically, after @a exit_cb is invoked.
981 * @param working_directory child's current working directory, or @c NULL.
982 * @param command_line child program and arguments, or @c NULL.
983 * @param argv child's argument vector, or @c NULL.
984 * @param envp child's environment, or @c NULL.
985 * @param spawn_flags flags from SpawnFlags.
986 * @param stdin_cb callback to send data to childs's stdin, or @c NULL.
987 * @param stdin_data data to pass to @a stdin_cb.
988 * @param stdout_cb callback to receive child's stdout, or @c NULL.
989 * @param stdout_data data to pass to @a stdout_cb.
990 * @param stdout_max_length maximum data length to pass to stdout_cb, @c 0 = default.
991 * @param stderr_cb callback to receive child's stderr, or @c NULL.
992 * @param stderr_data data to pass to @a stderr_cb.
993 * @param stderr_max_length maximum data length to pass to stderr_cb, @c 0 = default.
994 * @param exit_cb callback to invoke when the child exits, or @c NULL.
995 * @param exit_data data to pass to @a exit_cb.
996 * @param child_pid return location for child process ID, or @c NULL.
997 * @param error return location for error.
999 * @return @c TRUE on success, @c FALSE on error.
1004 gboolean
spawn_with_callbacks(const gchar
*working_directory
, const gchar
*command_line
,
1005 gchar
**argv
, gchar
**envp
, SpawnFlags spawn_flags
, GIOFunc stdin_cb
, gpointer stdin_data
,
1006 SpawnReadFunc stdout_cb
, gpointer stdout_data
, gsize stdout_max_length
,
1007 SpawnReadFunc stderr_cb
, gpointer stderr_data
, gsize stderr_max_length
,
1008 GChildWatchFunc exit_cb
, gpointer exit_data
, GPid
*child_pid
, GError
**error
)
1011 int pipe
[3] = { -1, -1, -1 };
1013 g_return_val_if_fail(!(spawn_flags
& SPAWN_RECURSIVE
) || !(spawn_flags
& SPAWN_SYNC
),
1016 if (spawn_async_with_pipes(working_directory
, command_line
, argv
, envp
, &pid
,
1017 stdin_cb
? &pipe
[0] : NULL
, stdout_cb
? &pipe
[1] : NULL
,
1018 stderr_cb
? &pipe
[2] : NULL
, error
))
1020 SpawnWatcherData
*sw
= g_slice_new0(SpawnWatcherData
);
1021 gpointer cb_data
[3] = { stdin_data
, stdout_data
, stderr_data
};
1025 sw
->main_context
= spawn_flags
& SPAWN_SYNC
? g_main_context_new() : NULL
;
1030 for (i
= 0; i
< 3; i
++)
1032 SpawnChannelData
*sc
= &sw
->sc
[i
];
1033 GIOCondition condition
;
1034 GSourceFunc callback
;
1040 sc
->channel
= g_io_channel_win32_new_fd(pipe
[i
]);
1042 sc
->channel
= g_io_channel_unix_new(pipe
[i
]);
1043 g_io_channel_set_flags(sc
->channel
, G_IO_FLAG_NONBLOCK
, NULL
);
1045 g_io_channel_set_encoding(sc
->channel
, NULL
, NULL
);
1046 /* we have our own buffers, and GIO buffering blocks under Windows */
1047 g_io_channel_set_buffered(sc
->channel
, FALSE
);
1048 sc
->cb_data
= cb_data
[i
];
1052 sc
->cb
.write
= stdin_cb
;
1053 condition
= G_IO_OUT
| G_IO_FAILURE
;
1054 callback
= (GSourceFunc
) spawn_write_cb
;
1058 gboolean line_buffered
= !(spawn_flags
&
1059 ((SPAWN_STDOUT_UNBUFFERED
>> 1) << i
));
1061 condition
= G_IO_IN
| G_IO_PRI
| G_IO_FAILURE
;
1062 callback
= (GSourceFunc
) spawn_read_cb
;
1066 sc
->cb
.read
= stdout_cb
;
1067 sc
->max_length
= stdout_max_length
? stdout_max_length
:
1068 line_buffered
? 24576 : DEFAULT_IO_LENGTH
;
1072 sc
->cb
.read
= stderr_cb
;
1073 sc
->max_length
= stderr_max_length
? stderr_max_length
:
1074 line_buffered
? 8192 : DEFAULT_IO_LENGTH
;
1079 sc
->line_buffer
= g_string_sized_new(sc
->max_length
+
1084 source
= g_io_create_watch(sc
->channel
, condition
);
1085 g_io_channel_unref(sc
->channel
);
1087 if (spawn_flags
& (SPAWN_STDIN_RECURSIVE
<< i
))
1088 g_source_set_can_recurse(source
, TRUE
);
1089 else if (i
) /* to avoid new string on each call */
1090 sc
->buffer
= g_string_sized_new(sc
->max_length
);
1092 g_source_set_callback(source
, callback
, sc
, spawn_destroy_cb
);
1093 g_source_attach(source
, sw
->main_context
);
1094 g_source_unref(source
);
1097 sw
->exit_cb
= exit_cb
;
1098 sw
->exit_data
= exit_data
;
1099 source
= g_child_watch_source_new(pid
);
1100 g_source_set_callback(source
, (GSourceFunc
) spawn_watch_cb
, sw
, NULL
);
1101 g_source_attach(source
, sw
->main_context
);
1102 g_source_unref(source
);
1104 if (spawn_flags
& SPAWN_SYNC
)
1106 sw
->main_loop
= g_main_loop_new(sw
->main_context
, FALSE
);
1107 g_main_context_unref(sw
->main_context
);
1108 g_main_loop_run(sw
->main_loop
);
1119 * Writes (a portion of) the data pointed by @a data->ptr to the @a channel.
1121 * If @c G_IO_OUT in @a condition is set, and the @a data->size is > 0, attempts to write
1122 * @a data->ptr (or a portion of it, depending on the size) to the @a channel. On success,
1123 * increases ptr and decreases size with the number of characters written.
1125 * This function may converted to @c GIOFunc and passed to @c spawn_with_callbacks() as
1126 * @c stdin_cb, together with a @c SpawnWriteData for @c stdin_data. As with any other
1127 * callback data, make sure that @c stdin_data exists while the child is being executed.
1128 * (For example, on asynchronous execution, you can allocate the data in the heap, and free
1129 * it in your @c spawn_with_callbacks() @c exit_cb callback.)
1131 * @param channel the channel to write data to.
1132 * @param condition condition to check for @c G_IO_OUT.
1133 * @param data @c SpawnWriteData to write to @a channel.
1135 * @return @c TRUE if the remaining size is > 0 and @a condition does not indicate any error,
1136 * @c FALSE otherwise.
1141 gboolean
spawn_write_data(GIOChannel
*channel
, GIOCondition condition
, SpawnWriteData
*data
)
1143 if ((condition
& G_IO_OUT
) && data
->size
)
1145 gsize chars_written
= 0;
1147 g_io_channel_write_chars(channel
, data
->ptr
, data
->size
< DEFAULT_IO_LENGTH
?
1148 data
->size
: DEFAULT_IO_LENGTH
, &chars_written
, NULL
);
1150 /* "This can be nonzero even if the return value is not G_IO_STATUS_NORMAL." */
1153 data
->ptr
+= chars_written
;
1154 data
->size
-= chars_written
;
1158 return data
->size
> 0 && !(condition
& G_IO_FAILURE
);
1162 static void spawn_append_gstring_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1164 if (condition
& (G_IO_IN
| G_IO_PRI
))
1165 g_string_append_len((GString
*) data
, string
->str
, string
->len
);
1169 static void spawn_get_exit_status_cb(G_GNUC_UNUSED GPid pid
, gint status
, gpointer exit_status
)
1171 *(gint
*) exit_status
= status
;
1176 * Executes a child synchronously.
1178 * A command line or an argument vector must be passed. If both are present, the argument
1179 * vector is appended to the command line. An empty command line is not allowed.
1181 * The @a stdin_data is sent to the child with @c spawn_write_data().
1183 * All output from the child, including the nul characters, is stored in @a stdout_data and
1184 * @a stderr_data (if non-NULL). Any existing data in these strings will be erased.
1186 * @param working_directory child's current working directory, or @c NULL.
1187 * @param command_line child program and arguments, or @c NULL.
1188 * @param argv child's argument vector, or @c NULL.
1189 * @param envp child's environment, or @c NULL.
1190 * @param stdin_data data to send to childs's stdin, or @c NULL.
1191 * @param stdout_data GString location to receive the child's stdout, or NULL.
1192 * @param stderr_data GString location to receive the child's stderr, or NULL.
1193 * @param exit_status return location for the child exit code, or NULL.
1194 * @param error return location for error.
1196 * @return @c TRUE on success, @c FALSE on error.
1201 gboolean
spawn_sync(const gchar
*working_directory
, const gchar
*command_line
, gchar
**argv
,
1202 gchar
**envp
, SpawnWriteData
*stdin_data
, GString
*stdout_data
, GString
*stderr_data
,
1203 gint
*exit_status
, GError
**error
)
1205 g_string_truncate(stdout_data
, 0);
1206 g_string_truncate(stderr_data
, 0);
1208 return spawn_with_callbacks(working_directory
, command_line
, argv
, envp
, SPAWN_SYNC
|
1209 SPAWN_UNBUFFERED
, stdin_data
? (GIOFunc
) spawn_write_data
: NULL
, stdin_data
,
1210 stdout_data
? spawn_append_gstring_cb
: NULL
, stdout_data
, 0,
1211 stderr_data
? spawn_append_gstring_cb
: NULL
, stderr_data
, 0,
1212 exit_status
? spawn_get_exit_status_cb
: NULL
, exit_status
, NULL
, error
);
1216 /* tests, not part of the API */
1221 static gboolean
read_line(const char *prompt
, char *buffer
, size_t size
)
1223 fputs(prompt
, stderr
);
1226 if (fgets(buffer
, size
, stdin
))
1228 char *s
= strchr(buffer
, '\n');
1238 static GString
*read_string(const char *prompt
)
1240 char buffer
[0x1000]; /* larger portions for spawn < file */
1241 GString
*string
= g_string_sized_new(sizeof buffer
);
1243 while (read_line(prompt
, buffer
, sizeof buffer
))
1246 g_string_append_c(string
, '\n');
1248 g_string_append(string
, buffer
);
1253 g_string_free(string
, TRUE
);
1261 static void print_cb(GString
*string
, GIOCondition condition
, gpointer data
)
1263 if (condition
& (G_IO_IN
| G_IO_PRI
))
1267 printf("%s: ", (const gchar
*) data
);
1268 /*fputs(string->str, stdout);*/
1269 for (i
= 0; i
< string
->len
; i
++)
1271 unsigned char c
= (unsigned char) string
->str
[i
];
1272 printf(c
>= ' ' && c
< 0x80 ? "%c" : "\\x%02x", c
);
1279 static void print_status(gint status
)
1281 fputs("finished, ", stderr
);
1283 if (SPAWN_WIFEXITED(status
))
1284 fprintf(stderr
, "exit code %d\n", SPAWN_WEXITSTATUS(status
));
1286 fputs("abnormal termination\n", stderr
);
1290 static void exit_cb(GPid pid
, gint status
, G_GNUC_UNUSED gpointer data
)
1292 fprintf(stderr
, "process %u ", (guint
) pid
);
1293 print_status(status
);
1297 static void watch_cb(GPid pid
, gint status
, gpointer data
)
1299 g_spawn_close_pid(pid
);
1300 exit_cb(pid
, status
, NULL
);
1301 g_main_loop_quit((GMainLoop
*) data
);
1305 int main(int argc
, char **argv
)
1311 fputs("usage: spawn <test-type>\n", stderr
);
1315 test_type
= argv
[1];
1317 if (!strcmp(test_type
, "syntax") || !strcmp(test_type
, "syntexec"))
1319 char command_line
[0x100];
1321 while (read_line("command line: ", command_line
, sizeof command_line
))
1323 GError
*error
= NULL
;
1325 if (spawn_check_command(command_line
, argv
[1][4] == 'e', &error
))
1326 fputs("valid\n", stderr
);
1329 fprintf(stderr
, "error: %s\n", error
->message
);
1330 g_error_free(error
);
1334 else if (!strcmp(test_type
, "execute"))
1336 char command_line
[0x100];
1338 while (read_line("command line: ", command_line
, sizeof command_line
))
1340 char working_directory
[0x100];
1341 char args
[4][0x100];
1342 char envs
[4][0x100];
1343 char *argv
[] = { args
[0], args
[1], args
[2], args
[3], NULL
};
1344 char *envp
[] = { envs
[0], envs
[1], envs
[2], envs
[3], NULL
};
1347 GError
*error
= NULL
;
1349 read_line("working directory: ", working_directory
, sizeof working_directory
);
1351 fputs("up to 4 arguments\n", stderr
);
1352 for (i
= 0; i
< 4 && read_line("argument: ", args
[i
], sizeof args
[i
]); i
++);
1355 fputs("up to 4 variables, or empty line for parent environment\n", stderr
);
1356 for (i
= 0; i
< 4 && read_line("variable: ", envs
[i
], sizeof envs
[i
]); i
++);
1359 if (spawn_async_with_pipes(*working_directory
? working_directory
: NULL
,
1360 *command_line
? command_line
: NULL
, argv
, i
? envp
: NULL
, &pid
, NULL
,
1361 NULL
, NULL
, &error
))
1363 GMainLoop
*loop
= g_main_loop_new(NULL
, TRUE
);
1365 g_child_watch_add(pid
, watch_cb
, loop
);
1366 g_main_loop_run(loop
);
1367 g_main_loop_unref(loop
);
1371 fprintf(stderr
, "error: %s\n", error
->message
);
1372 g_error_free(error
);
1376 else if (!strcmp(test_type
, "redirect") || !strcmp(test_type
, "redinput"))
1378 char command_line
[0x100];
1379 gboolean output
= test_type
[4] == 'r';
1381 while (read_line("command line: ", command_line
, sizeof command_line
))
1383 GString
*stdin_text
= read_string("text to send: ");
1384 SpawnWriteData stdin_data
;
1385 GError
*error
= NULL
;
1389 stdin_data
.ptr
= stdin_text
->str
;
1390 stdin_data
.size
= stdin_text
->len
;
1393 if (!spawn_with_callbacks(NULL
, command_line
, NULL
, NULL
, SPAWN_SYNC
,
1394 stdin_text
? (GIOFunc
) spawn_write_data
: NULL
, &stdin_data
,
1395 output
? print_cb
: NULL
, "stdout", 0, output
? print_cb
: NULL
,
1396 "stderr", 0, exit_cb
, NULL
, NULL
, &error
))
1398 fprintf(stderr
, "error: %s\n", error
->message
);
1399 g_error_free(error
);
1403 g_string_free(stdin_text
, TRUE
);
1406 else if (!strcmp(test_type
, "capture"))
1408 char command_line
[0x100];
1410 while (read_line("command line: ", command_line
, sizeof command_line
))
1412 GString
*stdin_text
= read_string("text to send: ");
1413 SpawnWriteData stdin_data
= { NULL
, 0 };
1414 GString
*stdout_data
= g_string_sized_new(0x10000); /* may grow */
1415 GString
*stderr_data
= g_string_sized_new(0x1000); /* may grow */
1417 GError
*error
= NULL
;
1421 stdin_data
.ptr
= stdin_text
->str
;
1422 stdin_data
.size
= stdin_text
->len
;
1425 if (spawn_sync(NULL
, command_line
, NULL
, NULL
, &stdin_data
, stdout_data
,
1426 stderr_data
, &exit_status
, &error
))
1428 printf("stdout: %s\n", stdout_data
->str
);
1429 printf("stderr: %s\n", stderr_data
->str
);
1430 print_status(exit_status
);
1434 fprintf(stderr
, "error: %s\n", error
->message
);
1435 g_error_free(error
);
1439 g_string_free(stdin_text
, TRUE
);
1441 g_string_free(stdout_data
, TRUE
);
1442 g_string_free(stderr_data
, TRUE
);
1447 fprintf(stderr
, "spawn: unknown test type '%s'", argv
[1]);
1453 #endif /* SPAWN_TEST */