mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-03 08:10:31 +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:
parent
ce2f7847e8
commit
a793d371cd
3 changed files with 65 additions and 55 deletions
|
@ -1138,6 +1138,55 @@ SCM_DEFINE (scm_tcsetpgrp, "tcsetpgrp", 2, 0, 0,
|
||||||
#undef FUNC_NAME
|
#undef FUNC_NAME
|
||||||
#endif /* HAVE_TCSETPGRP */
|
#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_DEFINE (scm_execl, "execl", 1, 0, 1,
|
||||||
(SCM filename, SCM args),
|
(SCM filename, SCM args),
|
||||||
"Executes the file named by @var{filename} as a new process image.\n"
|
"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);
|
exec_file = scm_to_locale_string (filename);
|
||||||
scm_dynwind_free (exec_file);
|
scm_dynwind_free (exec_file);
|
||||||
|
|
||||||
exec_argv = scm_i_allocate_string_pointers (args);
|
exec_argv = allocate_string_pointers (args);
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
execv (exec_file, (const char * const *)exec_argv);
|
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);
|
exec_file = scm_to_locale_string (filename);
|
||||||
scm_dynwind_free (exec_file);
|
scm_dynwind_free (exec_file);
|
||||||
|
|
||||||
exec_argv = scm_i_allocate_string_pointers (args);
|
exec_argv = allocate_string_pointers (args);
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
execvp (exec_file, (const char * const *)exec_argv);
|
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);
|
exec_file = scm_to_locale_string (filename);
|
||||||
scm_dynwind_free (exec_file);
|
scm_dynwind_free (exec_file);
|
||||||
|
|
||||||
exec_argv = scm_i_allocate_string_pointers (args);
|
exec_argv = allocate_string_pointers (args);
|
||||||
exec_env = scm_i_allocate_string_pointers (env);
|
exec_env = allocate_string_pointers (env);
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
execve (exec_file, (const char * const *) exec_argv, (const char * const *) exec_env);
|
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);
|
exec_file = scm_to_locale_string (program);
|
||||||
scm_dynwind_free (exec_file);
|
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))
|
if (SCM_UNBNDP (env))
|
||||||
exec_env = environ;
|
exec_env = environ;
|
||||||
else
|
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))
|
if (SCM_UNBNDP (in_scm))
|
||||||
in_scm = scm_current_input_port ();
|
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;
|
char **exec_env = environ;
|
||||||
|
|
||||||
exec_file = scm_to_locale_string (prog);
|
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);
|
reading = scm_is_pair (from);
|
||||||
writing = scm_is_pair (to);
|
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);
|
*pid = do_spawn (exec_file, exec_argv, exec_env, in, out, err, 1);
|
||||||
int errno_save = (*pid < 0) ? errno : 0;
|
int errno_save = (*pid < 0) ? errno : 0;
|
||||||
|
|
||||||
|
free_string_pointers (exec_argv);
|
||||||
|
|
||||||
if (reading)
|
if (reading)
|
||||||
close (c2p[1]);
|
close (c2p[1]);
|
||||||
if (writing)
|
if (writing)
|
||||||
|
|
|
@ -2430,52 +2430,6 @@ scm_makfromstrs (int argc, char **argv)
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
|
|
||||||
char **
|
|
||||||
scm_i_allocate_string_pointers (SCM list)
|
|
||||||
#define FUNC_NAME "scm_i_allocate_string_pointers"
|
|
||||||
{
|
|
||||||
char **result;
|
|
||||||
int list_len = scm_ilength (list);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (list_len < 0)
|
|
||||||
scm_wrong_type_arg_msg (NULL, 0, list, "proper list");
|
|
||||||
|
|
||||||
result = scm_gc_malloc ((list_len + 1) * sizeof (char *),
|
|
||||||
"string pointers");
|
|
||||||
result[list_len] = NULL;
|
|
||||||
|
|
||||||
/* The list might have been modified in another thread, so
|
|
||||||
we check LIST before each access.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < list_len && scm_is_pair (list); i++)
|
|
||||||
{
|
|
||||||
SCM str = SCM_CAR (list);
|
|
||||||
size_t len; /* String length in bytes */
|
|
||||||
char *c_str = scm_to_locale_stringn (str, &len);
|
|
||||||
|
|
||||||
/* OPTIMIZE-ME: Right now, scm_to_locale_stringn always uses
|
|
||||||
scm_malloc to allocate the returned string, which must be
|
|
||||||
explicitly deallocated. This forces us to copy the string a
|
|
||||||
second time into a new buffer. Ideally there would be variants
|
|
||||||
of scm_to_*_stringn that can return garbage-collected buffers. */
|
|
||||||
|
|
||||||
result[i] = scm_gc_malloc_pointerless (len + 1, "string");
|
|
||||||
memcpy (result[i], c_str, len);
|
|
||||||
result[i][len] = '\0';
|
|
||||||
free (c_str);
|
|
||||||
|
|
||||||
list = SCM_CDR (list);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#undef FUNC_NAME
|
|
||||||
|
|
||||||
void
|
void
|
||||||
scm_i_get_substring_spec (size_t len,
|
scm_i_get_substring_spec (size_t len,
|
||||||
SCM start, size_t *cstart,
|
SCM start, size_t *cstart,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef SCM_STRINGS_H
|
#ifndef SCM_STRINGS_H
|
||||||
#define SCM_STRINGS_H
|
#define SCM_STRINGS_H
|
||||||
|
|
||||||
/* Copyright 1995-1998,2000-2001,2004-2006,2008-2011,2013,2015-2019,2022
|
/* Copyright 1995-1998,2000-2001,2004-2006,2008-2011,2013,2015-2019,2022,2025
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of Guile.
|
This file is part of Guile.
|
||||||
|
@ -265,7 +265,6 @@ SCM_INTERNAL void scm_decoding_error (const char *subr, int err,
|
||||||
|
|
||||||
/* internal utility functions. */
|
/* internal utility functions. */
|
||||||
|
|
||||||
SCM_INTERNAL char **scm_i_allocate_string_pointers (SCM list);
|
|
||||||
SCM_INTERNAL void scm_i_get_substring_spec (size_t len,
|
SCM_INTERNAL void scm_i_get_substring_spec (size_t len,
|
||||||
SCM start, size_t *cstart,
|
SCM start, size_t *cstart,
|
||||||
SCM end, size_t *cend);
|
SCM end, size_t *cend);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue