From: Jonas Devlieghere Date: Thu, 3 Oct 2019 18:29:01 +0000 (+0000) Subject: [Host] Return the user's shell from GetDefaultShell X-Git-Tag: llvmorg-11-init~7596 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f149ea8bb5ddd488bc20f8e0de3dbfb7c4d4bf12;p=platform%2Fupstream%2Fllvm.git [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 llvm-svn: 373644 --- diff --git a/lldb/lit/Host/Inputs/simple.c b/lldb/lit/Host/Inputs/simple.c new file mode 100644 index 0000000..06e216a --- /dev/null +++ b/lldb/lit/Host/Inputs/simple.c @@ -0,0 +1 @@ +int main(int argc, char const *argv[]) { return 0; } diff --git a/lldb/lit/Host/TestCustomShell.test b/lldb/lit/Host/TestCustomShell.test new file mode 100644 index 0000000..58cda2e --- /dev/null +++ b/lldb/lit/Host/TestCustomShell.test @@ -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 diff --git a/lldb/source/Host/posix/HostInfoPosix.cpp b/lldb/source/Host/posix/HostInfoPosix.cpp index e7d0dee..76f77e3 100644 --- a/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/lldb/source/Host/posix/HostInfoPosix.cpp @@ -52,15 +52,19 @@ protected: }; } // namespace -llvm::Optional PosixUserIDResolver::DoGetUserName(id_t uid) { +struct PasswdEntry { + std::string username; + std::string shell; +}; + +static llvm::Optional 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 PosixUserIDResolver::DoGetUserName(id_t uid) { 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 PosixUserIDResolver::DoGetUserName(id_t uid) { + if (llvm::Optional password = GetPassword(uid)) + return password->username; + return llvm::None; +} + llvm::Optional PosixUserIDResolver::DoGetGroupName(id_t gid) { #ifndef __ANDROID__ char group_buffer[PATH_MAX]; @@ -113,7 +123,13 @@ uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); } 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 password = GetPassword(::geteuid())) + return FileSpec(password->shell); + return FileSpec("/bin/sh"); +} bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) { return ComputePathRelativeToLibrary(file_spec, "/bin");