1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-07-02 15:40:38 +02:00

Move string-pointer-array handling to posix.c

* libguile/posix.c (free_string_pointers):
(free_string_pointers_on_unwind):
(allocate_string_pointers): Move here from string.c, and use malloc/free
instead of GC facilities. Adapt all users.
* libguile/strings.h:
* libguile/strings.c (scm_i_allocate_string_pointers): Remove.
This commit is contained in:
Andy Wingo 2025-06-20 09:48:43 +02:00
parent ce2f7847e8
commit a793d371cd
3 changed files with 65 additions and 55 deletions

View file

@ -1138,6 +1138,55 @@ SCM_DEFINE (scm_tcsetpgrp, "tcsetpgrp", 2, 0, 0,
#undef FUNC_NAME
#endif /* HAVE_TCSETPGRP */
/* Return a newly allocated array of char pointers to each of the strings
in args, with a terminating NULL pointer. The strings are encoded using
the current locale. */
static void
free_string_pointers (char **pointers)
{
for (char **walk = pointers; *walk; walk++)
free (*walk);
free (pointers);
}
static void
free_string_pointers_on_unwind (void *data)
{
free_string_pointers (data);
}
static char **
allocate_string_pointers (SCM list)
{
int list_len = scm_ilength (list);
int i;
if (list_len < 0)
scm_wrong_type_arg_msg (NULL, 0, list, "proper list");
char **result = scm_calloc ((list_len + 1) * sizeof (char *));
scm_dynwind_begin (0);
scm_dynwind_unwind_handler (free_string_pointers_on_unwind, result, 0);
for (i = 0; i < list_len; i++, list = scm_cdr (list))
{
SCM str = scm_car (list);
size_t len; /* String length in bytes */
char *c_str = scm_to_locale_stringn (str, &len);
result[i] = malloc (len + 1);
memcpy (result[i], c_str, len);
result[i][len] = '\0';
free (c_str);
}
scm_dynwind_end ();
return result;
}
SCM_DEFINE (scm_execl, "execl", 1, 0, 1,
(SCM filename, SCM args),
"Executes the file named by @var{filename} as a new process image.\n"
@ -1159,7 +1208,7 @@ SCM_DEFINE (scm_execl, "execl", 1, 0, 1,
exec_file = scm_to_locale_string (filename);
scm_dynwind_free (exec_file);
exec_argv = scm_i_allocate_string_pointers (args);
exec_argv = allocate_string_pointers (args);
#ifdef __MINGW32__
execv (exec_file, (const char * const *)exec_argv);
@ -1192,7 +1241,7 @@ SCM_DEFINE (scm_execlp, "execlp", 1, 0, 1,
exec_file = scm_to_locale_string (filename);
scm_dynwind_free (exec_file);
exec_argv = scm_i_allocate_string_pointers (args);
exec_argv = allocate_string_pointers (args);
#ifdef __MINGW32__
execvp (exec_file, (const char * const *)exec_argv);
@ -1229,8 +1278,8 @@ SCM_DEFINE (scm_execle, "execle", 2, 0, 1,
exec_file = scm_to_locale_string (filename);
scm_dynwind_free (exec_file);
exec_argv = scm_i_allocate_string_pointers (args);
exec_env = scm_i_allocate_string_pointers (env);
exec_argv = allocate_string_pointers (args);
exec_env = allocate_string_pointers (env);
#ifdef __MINGW32__
execve (exec_file, (const char * const *) exec_argv, (const char * const *) exec_env);
@ -1474,12 +1523,18 @@ SCM_DEFINE (scm_spawn_process, "spawn", 2, 0, 1,
exec_file = scm_to_locale_string (program);
scm_dynwind_free (exec_file);
exec_argv = scm_i_allocate_string_pointers (arguments);
exec_argv = allocate_string_pointers (arguments);
scm_dynwind_unwind_handler (free_string_pointers_on_unwind, exec_argv,
SCM_F_WIND_EXPLICITLY);
if (SCM_UNBNDP (env))
exec_env = environ;
else
exec_env = scm_i_allocate_string_pointers (env);
{
exec_env = allocate_string_pointers (env);
scm_dynwind_unwind_handler (free_string_pointers_on_unwind, exec_env,
SCM_F_WIND_EXPLICITLY);
}
if (SCM_UNBNDP (in_scm))
in_scm = scm_current_input_port ();
@ -1530,7 +1585,7 @@ piped_process (pid_t *pid, SCM prog, SCM args, SCM from, SCM to)
char **exec_env = environ;
exec_file = scm_to_locale_string (prog);
exec_argv = scm_i_allocate_string_pointers (scm_cons (prog, args));
exec_argv = allocate_string_pointers (scm_cons (prog, args));
reading = scm_is_pair (from);
writing = scm_is_pair (to);
@ -1575,6 +1630,8 @@ piped_process (pid_t *pid, SCM prog, SCM args, SCM from, SCM to)
*pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err, 1);
int errno_save = (*pid < 0) ? errno : 0;
free_string_pointers (exec_argv);
if (reading)
close (c2p[1]);
if (writing)