]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Get rid of VG_(getcwd) and replace it with a pair of functions,
authorJulian Seward <jseward@acm.org>
Mon, 9 Jul 2007 23:13:07 +0000 (23:13 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 9 Jul 2007 23:13:07 +0000 (23:13 +0000)
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

cachegrind/cg_main.c
callgrind/dump.c
coregrind/launcher-aix5.c
coregrind/m_commandline.c
coregrind/m_libcfile.c
coregrind/m_libcproc.c
coregrind/m_main.c
coregrind/pub_core_libcfile.h
include/pub_tool_libcfile.h
massif/ms_main.c

index 7901a0131ec1ae8cc12a5c0355279132a90f51c1..345a6cb45f4f4aa542d29af63c99cca4db9d6a5d 100644 (file)
@@ -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)) {
index 7172533b5fceb2cd9588b8417ab8771c78943c9e..a46a180fc8750d48603825e1f988663a79c874f7 100644 (file)
@@ -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;
index e7f2115671c8c3b7c1a2d335cfb3d5f8825e6247..4b4753486c40a9b03ae8d7f834e33c3a3e74b1ff 100644 (file)
@@ -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. */
index 3c3d95e0baa4a210a0f119b9168e7e9b5fa94e0b..19ad82a06d1419b5b5e2bf7812b99d3bebf38c3c 100644 (file)
@@ -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(".") );
       }
index 2038ee46c1fb66d4e489d3de73a2cc3ae192cd23..f04fbde4c7263af307df9a18589c067202c77121 100644 (file)
@@ -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;
index 1dc748e94fd949db0eba142214fd903e12bac46a..3b9cf93068c9613b9680d89c281364d7fa849083 100644 (file)
@@ -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];
index 80a6ebd58d277376f94fe86030ee01d656db5ce2..319753d803d834342bb7f32f68a1f397f99651eb 100644 (file)
@@ -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 
index f859777b5fd916a1335261877463dec0a7297b47..83a426f2807ba20f6597b4d173f751c204715f59 100644 (file)
@@ -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
 
 /*--------------------------------------------------------------------*/
index 7d394cb6e3724edb5df1ec3829b10babfeb97dbc..d51b3610212f42ba5ec571b8879013bc9ad234c1 100644 (file)
@@ -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
 
 /*--------------------------------------------------------------------*/
index 6fa430b1f83fa0cfffe614b48f554a56d3062d48..55c4828c5296f828c91bc8717ee9d76e94aae584 100644 (file)
@@ -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)