Factor out differences between VG_(system) and PRE(execve). Required moving

mash_colon_env() from vg_syscalls.c to vg_mylibc.c.  Saved 20 lines of code.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2554
This commit is contained in:
Nicholas Nethercote 2004-08-03 13:08:31 +00:00
parent b960eb25f7
commit 7bdbf7377f
3 changed files with 107 additions and 127 deletions

View File

@ -1096,8 +1096,10 @@ extern Int VG_(write_socket)( Int sd, void *msg, Int count );
extern Int VG_(connect_via_socket)( UChar* str );
/* Environment manipulations */
extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname, const Char *val );
extern void VG_(env_unsetenv) ( Char **env, const Char *varname );
extern Char **VG_(env_setenv) ( Char ***envp, const Char* varname,
const Char *val );
extern void VG_(env_unsetenv) ( Char **env, const Char *varname );
extern void VG_(env_remove_valgrind_env_stuff) ( Char** env );
/* ---------------------------------------------------------------------
Exports of vg_message.c
@ -1456,10 +1458,6 @@ extern void VG_(atfork)(vg_atfork_t pre, vg_atfork_t parent, vg_atfork_t child);
extern void VG_(init_preopened_fds) ( void );
extern void VG_(fd_stats) ( void );
/* Walk through a colon separated list variable, removing entries
which match pattern. */
extern void VG_(mash_colon_env)(Char *varp, const Char *pattern);
/* ---------------------------------------------------------------------
Exports of vg_transtab.c
------------------------------------------------------------------ */

View File

@ -1488,6 +1488,102 @@ Int VG_(setpgid) ( Int pid, Int pgrp )
return VG_(do_syscall)(__NR_setpgid, pid, pgrp);
}
/* Walk through a colon-separated environment variable, and remove the
entries which match remove_pattern. It slides everything down over
the removed entries, and pads the remaining space with '\0'. It
modifies the entries in place (in the client address space), but it
shouldn't matter too much, since we only do this just before an
execve().
This is also careful to mop up any excess ':'s, since empty strings
delimited by ':' are considered to be '.' in a path.
*/
static void mash_colon_env(Char *varp, const Char *remove_pattern)
{
Char *const start = varp;
Char *entry_start = varp;
Char *output = varp;
if (varp == NULL)
return;
while(*varp) {
if (*varp == ':') {
Char prev;
Bool match;
/* This is a bit subtle: we want to match against the entry
we just copied, because it may have overlapped with
itself, junking the original. */
prev = *output;
*output = '\0';
match = VG_(string_match)(remove_pattern, entry_start);
*output = prev;
if (match) {
output = entry_start;
varp++; /* skip ':' after removed entry */
} else
entry_start = output+1; /* entry starts after ':' */
}
*output++ = *varp++;
}
/* match against the last entry */
if (VG_(string_match)(remove_pattern, entry_start)) {
output = entry_start;
if (output > start) {
/* remove trailing ':' */
output--;
vg_assert(*output == ':');
}
}
/* pad out the left-overs with '\0' */
while(output < varp)
*output++ = '\0';
}
// Removes all the Valgrind-added stuff from the passed environment. Used
// when starting child processes, so they don't see that added stuff.
void VG_(env_remove_valgrind_env_stuff)(Char** envp)
{
Int i;
Char* ld_preload_str = NULL;
Char* ld_library_path_str = NULL;
Char* buf;
// Find LD_* variables
for (i = 0; envp[i] != NULL; i++) {
if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
ld_preload_str = &envp[i][11];
if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
ld_library_path_str = &envp[i][16];
}
buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
// Remove Valgrind-specific entries from LD_*.
VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
mash_colon_env(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
mash_colon_env(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*", VG_(libdir));
mash_colon_env(ld_library_path_str, buf);
// Remove VALGRIND_CLO variable.
VG_(env_unsetenv)(envp, VALGRINDCLO);
// XXX if variable becomes empty, remove it completely?
VG_(arena_free)(VG_AR_CORE, buf);
}
/* Return -1 if error, else 0. NOTE does not indicate return code of
child! */
Int VG_(system) ( Char* cmd )
@ -1506,36 +1602,8 @@ Int VG_(system) ( Char* cmd )
/* restore the DATA rlimit for the child */
VG_(setrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
if (envp == NULL) {
Int i;
Char* ld_preload_str = NULL;
Char* ld_library_path_str = NULL;
Char* buf;
envp = env_clone(VG_(client_envp));
for (i = 0; envp[i] != NULL; i++) {
if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
ld_preload_str = &envp[i][11];
if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
ld_library_path_str = &envp[i][16];
}
buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*", VG_(libdir));
VG_(mash_colon_env)(ld_library_path_str, buf);
VG_(env_unsetenv)(envp, VALGRINDCLO);
VG_(arena_free)(VG_AR_CORE, buf);
}
envp = env_clone(VG_(client_envp));
VG_(env_remove_valgrind_env_stuff)( envp );
argv[0] = "/bin/sh";
argv[1] = "-c";

View File

@ -153,67 +153,6 @@ static Bool valid_client_addr(Addr start, UInt size, ThreadId tid, const Char *s
return ret;
}
/* Walk through a colon-separated environment variable, and remove the
entries which matches file_pattern. It slides everything down over
the removed entries, and pads the remaining space with '\0'. It
modifies the entries in place (in the client address space), but it
shouldn't matter too much, since we only do this just before an
execve().
This is also careful to mop up any excess ':'s, since empty strings
delimited by ':' are considered to be '.' in a path.
*/
void VG_(mash_colon_env)(Char *varp, const Char *remove_pattern)
{
Char *const start = varp;
Char *entry_start = varp;
Char *output = varp;
if (varp == NULL)
return;
while(*varp) {
if (*varp == ':') {
Char prev;
Bool match;
/* This is a bit subtle: we want to match against the entry
we just copied, because it may have overlapped with
itself, junking the original. */
prev = *output;
*output = '\0';
match = VG_(string_match)(remove_pattern, entry_start);
*output = prev;
if (match) {
output = entry_start;
varp++; /* skip ':' after removed entry */
} else
entry_start = output+1; /* entry starts after ':' */
}
*output++ = *varp++;
}
/* match against the last entry */
if (VG_(string_match)(remove_pattern, entry_start)) {
output = entry_start;
if (output > start) {
/* remove trailing ':' */
output--;
vg_assert(*output == ':');
}
}
/* pad out the left-overs with '\0' */
while(output < varp)
*output++ = '\0';
}
/* ---------------------------------------------------------------------
Doing mmap, mremap
------------------------------------------------------------------ */
@ -1839,39 +1778,14 @@ PRE(execve)
VG_(nuke_all_threads_except)( VG_INVALID_THREADID );
{
/* Make the LD_LIBRARY_PATH/LD_PRELOAD disappear so that the
child doesn't get our libpthread and other stuff. This is
done unconditionally, since if we are tracing the child,
stage1/2 will set up the appropriate client environment. */
Int i;
// Remove the valgrind-specific stuff from the environment so the
// child doesn't get our libpthread and other stuff. This is
// done unconditionally, since if we are tracing the child,
// stage1/2 will set up the appropriate client environment.
Char** envp = (Char**)arg3;
Char* ld_preload_str = NULL;
Char* ld_library_path_str = NULL;
if (envp != NULL) {
Char *buf;
for (i = 0; envp[i] != NULL; i++) {
if (VG_(strncmp)(envp[i], "LD_PRELOAD=", 11) == 0)
ld_preload_str = &envp[i][11];
if (VG_(strncmp)(envp[i], "LD_LIBRARY_PATH=", 16) == 0)
ld_library_path_str = &envp[i][16];
}
buf = VG_(arena_malloc)(VG_AR_CORE, VG_(strlen)(VG_(libdir)) + 20);
VG_(sprintf)(buf, "%s*/vg_inject.so", VG_(libdir));
VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*/vgpreload_*.so", VG_(libdir));
VG_(mash_colon_env)(ld_preload_str, buf);
VG_(sprintf)(buf, "%s*", VG_(libdir));
VG_(mash_colon_env)(ld_library_path_str, buf);
VG_(env_unsetenv)(envp, VALGRINDCLO);
/* XXX if variable becomes empty, remove it completely? */
VG_(env_remove_valgrind_env_stuff)( envp );
}
}