diff options
author | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2007-07-09 23:13:07 +0000 |
---|---|---|
committer | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2007-07-09 23:13:07 +0000 |
commit | 198f34fa929569172d863f9c33f9686855ca975a (patch) | |
tree | b7837222b0ffd4c8e97e409372606eaa65b29838 | |
parent | ca73f4db01587833757cf43c12eb3a4c4dcaafc5 (diff) | |
download | valgrind-198f34fa929569172d863f9c33f9686855ca975a.tar.gz |
Get rid of VG_(getcwd) and replace it with a pair of functions,
VG_(record_startup_wd) which records the working directory at startup,
and VG_(get_startup_wd) which later tells you what value was recorded.
This works because all uses of VG_(getcwd) serve only to record the
directory at process start anyway. The motivation is that AIX does
not support sys_getcwd directly, so it's easier for the launcher to
ship in the required value using an environment variable. On Linux
sys_getcwd is used as before.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6764 a5019735-40e9-0310-863c-91ae7b9d1cf9
-rw-r--r-- | cachegrind/cg_main.c | 2 | ||||
-rw-r--r-- | callgrind/dump.c | 2 | ||||
-rw-r--r-- | coregrind/launcher-aix5.c | 23 | ||||
-rw-r--r-- | coregrind/m_commandline.c | 2 | ||||
-rw-r--r-- | coregrind/m_libcfile.c | 74 | ||||
-rw-r--r-- | coregrind/m_libcproc.c | 3 | ||||
-rw-r--r-- | coregrind/m_main.c | 16 | ||||
-rw-r--r-- | coregrind/pub_core_libcfile.h | 8 | ||||
-rw-r--r-- | include/pub_tool_libcfile.h | 4 | ||||
-rw-r--r-- | massif/ms_main.c | 2 |
10 files changed, 117 insertions, 19 deletions
diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 7901a0131..345a6cb45 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -1754,7 +1754,7 @@ static void cg_post_clo_init(void) } /* Get working directory */ - tl_assert( VG_(getcwd)(base_dir, VKI_PATH_MAX) ); + tl_assert( VG_(get_startup_wd)(base_dir, VKI_PATH_MAX) ); /* Do we have a --log-file-qualifier= to consider? */ if (VG_(clo_log_file_qualifier)) { diff --git a/callgrind/dump.c b/callgrind/dump.c index 7172533b5..a46a180fc 100644 --- a/callgrind/dump.c +++ b/callgrind/dump.c @@ -1689,7 +1689,7 @@ void CLG_(init_dumps)() until it succeeds. */ while (NULL == base_directory) { base_directory = CLG_MALLOC(size); - if (!VG_(getcwd)(base_directory, size)) { + if (!VG_(get_startup_wd)(base_directory, size)) { VG_(free)(base_directory); base_directory = 0; size *= 2; diff --git a/coregrind/launcher-aix5.c b/coregrind/launcher-aix5.c index e7f211567..4b4753486 100644 --- a/coregrind/launcher-aix5.c +++ b/coregrind/launcher-aix5.c @@ -1526,6 +1526,29 @@ int main ( int argc, char** argv, char** envp ) return 1; } + /* Find out what the current working directory is, and stuff it into the + environment so that the child can find it. */ + char wd_buf[4096]; + memset(wd_buf, 0, sizeof(wd_buf)); + if (getcwd(wd_buf, sizeof(wd_buf)-1) == NULL) { + fprintf(stderr,"%s: getcwd(..) failed\n", argv[0]); + return 1; + } + assert(wd_buf[ sizeof(wd_buf)-1 ] == 0); + char* set_cwd = calloc(1, 100+sizeof(wd_buf)); + if (set_cwd == NULL) { + fprintf(stderr,"%s: calloc of set_cwd failed\n", argv[0]); + return 1; + } + sprintf(set_cwd, "VALGRIND_STARTUP_PWD_%d_XYZZY=%s", getpid(), wd_buf); + VG_(debugLog)(1, "launcher", "doing putenv(\"%s\")\n", set_cwd); + putenv_err = putenv(set_cwd); + if (putenv_err) { + fprintf(stderr,"%s: putenv(\"VALGRIND_STARTUP_PWD_...\") failed\n", + argv[0]); + return 1; + } + /* Also, cook up the fully qualified name of this executable. The following is a kludge, but I don't see how to really get the fully qualified name on AIX. */ diff --git a/coregrind/m_commandline.c b/coregrind/m_commandline.c index 3c3d95e0b..19ad82a06 100644 --- a/coregrind/m_commandline.c +++ b/coregrind/m_commandline.c @@ -210,7 +210,7 @@ void VG_(split_up_argv)( Int argc, HChar** argv ) // contents will be applied twice. (bug #142488) if (home) { HChar cwd[VKI_PATH_MAX+1]; - Bool cwd_ok = VG_(getcwd)(cwd, VKI_PATH_MAX); + Bool cwd_ok = VG_(get_startup_wd)(cwd, VKI_PATH_MAX); f2_clo = ( (cwd_ok && VG_STREQ(home, cwd)) ? NULL : read_dot_valgrindrc(".") ); } diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 2038ee46c..f04fbde4c 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -217,27 +217,73 @@ Int VG_(unlink) ( Char* file_name ) return res.isError ? (-1) : 0; } -Bool VG_(getcwd) ( Char* buf, SizeT size ) -{ +/* The working directory at startup. AIX doesn't provide an easy + system call to do getcwd, but fortunately we don't need arbitrary + getcwd support. All that is really needed is to note the cwd at + process startup. Hence VG_(record_startup_wd) notes it (in a + platform dependent way) and VG_(get_startup_wd) produces the noted + value. Hence: */ +static HChar startup_wd[VKI_PATH_MAX]; +static Bool startup_wd_acquired = False; + +/* Record the process' working directory at startup. Is intended to + be called exactly once, at startup, before the working directory + changes. Return True for success, False for failure, so that the + caller can bomb out suitably without creating module cycles if + there is a problem. */ +Bool VG_(record_startup_wd) ( void ) +{ + const Int szB = sizeof(startup_wd); + vg_assert(!startup_wd_acquired); + vg_assert(szB >= 512 && szB <= 16384/*let's say*/); /* stay sane */ + VG_(memset)(startup_wd, 0, szB); # if defined(VGO_linux) - SysRes res; - vg_assert(buf != NULL); - res = VG_(do_syscall2)(__NR_getcwd, (UWord)buf, size); - return res.isError ? False : True; + /* Simple: just ask the kernel */ + { SysRes res + = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1); + vg_assert(startup_wd[szB-1] == 0); + if (res.isError) { + return False; + } else { + startup_wd_acquired = True; + return True; + } + } # elif defined(VGO_aix5) - static Int complaints = 3; - if (complaints-- > 0) - VG_(debugLog)(0, "libcfile", - "Warning: AIX5: m_libcfile.c: kludged 'getcwd'\n"); - if (size < 2) return False; - buf[0] = '.'; - buf[1] = 0; - return True; + /* We can't ask the kernel, so instead rely on launcher-aix5.c to + tell us the startup path. Note the env var is keyed to the + parent's PID, not ours, since our parent is the launcher + process. */ + { Char envvar[100]; + Char* wd = NULL; + VG_(memset)(envvar, 0, sizeof(envvar)); + VG_(sprintf)(envvar, "VALGRIND_STARTUP_PWD_%d_XYZZY", + (Int)VG_(getppid)()); + wd = VG_(getenv)( envvar ); + if (wd == NULL || (1+VG_(strlen)(wd) >= szB)) + return False; + VG_(strncpy_safely)(startup_wd, wd, szB); + vg_assert(startup_wd[szB-1] == 0); + startup_wd_acquired = True; + return True; + } # else # error Unknown OS # endif } +/* Copy the previously acquired startup_wd into buf[0 .. size-1], + or return False if buf isn't big enough. */ +Bool VG_(get_startup_wd) ( Char* buf, SizeT size ) +{ + vg_assert(startup_wd_acquired); + vg_assert(startup_wd[ sizeof(startup_wd)-1 ] == 0); + if (1+VG_(strlen)(startup_wd) >= size) + return False; + VG_(strncpy_safely)(buf, startup_wd, size); + return True; +} + Int VG_(readlink) (Char* path, Char* buf, UInt bufsiz) { SysRes res; diff --git a/coregrind/m_libcproc.c b/coregrind/m_libcproc.c index 1dc748e94..3b9cf9306 100644 --- a/coregrind/m_libcproc.c +++ b/coregrind/m_libcproc.c @@ -47,7 +47,7 @@ /* As deduced from sp_at_startup, the client's argc, argv[] and envp[] as extracted from the client's stack at startup-time. */ -Char** VG_(client_envp); +Char** VG_(client_envp) = NULL; /* Path to library directory */ const Char *VG_(libdir) = VG_LIBDIR; @@ -57,6 +57,7 @@ const Char *VG_(libdir) = VG_LIBDIR; Char *VG_(getenv)(Char *varname) { Int i, n; + vg_assert( VG_(client_envp) ); n = VG_(strlen)(varname); for (i = 0; VG_(client_envp)[i] != NULL; i++) { Char* s = VG_(client_envp)[i]; diff --git a/coregrind/m_main.c b/coregrind/m_main.c index 80a6ebd58..319753d80 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -1377,6 +1377,22 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **envp ) ); } + //-------------------------------------------------------------- + // Record the working directory at startup + // p: none (Linux), getenv and sys_getpid work (AIX) + VG_(debugLog)(1, "main", "Getting the working directory at startup\n"); + { Bool ok = VG_(record_startup_wd)(); + if (!ok) + VG_(err_config_error)( "Can't establish current working " + "directory at startup"); + } + { Char buf[VKI_PATH_MAX+1]; + Bool ok = VG_(get_startup_wd)( buf, sizeof(buf) ); + vg_assert(ok); + buf[VKI_PATH_MAX] = 0; + VG_(debugLog)(1, "main", "... %s\n", buf ); + } + //============================================================ // Command line argument handling order: // * If --help/--help-debug are present, show usage message diff --git a/coregrind/pub_core_libcfile.h b/coregrind/pub_core_libcfile.h index f859777b5..83a426f28 100644 --- a/coregrind/pub_core_libcfile.h +++ b/coregrind/pub_core_libcfile.h @@ -81,6 +81,14 @@ extern SysRes VG_(pread) ( Int fd, void* buf, Int count, Int offset ); written is guaranteed not to exceed 64+strlen(part_of_name). */ extern Int VG_(mkstemp) ( HChar* part_of_name, /*OUT*/HChar* fullname ); +/* Record the process' working directory at startup. Is intended to + be called exactly once, at startup, before the working directory + changes. Return True for success, False for failure, so that the + caller can bomb out suitably without creating module cycles if + there is a problem. The saved value can later be acquired by + calling VG_(get_startup_wd) (in pub_tool_libcfile.h). */ +extern Bool VG_(record_startup_wd) ( void ); + #endif // __PUB_CORE_LIBCFILE_H /*--------------------------------------------------------------------*/ diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index 7d394cb6e..d51b36102 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -56,6 +56,10 @@ extern Bool VG_(getcwd) ( Char* buf, SizeT size ); extern Int VG_(readlink)( Char* path, Char* buf, UInt bufsize ); extern Int VG_(getdents)( UInt fd, struct vki_dirent *dirp, UInt count ); +/* Copy the working directory at startup into buf[0 .. size-1], or return + False if buf is too small. */ +extern Bool VG_(get_startup_wd) ( Char* buf, SizeT size ); + #endif // __PUB_TOOL_LIBCFILE_H /*--------------------------------------------------------------------*/ diff --git a/massif/ms_main.c b/massif/ms_main.c index 6fa430b1f..55c4828c5 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -1758,7 +1758,7 @@ static void ms_pre_clo_init(void) // Dummy node at top of the context structure. alloc_xpt = new_XPt(0, NULL, /*is_bottom*/False); - tl_assert( VG_(getcwd)(base_dir, VKI_PATH_MAX) ); + tl_assert( VG_(get_startup_wd)(base_dir, VKI_PATH_MAX) ); } VG_DETERMINE_INTERFACE_VERSION(ms_pre_clo_init) |