aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9>2007-07-09 23:13:07 +0000
committersewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9>2007-07-09 23:13:07 +0000
commit198f34fa929569172d863f9c33f9686855ca975a (patch)
treeb7837222b0ffd4c8e97e409372606eaa65b29838
parentca73f4db01587833757cf43c12eb3a4c4dcaafc5 (diff)
downloadvalgrind-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.c2
-rw-r--r--callgrind/dump.c2
-rw-r--r--coregrind/launcher-aix5.c23
-rw-r--r--coregrind/m_commandline.c2
-rw-r--r--coregrind/m_libcfile.c74
-rw-r--r--coregrind/m_libcproc.c3
-rw-r--r--coregrind/m_main.c16
-rw-r--r--coregrind/pub_core_libcfile.h8
-rw-r--r--include/pub_tool_libcfile.h4
-rw-r--r--massif/ms_main.c2
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)