[Lldb-commits] [lldb] r373644 - [Host] Return the user's shell from GetDefaultShell

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 3 11:29:01 PDT 2019


Author: jdevlieghere
Date: Thu Oct  3 11:29:01 2019
New Revision: 373644

URL: http://llvm.org/viewvc/llvm-project?rev=373644&view=rev
Log:
[Host] Return the user's shell from GetDefaultShell

LLDB handles shell expansion by running lldb-argdumper under a shell.
Currently, this is always /bin/sh on POSIX. This potentially leads to
different behavior between lldb and the user's current shell. Here's an
example of different expansions between shells:

$ /bin/bash -c 'echo -config={Options:[{key:foo_key,value:foo_value}]}'
-config={Options:[key:foo_key]} -config={Options:[value:foo_value]}

$ /bin/zsh -c 'echo -config={Options:[{key:foo_key,value:foo_value}]}'
zsh:1: no matches found: -config={Options:[key:foo_key]}

$ /bin/sh -c 'echo -config={Options:[{key:foo_key,value:foo_value}]}'
-config={Options:[key:foo_key]} -config={Options:[value:foo_value]}

$ /bin/fish -c 'echo -config={Options:[{key:foo_key,value:foo_value}]}'
-config=Options:[key:foo_key] -config=Options:[value:foo_value]

To reduce surprises, this patch returns the user's current shell. It
first looks at the SHELL environment variable. If that isn't set, it'll
ask for the user's default shell. Only if that fails, we'll fallback to
/bin/sh, which should always be available.

Differential revision: https://reviews.llvm.org/D68316

Added:
    lldb/trunk/lit/Host/
    lldb/trunk/lit/Host/Inputs/
    lldb/trunk/lit/Host/Inputs/simple.c
    lldb/trunk/lit/Host/TestCustomShell.test
Modified:
    lldb/trunk/source/Host/posix/HostInfoPosix.cpp

Added: lldb/trunk/lit/Host/Inputs/simple.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Host/Inputs/simple.c?rev=373644&view=auto
==============================================================================
--- lldb/trunk/lit/Host/Inputs/simple.c (added)
+++ lldb/trunk/lit/Host/Inputs/simple.c Thu Oct  3 11:29:01 2019
@@ -0,0 +1 @@
+int main(int argc, char const *argv[]) { return 0; }

Added: lldb/trunk/lit/Host/TestCustomShell.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Host/TestCustomShell.test?rev=373644&view=auto
==============================================================================
--- lldb/trunk/lit/Host/TestCustomShell.test (added)
+++ lldb/trunk/lit/Host/TestCustomShell.test Thu Oct  3 11:29:01 2019
@@ -0,0 +1,8 @@
+# UNSUPPORTED: system-windows
+
+# RUN: %clang %S/Inputs/simple.c -g -o %t.out
+# RUN: SHELL=bogus %lldb %t.out -b -o 'run' 2>&1 | FileCheck %s --check-prefix ERROR
+# RUN: env -i %lldb %t.out -b -o 'run' 2>&1 | FileCheck %s
+
+# ERROR: error: shell expansion failed
+# CHECK-NOT: error: shell expansion failed

Modified: lldb/trunk/source/Host/posix/HostInfoPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/HostInfoPosix.cpp?rev=373644&r1=373643&r2=373644&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/HostInfoPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/HostInfoPosix.cpp Thu Oct  3 11:29:01 2019
@@ -52,15 +52,19 @@ protected:
 };
 } // namespace
 
-llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {
+struct PasswdEntry {
+  std::string username;
+  std::string shell;
+};
+
+static llvm::Optional<PasswdEntry> GetPassword(id_t uid) {
 #ifdef USE_GETPWUID
   // getpwuid_r is missing from android-9
-  // UserIDResolver provides some thread safety by making sure noone calls this
-  // function concurrently, but using getpwuid is ultimately not thread-safe as
-  // we don't know who else might be calling it.
-  struct passwd *user_info_ptr = ::getpwuid(uid);
-  if (user_info_ptr)
-    return std::string(user_info_ptr->pw_name);
+  // The caller should provide some thread safety by making sure no one calls
+  // this function concurrently, because using getpwuid is ultimately not
+  // thread-safe as we don't know who else might be calling it.
+  if (auto *user_info_ptr = ::getpwuid(uid))
+    return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};
 #else
   struct passwd user_info;
   struct passwd *user_info_ptr = &user_info;
@@ -69,12 +73,18 @@ llvm::Optional<std::string> PosixUserIDR
   if (::getpwuid_r(uid, &user_info, user_buffer, user_buffer_size,
                    &user_info_ptr) == 0 &&
       user_info_ptr) {
-    return std::string(user_info_ptr->pw_name);
+    return PasswdEntry{user_info_ptr->pw_name, user_info_ptr->pw_shell};
   }
 #endif
   return llvm::None;
 }
 
+llvm::Optional<std::string> PosixUserIDResolver::DoGetUserName(id_t uid) {
+  if (llvm::Optional<PasswdEntry> password = GetPassword(uid))
+    return password->username;
+  return llvm::None;
+}
+
 llvm::Optional<std::string> PosixUserIDResolver::DoGetGroupName(id_t gid) {
 #ifndef __ANDROID__
   char group_buffer[PATH_MAX];
@@ -113,7 +123,13 @@ uint32_t HostInfoPosix::GetEffectiveUser
 
 uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); }
 
-FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); }
+FileSpec HostInfoPosix::GetDefaultShell() {
+  if (const char *v = ::getenv("SHELL"))
+    return FileSpec(v);
+  if (llvm::Optional<PasswdEntry> password = GetPassword(::geteuid()))
+    return FileSpec(password->shell);
+  return FileSpec("/bin/sh");
+}
 
 bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {
   return ComputePathRelativeToLibrary(file_spec, "/bin");




More information about the lldb-commits mailing list