Author: gclayton Date: Tue Apr 19 18:04:35 2016 New Revision: 266832 URL: http://llvm.org/viewvc/llvm-project?rev=266832&view=rev Log: llvm::sys::path::home_directory() relies on having "HOME" set in the environment and that might not always be set. Our FileSpec class uses this function to resolve any paths that start with "~/" on systems that support home directories as '~'. I have modified FileSpec::ResolveUsername (llvm::SmallVectorImpl<char> &path) to deal with the cases where llvm::sys::path::home_directory() returns false by digging a little further on unix systems and setting "HOME" in the environment so that subsequent calls to llvm::sys::path::home_directory() will succeed.
I also added a test to ensure we don't regress. <rdar://problem/25342377> Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py Modified: lldb/trunk/source/Host/common/FileSpec.cpp Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py?rev=266832&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/llvm/TestLLVM.py Tue Apr 19 18:04:35 2016 @@ -0,0 +1,60 @@ +""" +Test lldb 'commands regex' command which allows the user to create a regular expression command. +""" + +from __future__ import print_function + + + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class TestHomeDirectory(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=["windows"]) + @no_debug_info_test + def test_tilde_home_directory(self): + """Test that we can resolve "~/" in paths correctly. + When a path starts with "~/", we use llvm::sys::path::home_directory() to + resolve the home directory. This currently relies on "HOME" being set in the + environment. While this is usually set, we can't rely upon that. We might + eventually get a fix into llvm::sys::path::home_directory() so it doesn't rely + on having to have an environment variable set, but until then we have work around + code in FileSpec::ResolveUsername (llvm::SmallVectorImpl<char> &path) to ensure + this always works. This test tests that we get the correct answer for with and + without "HOME" being set in the environment.""" + import pexpect + prompt = "(lldb) " + + child = pexpect.spawn('%s --no-use-colors %s' % (lldbtest_config.lldbExec, self.lldbOption)) + # Turn on logging for what the child sends back. + if self.TraceOn(): + child.logfile_read = sys.stdout + # So that the spawned lldb session gets shutdown durng teardown. + self.child = child + + # Resolve "~/." to the full path of our home directory + "/." + if 'HOME' in os.environ: + home_dir = os.environ['HOME'] + if self.TraceOn(): + print("home directory is: '%s'" % (home_dir)) + if os.path.exists(home_dir): + home_dir_slash_dot = home_dir + '/.' + child.expect_exact(prompt) + child.sendline('''script str(lldb.SBFileSpec("~/.", True))''') + child.expect_exact(home_dir) + child.expect_exact(prompt) + child.sendline('''script import os; os.unsetenv('HOME'); str(lldb.SBFileSpec("~/", True))'''); + child.expect_exact(home_dir) + child.expect_exact(prompt) + elif self.TraceOn(): + print('''home directory "%s" doesn't exist, skipping home directory test''' % (home_dir)) + elif self.TraceOn(): + print('"HOME" not in environment, skipping home directory test') + + child.sendline('quit') Modified: lldb/trunk/source/Host/common/FileSpec.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=266832&r1=266831&r2=266832&view=diff ============================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp (original) +++ lldb/trunk/source/Host/common/FileSpec.cpp Tue Apr 19 18:04:35 2016 @@ -185,8 +185,22 @@ FileSpec::ResolveUsername (llvm::SmallVe { // A path of ~/ resolves to the current user's home dir llvm::SmallString<64> home_dir; + // llvm::sys::path::home_directory() only checks if "HOME" is set in the + // environment and does nothing else to locate the user home directory if (!llvm::sys::path::home_directory(home_dir)) - return; + { + struct passwd *pw = getpwuid(getuid()); + if (pw && pw->pw_dir && pw->pw_dir[0]) + { + // Update our environemnt so llvm::sys::path::home_directory() works next time + setenv("HOME", pw->pw_dir, 0); + home_dir.assign(llvm::StringRef(pw->pw_dir)); + } + else + { + return; + } + } // Overwrite the ~ with the first character of the homedir, and insert // the rest. This way we only trigger one move, whereas an insert _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits