Merge 14206,14207,14261,14577,14578 from BUF_REMOVAL branch to trunk.
This changes VG_(record_startup_wd) to dynamically allocate a large
enough buffer for the directory name. As the dynamic memory manager has
started up a while ago, this is quite safe. Also rewrite VG_(get_startup_wd)
to simply return the directory name. No more messing with copying it
around. Adapt call sites.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14579 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_commandline.c b/coregrind/m_commandline.c
index 9f020fd..3a4c271 100644
--- a/coregrind/m_commandline.c
+++ b/coregrind/m_commandline.c
@@ -218,9 +218,8 @@
       // Don't read ./.valgrindrc if "." is the same as "$HOME", else its
       // contents will be applied twice. (bug #142488)
       if (home) {
-         HChar cwd[VKI_PATH_MAX+1];
-         Bool  cwd_ok = VG_(get_startup_wd)(cwd, VKI_PATH_MAX);
-         f2_clo = ( (cwd_ok && VG_STREQ(home, cwd))
+         const HChar *cwd = VG_(get_startup_wd)();
+         f2_clo = ( VG_STREQ(home, cwd)
                        ? NULL : read_dot_valgrindrc(".") );
       }
 
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 9459f7a..ceb6bdc 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -418,14 +418,12 @@
    return sr_isError(res) ? (-1) : 0;
 }
 
-/* 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;
+/* The working directory at startup.
+   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. */
+static HChar *startup_wd;
+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
@@ -434,37 +432,39 @@
    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)
    /* 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 (sr_isError(res)) {
-        return False;
-     } else {
-        startup_wd_acquired = True;
-        return True;
-     }
-   }
+   SysRes res;
+   SizeT szB = 0;
+   do { 
+      szB += 500;
+      startup_wd = VG_(realloc)("startup_wd", startup_wd, szB);
+      VG_(memset)(startup_wd, 0, szB);
+      res = VG_(do_syscall2)(__NR_getcwd, (UWord)startup_wd, szB-1);
+   } while (sr_isError(res));
+
+   vg_assert(startup_wd[szB-1] == 0);
+   startup_wd_acquired = True;
+   return True;
+
 #  elif defined(VGO_darwin)
    /* We can't ask the kernel, so instead rely on launcher-*.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. */
-   { HChar  envvar[100];
-     HChar* wd = NULL;
+   { HChar  envvar[100];   // large enough
+     HChar* wd;
      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))
+     if (wd == NULL)
         return False;
-     VG_(strncpy_safely)(startup_wd, wd, szB);
-     vg_assert(startup_wd[szB-1] == 0);
+     SizeT need = VG_(strlen)(wd) + 1;
+     startup_wd = VG_(malloc)("startup_wd", need);
+     VG_(strcpy)(startup_wd, wd);
      startup_wd_acquired = True;
      return True;
    }
@@ -473,16 +473,12 @@
 #  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) ( HChar* buf, SizeT size )
+/* Return the previously acquired startup_wd. */
+const HChar *VG_(get_startup_wd) ( void )
 {
    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;
+
+   return startup_wd;
 }
 
 SysRes VG_(poll) (struct vki_pollfd *fds, Int nfds, Int timeout)
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 94dc415..1499c8a 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -1763,12 +1763,7 @@
         VG_(err_config_error)( "Can't establish current working "
                                "directory at startup\n");
    }
-   { HChar 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 );
-   }
+   VG_(debugLog)(1, "main", "... %s\n", VG_(get_startup_wd)() );
 
    //============================================================
    // Command line argument handling order:
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index 0710c8d..3140b81 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -142,12 +142,11 @@
 // expanding %p and %q entries.  Returns a new, malloc'd string.
 HChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format)
 {
-   static HChar base_dir[VKI_PATH_MAX];
+   const HChar *base_dir;
    Int len, i = 0, j = 0;
    HChar* out;
 
-   Bool ok = VG_(get_startup_wd)(base_dir, VKI_PATH_MAX);
-   vg_assert(ok);
+   base_dir = VG_(get_startup_wd)();
 
    if (VG_STREQ(format, "")) {
       // Empty name, bad.
diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h
index ea50289..bb1a6e4 100644
--- a/include/pub_tool_libcfile.h
+++ b/include/pub_tool_libcfile.h
@@ -103,9 +103,9 @@
 /* Return the name of a directory for temporary files. */
 extern const HChar* VG_(tmpdir)(void);
 
-/* 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) ( HChar* buf, SizeT size );
+/* Return the working directory at startup. The returned string is
+   persistent. */
+extern const HChar *VG_(get_startup_wd) ( void );
 
 #endif   // __PUB_TOOL_LIBCFILE_H