summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glib/gspawn.c38
1 files changed, 30 insertions, 8 deletions
diff --git a/glib/gspawn.c b/glib/gspawn.c
index 032835b93..3ed437423 100644
--- a/glib/gspawn.c
+++ b/glib/gspawn.c
@@ -1769,8 +1769,10 @@ fork_exec_with_fds (gboolean intermediate_child,
gint status;
const gchar *chosen_search_path;
gchar *search_path_buffer = NULL;
+ gchar *search_path_buffer_heap = NULL;
gsize search_path_buffer_len = 0;
gchar **argv_buffer = NULL;
+ gchar **argv_buffer_heap = NULL;
gsize argv_buffer_len = 0;
#ifdef POSIX_SPAWN_AVAILABLE
@@ -1864,7 +1866,17 @@ fork_exec_with_fds (gboolean intermediate_child,
if (chosen_search_path != NULL)
{
search_path_buffer_len = strlen (chosen_search_path) + strlen (argv[0]) + 2;
- search_path_buffer = g_malloc (search_path_buffer_len);
+ if (search_path_buffer_len < 4000)
+ {
+ /* Prefer small stack allocations to avoid valgrind leak warnings
+ * in forked child. The 4000B cutoff is arbitrary. */
+ search_path_buffer = g_alloca (search_path_buffer_len);
+ }
+ else
+ {
+ search_path_buffer_heap = g_malloc (search_path_buffer_len);
+ search_path_buffer = search_path_buffer_heap;
+ }
}
if (search_path || search_path_from_envp)
@@ -1876,12 +1888,22 @@ fork_exec_with_fds (gboolean intermediate_child,
* script_execute() has to be called later on, it can build a wrapper argv
* array in this buffer. */
argv_buffer_len = g_strv_length (argv) + 2;
- argv_buffer = g_new (gchar *, argv_buffer_len);
+ if (argv_buffer_len < 4000 / sizeof (gchar *))
+ {
+ /* Prefer small stack allocations to avoid valgrind leak warnings
+ * in forked child. The 4000B cutoff is arbitrary. */
+ argv_buffer = g_newa (gchar *, argv_buffer_len);
+ }
+ else
+ {
+ argv_buffer_heap = g_new (gchar *, argv_buffer_len);
+ argv_buffer = argv_buffer_heap;
+ }
if (!g_unix_open_pipe (child_err_report_pipe, pipe_flags, error))
{
- g_free (search_path_buffer);
- g_free (argv_buffer);
+ g_free (search_path_buffer_heap);
+ g_free (argv_buffer_heap);
return FALSE;
}
@@ -2128,8 +2150,8 @@ fork_exec_with_fds (gboolean intermediate_child,
close_and_invalidate (&child_err_report_pipe[0]);
close_and_invalidate (&child_pid_report_pipe[0]);
- g_free (search_path_buffer);
- g_free (argv_buffer);
+ g_free (search_path_buffer_heap);
+ g_free (argv_buffer_heap);
if (child_pid)
*child_pid = pid;
@@ -2163,8 +2185,8 @@ fork_exec_with_fds (gboolean intermediate_child,
close_and_invalidate (&child_pid_report_pipe[0]);
close_and_invalidate (&child_pid_report_pipe[1]);
- g_free (search_path_buffer);
- g_free (argv_buffer);
+ g_free (search_path_buffer_heap);
+ g_free (argv_buffer_heap);
return FALSE;
}