From 0e1d1ed246d1927f54a2160ab4a2a863793a6870 Mon Sep 17 00:00:00 2001 From: Grant Paul Date: Wed, 16 Nov 2016 03:51:04 -0800 Subject: [PATCH] Add Windows support for user and group info; separate from process. Separate from the process as it is only vaguely related and adding unused user information to in-memory process contexts was extra code. Windows support uses the SID as the user ID, as it matches the idea of an identifer uniquely identifying a user or a group. --- Libraries/builtin/Tests/test_copy.cpp | 6 +- Libraries/builtin/Tests/test_copyPlist.cpp | 6 +- Libraries/builtin/Tests/test_copyStrings.cpp | 12 +- .../Headers/pbxbuild/Build/Environment.h | 2 + .../pbxbuild/Sources/Build/Environment.cpp | 9 +- Libraries/pbxproj/Tools/dump_xcodeproj.cpp | 12 +- .../Headers/pbxsetting/DefaultSettings.h | 5 +- .../pbxsetting/Sources/DefaultSettings.cpp | 15 +- Libraries/process/CMakeLists.txt | 3 + Libraries/process/Headers/process/Context.h | 26 -- .../process/Headers/process/DefaultContext.h | 9 - .../process/Headers/process/DefaultUser.h | 38 +++ .../process/Headers/process/MemoryContext.h | 33 +-- .../process/Headers/process/MemoryUser.h | 60 ++++ Libraries/process/Headers/process/User.h | 57 ++++ Libraries/process/Sources/Context.cpp | 6 - Libraries/process/Sources/DefaultContext.cpp | 74 +---- Libraries/process/Sources/DefaultLauncher.cpp | 14 - Libraries/process/Sources/DefaultUser.cpp | 280 ++++++++++++++++++ Libraries/process/Sources/MemoryContext.cpp | 20 +- Libraries/process/Sources/MemoryUser.cpp | 42 +++ Libraries/process/Sources/User.cpp | 23 ++ .../xcdriver/Headers/xcdriver/BuildAction.h | 3 +- Libraries/xcdriver/Headers/xcdriver/Driver.h | 3 +- .../xcdriver/Headers/xcdriver/FindAction.h | 3 +- .../xcdriver/Headers/xcdriver/ListAction.h | 3 +- .../xcdriver/ShowBuildSettingsAction.h | 3 +- .../Headers/xcdriver/ShowSDKsAction.h | 3 +- .../xcdriver/Headers/xcdriver/VersionAction.h | 3 +- Libraries/xcdriver/Sources/BuildAction.cpp | 6 +- Libraries/xcdriver/Sources/Driver.cpp | 14 +- Libraries/xcdriver/Sources/FindAction.cpp | 6 +- Libraries/xcdriver/Sources/ListAction.cpp | 7 +- .../Sources/ShowBuildSettingsAction.cpp | 7 +- Libraries/xcdriver/Sources/ShowSDKsAction.cpp | 6 +- Libraries/xcdriver/Sources/VersionAction.cpp | 6 +- Libraries/xcdriver/Tools/xcbuild.cpp | 4 +- .../Headers/xcexecution/Executor.h | 2 + .../Headers/xcexecution/NinjaExecutor.h | 1 + .../Headers/xcexecution/SimpleExecutor.h | 1 + .../xcexecution/Sources/NinjaExecutor.cpp | 11 +- .../xcexecution/Sources/SimpleExecutor.cpp | 16 +- .../xcexecution/Tests/test_SimpleExecutor.cpp | 6 +- Libraries/xcsdk/Headers/xcsdk/Configuration.h | 2 + Libraries/xcsdk/Headers/xcsdk/Environment.h | 2 + Libraries/xcsdk/Sources/Configuration.cpp | 5 +- Libraries/xcsdk/Sources/Environment.cpp | 5 +- Libraries/xcsdk/Tools/xcode-select.cpp | 5 +- Libraries/xcsdk/Tools/xcrun.cpp | 17 +- .../xcworkspace/Tools/dump_xcworkspace.cpp | 7 +- 50 files changed, 625 insertions(+), 284 deletions(-) create mode 100644 Libraries/process/Headers/process/DefaultUser.h create mode 100644 Libraries/process/Headers/process/MemoryUser.h create mode 100644 Libraries/process/Headers/process/User.h create mode 100644 Libraries/process/Sources/DefaultUser.cpp create mode 100644 Libraries/process/Sources/MemoryUser.cpp create mode 100644 Libraries/process/Sources/User.cpp diff --git a/Libraries/builtin/Tests/test_copy.cpp b/Libraries/builtin/Tests/test_copy.cpp index be5dc8c0..6bd38c23 100644 --- a/Libraries/builtin/Tests/test_copy.cpp +++ b/Libraries/builtin/Tests/test_copy.cpp @@ -34,11 +34,7 @@ Process(std::string const &executable, std::vector const &arguments executable, "/", arguments, - std::unordered_map(), - 0, - 0, - "root", - "wheel"); + std::unordered_map()); } TEST(copy, Name) diff --git a/Libraries/builtin/Tests/test_copyPlist.cpp b/Libraries/builtin/Tests/test_copyPlist.cpp index 3a7071bc..521c9c23 100644 --- a/Libraries/builtin/Tests/test_copyPlist.cpp +++ b/Libraries/builtin/Tests/test_copyPlist.cpp @@ -65,11 +65,7 @@ TEST(copyPlist, CopyMultiple) "--outdir", "output", "--convert", "ascii1", }, - std::unordered_map(), - 0, - 0, - "root", - "wheel"); + std::unordered_map()); EXPECT_EQ(0, driver.run(&processContext, &filesystem)); contents.clear(); diff --git a/Libraries/builtin/Tests/test_copyStrings.cpp b/Libraries/builtin/Tests/test_copyStrings.cpp index 36caf99d..604fe7d2 100644 --- a/Libraries/builtin/Tests/test_copyStrings.cpp +++ b/Libraries/builtin/Tests/test_copyStrings.cpp @@ -47,11 +47,7 @@ TEST(copyStrings, CopyMultiple) "--outdir", "output", "--outputencoding", "utf-8", }, - std::unordered_map(), - 0, - 0, - "root", - "wheel"); + std::unordered_map()); EXPECT_EQ(0, driver.run(&processContext, &filesystem)); contents.clear(); @@ -93,11 +89,7 @@ TEST(copyStrings, InputOutputEncoding) "--inputencoding", entry1.first, "--outputencoding", entry2.first, }, - std::unordered_map(), - 0, - 0, - "root", - "wheel"); + std::unordered_map()); EXPECT_EQ(0, driver.run(&processContext, &filesystem)); std::vector contents; diff --git a/Libraries/pbxbuild/Headers/pbxbuild/Build/Environment.h b/Libraries/pbxbuild/Headers/pbxbuild/Build/Environment.h index 481cd7b9..e83c7bb6 100644 --- a/Libraries/pbxbuild/Headers/pbxbuild/Build/Environment.h +++ b/Libraries/pbxbuild/Headers/pbxbuild/Build/Environment.h @@ -18,6 +18,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace pbxbuild { namespace Build { @@ -73,6 +74,7 @@ public: */ static ext::optional Default( + process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem); }; diff --git a/Libraries/pbxbuild/Sources/Build/Environment.cpp b/Libraries/pbxbuild/Sources/Build/Environment.cpp index a80e6882..106b7293 100644 --- a/Libraries/pbxbuild/Sources/Build/Environment.cpp +++ b/Libraries/pbxbuild/Sources/Build/Environment.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace Build = pbxbuild::Build; @@ -32,9 +33,9 @@ Environment( } ext::optional Build::Environment:: -Default(process::Context const *processContext, Filesystem const *filesystem) +Default(process::User const *user, process::Context const *processContext, Filesystem const *filesystem) { - ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem); + ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(user, processContext, filesystem); if (!developerRoot) { fprintf(stderr, "error: couldn't find developer dir\n"); return ext::nullopt; @@ -62,7 +63,7 @@ Default(process::Context const *processContext, Filesystem const *filesystem) */ specManager->registerDomains(filesystem, pbxspec::Manager::DefaultDomains(*developerRoot)); - auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(processContext)); + auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(user, processContext)); auto sdkManager = xcsdk::SDK::Manager::Open(filesystem, *developerRoot, configuration); if (sdkManager == nullptr) { fprintf(stderr, "error: couldn't create SDK manager\n"); @@ -92,7 +93,7 @@ Default(process::Context const *processContext, Filesystem const *filesystem) pbxsetting::Environment baseEnvironment; baseEnvironment.insertBack(buildSystem->defaultSettings(), true); baseEnvironment.insertBack(sdkManager->computedSettings(), false); - std::vector defaultLevels = pbxsetting::DefaultSettings::Levels(processContext); + std::vector defaultLevels = pbxsetting::DefaultSettings::Levels(user, processContext); for (pbxsetting::Level const &level : defaultLevels) { baseEnvironment.insertBack(level, false); } diff --git a/Libraries/pbxproj/Tools/dump_xcodeproj.cpp b/Libraries/pbxproj/Tools/dump_xcodeproj.cpp index c2989df5..3e64ef12 100644 --- a/Libraries/pbxproj/Tools/dump_xcodeproj.cpp +++ b/Libraries/pbxproj/Tools/dump_xcodeproj.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include @@ -185,14 +187,14 @@ GetHeaderFilePaths(PBX::Project::shared_ptr const &project, } void -CompleteDump(process::Context const *processContext, Filesystem const *filesystem, PBX::Project::shared_ptr const &project) +CompleteDump(process::User const *user, Filesystem const *filesystem, PBX::Project::shared_ptr const &project) { printf("Project File: %s\n", project->projectFile().c_str()); printf("Base Path: %s\n", project->basePath().c_str()); printf("Name: %s\n", project->name().c_str()); printf("Schemes:\n"); - xcscheme::SchemeGroup::shared_ptr group = xcscheme::SchemeGroup::Open(filesystem, processContext->userName(), project->basePath(), project->projectFile(), project->name()); + xcscheme::SchemeGroup::shared_ptr group = xcscheme::SchemeGroup::Open(filesystem, user->userName(), project->basePath(), project->projectFile(), project->name()); for (auto &I : group->schemes()) { printf("\t%s [%s]%s\n", I->name().c_str(), I->shared() ? "Shared" : I->owner().c_str(), @@ -400,7 +402,7 @@ int main(int argc, char **argv) { DefaultFilesystem filesystem = DefaultFilesystem(); - process::DefaultContext processContext = process::DefaultContext(); + process::DefaultUser user = process::DefaultUser(); if (argc < 2) { fprintf(stderr, "usage: %s filename.xcodeproj\n", argv[0]); @@ -414,7 +416,7 @@ main(int argc, char **argv) return -1; } - CompleteDump(&processContext, &filesystem, project); + CompleteDump(&user, &filesystem, project); printf("Information about project \"%s\":\n", project->name().c_str()); @@ -442,7 +444,7 @@ main(int argc, char **argv) } printf("\n"); - xcscheme::SchemeGroup::shared_ptr group = xcscheme::SchemeGroup::Open(&filesystem, processContext.userName(), project->basePath(), project->projectFile(), project->name()); + xcscheme::SchemeGroup::shared_ptr group = xcscheme::SchemeGroup::Open(&filesystem, user.userName(), project->basePath(), project->projectFile(), project->name()); if (!group->schemes().empty()) { printf("%4sSchemes:\n", ""); for (auto scheme : group->schemes()) { diff --git a/Libraries/pbxsetting/Headers/pbxsetting/DefaultSettings.h b/Libraries/pbxsetting/Headers/pbxsetting/DefaultSettings.h index a03e7840..42da5563 100644 --- a/Libraries/pbxsetting/Headers/pbxsetting/DefaultSettings.h +++ b/Libraries/pbxsetting/Headers/pbxsetting/DefaultSettings.h @@ -16,6 +16,7 @@ #include namespace process { class Context; } +namespace process { class User; } namespace pbxsetting { @@ -30,7 +31,7 @@ private: public: static Level - Environment(process::Context const *processContext); + Environment(process::User const *user, process::Context const *processContext); static Level Internal(void); static Level @@ -47,7 +48,7 @@ public: * All of the default setting levels, in order. */ static std::vector - Levels(process::Context const *processContext); + Levels(process::User const *user, process::Context const *processContext); }; } diff --git a/Libraries/pbxsetting/Sources/DefaultSettings.cpp b/Libraries/pbxsetting/Sources/DefaultSettings.cpp index f58f5c8f..969a57e5 100644 --- a/Libraries/pbxsetting/Sources/DefaultSettings.cpp +++ b/Libraries/pbxsetting/Sources/DefaultSettings.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -25,7 +26,7 @@ using pbxsetting::Type; using libutil::FSUtil; Level DefaultSettings:: -Environment(process::Context const *processContext) +Environment(process::User const *user, process::Context const *processContext) { std::vector settings; @@ -37,10 +38,10 @@ Environment(process::Context const *processContext) } } - settings.push_back(Setting::Create("UID", Type::FormatInteger(processContext->userID()))); - settings.push_back(Setting::Create("USER", processContext->userName())); - settings.push_back(Setting::Create("GID", Type::FormatInteger(processContext->groupID()))); - settings.push_back(Setting::Create("GROUP", processContext->groupName())); + settings.push_back(Setting::Create("UID", user->userID())); + settings.push_back(Setting::Create("USER", user->userName())); + settings.push_back(Setting::Create("GID", user->groupID())); + settings.push_back(Setting::Create("GROUP", user->groupName())); settings.push_back(Setting::Parse("USER_APPS_DIR", "$(HOME)/Applications")); settings.push_back(Setting::Parse("USER_LIBRARY_DIR", "$(HOME)/Library")); @@ -172,10 +173,10 @@ Build(void) } std::vector DefaultSettings:: -Levels(process::Context const *processContext) +Levels(process::User const *user, process::Context const *processContext) { return { - Environment(processContext), + Environment(user, processContext), Internal(), Local(), System(), diff --git a/Libraries/process/CMakeLists.txt b/Libraries/process/CMakeLists.txt index 39309206..79173177 100644 --- a/Libraries/process/CMakeLists.txt +++ b/Libraries/process/CMakeLists.txt @@ -14,6 +14,9 @@ add_library(process Sources/Launcher.cpp Sources/DefaultLauncher.cpp Sources/MemoryLauncher.cpp + Sources/User.cpp + Sources/DefaultUser.cpp + Sources/MemoryUser.cpp ) target_link_libraries(process PUBLIC ext util) diff --git a/Libraries/process/Headers/process/Context.h b/Libraries/process/Headers/process/Context.h index 14246156..dd8cfa22 100644 --- a/Libraries/process/Headers/process/Context.h +++ b/Libraries/process/Headers/process/Context.h @@ -52,37 +52,11 @@ public: */ virtual ext::optional environmentVariable(std::string const &variable) const = 0; -public: - /* - * Active user ID. - */ - virtual int32_t userID() const = 0; - - /* - * Active group ID. - */ - virtual int32_t groupID() const = 0; - - /* - * Active user name. - */ - virtual std::string const &userName() const = 0; - - /* - * Active group name. - */ - virtual std::string const &groupName() const = 0; - public: /* * The default environment search paths. */ std::vector executableSearchPaths() const; - - /* - * The home directory from the environment. - */ - virtual ext::optional userHomeDirectory() const; }; } diff --git a/Libraries/process/Headers/process/DefaultContext.h b/Libraries/process/Headers/process/DefaultContext.h index 0b3eb09f..d472a729 100644 --- a/Libraries/process/Headers/process/DefaultContext.h +++ b/Libraries/process/Headers/process/DefaultContext.h @@ -31,15 +31,6 @@ public: virtual std::vector const &commandLineArguments() const; virtual std::unordered_map const &environmentVariables() const; virtual ext::optional environmentVariable(std::string const &variable) const; - -public: - virtual int32_t userID() const; - virtual int32_t groupID() const; - virtual std::string const &userName() const; - virtual std::string const &groupName() const; - -public: - virtual ext::optional userHomeDirectory() const; }; } diff --git a/Libraries/process/Headers/process/DefaultUser.h b/Libraries/process/Headers/process/DefaultUser.h new file mode 100644 index 00000000..7786e8ae --- /dev/null +++ b/Libraries/process/Headers/process/DefaultUser.h @@ -0,0 +1,38 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __process_DefaultUser_h +#define __process_DefaultUser_h + +#include + +namespace process { + +/* + * The user for the current process. Generally, this should only be + * created in `main()` and passed down to anywhere else that needs it. + */ +class DefaultUser : public User { +public: + explicit DefaultUser(); + virtual ~DefaultUser(); + +public: + virtual std::string const &userID() const; + virtual std::string const &groupID() const; + virtual std::string const &userName() const; + virtual std::string const &groupName() const; + +public: + virtual ext::optional userHomeDirectory() const; +}; + +} + +#endif // !__process_DefaultUser_h diff --git a/Libraries/process/Headers/process/MemoryContext.h b/Libraries/process/Headers/process/MemoryContext.h index 6fad5336..739f369e 100644 --- a/Libraries/process/Headers/process/MemoryContext.h +++ b/Libraries/process/Headers/process/MemoryContext.h @@ -26,22 +26,12 @@ private: std::vector _commandLineArguments; std::unordered_map _environmentVariables; -private: - int32_t _userID; - int32_t _groupID; - std::string _userName; - std::string _groupName; - public: MemoryContext( std::string const &executablePath, std::string const ¤tDirectory, std::vector const &commandLineArguments, - std::unordered_map const &environmentVariables, - int32_t userID, - int32_t groupID, - std::string const &userName, - std::string const &groupName); + std::unordered_map const &environmentVariables); explicit MemoryContext(Context const *context); virtual ~MemoryContext(); @@ -68,27 +58,6 @@ public: { return _environmentVariables; } virtual ext::optional environmentVariable(std::string const &variable) const; - -public: - virtual int32_t userID() const - { return _userID; } - int32_t &userID() - { return _userID; } - - virtual int32_t groupID() const - { return _groupID; } - int32_t &groupID() - { return _groupID; } - - virtual std::string const &userName() const - { return _userName; } - std::string &userName() - { return _userName; } - - virtual std::string const &groupName() const - { return _groupName; } - std::string &groupName() - { return _groupName; } }; } diff --git a/Libraries/process/Headers/process/MemoryUser.h b/Libraries/process/Headers/process/MemoryUser.h new file mode 100644 index 00000000..5373b643 --- /dev/null +++ b/Libraries/process/Headers/process/MemoryUser.h @@ -0,0 +1,60 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __process_MemoryUser_h +#define __process_MemoryUser_h + +#include + +namespace process { + +/* + * A process user with arbitrary values. + */ +class MemoryUser : public User { +private: + std::string _userID; + std::string _groupID; + std::string _userName; + std::string _groupName; + +public: + MemoryUser( + std::string const &userID, + std::string const &groupID, + std::string const &userName, + std::string const &groupName); + explicit MemoryUser(User const *user); + virtual ~MemoryUser(); + +public: + virtual std::string const &userID() const + { return _userID; } + std::string &userID() + { return _userID; } + + virtual std::string const &groupID() const + { return _groupID; } + std::string &groupID() + { return _groupID; } + + virtual std::string const &userName() const + { return _userName; } + std::string &userName() + { return _userName; } + + virtual std::string const &groupName() const + { return _groupName; } + std::string &groupName() + { return _groupName; } +}; + +} + +#endif // !__process_MemoryUser_h diff --git a/Libraries/process/Headers/process/User.h b/Libraries/process/Headers/process/User.h new file mode 100644 index 00000000..6d255484 --- /dev/null +++ b/Libraries/process/Headers/process/User.h @@ -0,0 +1,57 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __process_User_h +#define __process_User_h + +#include +#include + +namespace process { + +/* + * The information passed into a launched process. + */ +class User { +protected: + User(); + virtual ~User(); + +public: + /* + * Active user ID. + */ + virtual std::string const &userID() const = 0; + + /* + * Active group ID. + */ + virtual std::string const &groupID() const = 0; + + /* + * Active user name. + */ + virtual std::string const &userName() const = 0; + + /* + * Active group name. + */ + virtual std::string const &groupName() const = 0; + +public: + + /* + * The home directory from the environment. + */ + virtual ext::optional userHomeDirectory() const = 0; +}; + +} + +#endif // !__process_User_h diff --git a/Libraries/process/Sources/Context.cpp b/Libraries/process/Sources/Context.cpp index 0e8b3a60..fd21f299 100644 --- a/Libraries/process/Sources/Context.cpp +++ b/Libraries/process/Sources/Context.cpp @@ -47,9 +47,3 @@ executableSearchPaths() const return paths; } -ext::optional Context:: -userHomeDirectory() const -{ - return environmentVariable("HOME"); -} - diff --git a/Libraries/process/Sources/DefaultContext.cpp b/Libraries/process/Sources/DefaultContext.cpp index 1397a84e..2169b35f 100644 --- a/Libraries/process/Sources/DefaultContext.cpp +++ b/Libraries/process/Sources/DefaultContext.cpp @@ -16,8 +16,9 @@ #include #include -#include -#include +#if _WIN32 +#include +#else #include #include #include @@ -187,72 +188,3 @@ environmentVariables() const return *environment; } - -std::string const &DefaultContext:: -userName() const -{ - static std::string const *userName = nullptr; - - std::once_flag flag; - std::call_once(flag, []{ - if (struct passwd const *pw = ::getpwuid(::getuid())) { - if (pw->pw_name != nullptr) { - userName = new std::string(pw->pw_name); - } - } - - if (userName == nullptr) { - std::ostringstream os; - os << ::getuid(); - userName = new std::string(os.str()); - } - }); - - return *userName; -} - -std::string const &DefaultContext:: -groupName() const -{ - static std::string const *groupName = nullptr; - - std::once_flag flag; - std::call_once(flag, []{ - if (struct group const *gr = ::getgrgid(::getgid())) { - if (gr->gr_name != nullptr) { - groupName = new std::string(gr->gr_name); - } - } - - if (groupName == nullptr) { - std::ostringstream os; - os << ::getgid(); - groupName = new std::string(os.str()); - } - }); - - return *groupName; -} - -int32_t DefaultContext:: -userID() const -{ - return ::getuid(); -} - -int32_t DefaultContext:: -groupID() const -{ - return ::getgid(); -} - -ext::optional DefaultContext:: -userHomeDirectory() const -{ - if (ext::optional value = Context::userHomeDirectory()) { - return value; - } else { - char *home = ::getpwuid(::getuid())->pw_dir; - return std::string(home); - } -} diff --git a/Libraries/process/Sources/DefaultLauncher.cpp b/Libraries/process/Sources/DefaultLauncher.cpp index 7e03de6c..8e172635 100644 --- a/Libraries/process/Sources/DefaultLauncher.cpp +++ b/Libraries/process/Sources/DefaultLauncher.cpp @@ -188,10 +188,6 @@ launch(Filesystem *filesystem, Context const *context) execEnv.push_back(nullptr); char *const *cExecEnv = const_cast(execEnv.data()); - /* Compute user. */ - uid_t uid = context->userID(); - gid_t gid = context->groupID(); - /* Setup parent-child stdout/stderr pipe. */ int pfd[2]; bool pipe_setup_success = true; @@ -232,16 +228,6 @@ launch(Filesystem *filesystem, Context const *context) ::_exit(1); } - if (::setuid(uid) == -1) { - ::perror("setuid"); - ::_exit(1); - } - - if (::setgid(gid) == -1) { - ::perror("setgid"); - ::_exit(1); - } - ::execve(cPath, cExecArgs, cExecEnv); ::_exit(-1); diff --git a/Libraries/process/Sources/DefaultUser.cpp b/Libraries/process/Sources/DefaultUser.cpp new file mode 100644 index 00000000..f4738ffc --- /dev/null +++ b/Libraries/process/Sources/DefaultUser.cpp @@ -0,0 +1,280 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#include + +#include +#include +#include +#include + +#if _WIN32 +#include +#include +#include +#else +#include +#include +#include +#endif + +using process::DefaultUser; + +#if _WIN32 +using WideString = std::basic_string::type>::type>; + +static std::string +WideStringToString(WideString const &str) +{ + int size = WideCharToMultiByte(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0, NULL, NULL); + std::string multi = std::string(); + multi.resize(size); + WideCharToMultiByte(CP_UTF8, 0, str.data(), (int)str.size(), &multi[0], size, NULL, NULL); + return multi; +} +#endif + +DefaultUser:: +DefaultUser() : + User() +{ +} + +DefaultUser:: +~DefaultUser() +{ +} + +#if _WIN32 +template +static T * +CreateToken(TOKEN_INFORMATION_CLASS type) +{ + HANDLE process = nullptr; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process) == 0) { + return nullptr; + } + + DWORD size = 0; + if (!GetTokenInformation(process, type, nullptr, 0, &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + return nullptr; + } + + T *token = static_cast(malloc(size)); + memset(token, 0, size); + if (!GetTokenInformation(process, type, token, size, &size)) { + return nullptr; + } + + if (!CloseHandle(process)) { + return nullptr; + } + + return token; +} +#endif + +std::string const &DefaultUser:: +userID() const +{ + static std::string const *userID = nullptr; + + static std::once_flag flag; + std::call_once(flag, []{ +#if _WIN32 + TOKEN_USER *token = CreateToken(TokenUser); + if (token == nullptr) { + abort(); + } + + LPWSTR string = nullptr; + if (!ConvertSidToStringSidW(token->User.Sid, &string)) { + abort(); + } + + WideString wide = WideString(string); + userID = new std::string(WideStringToString(wide)); + + LocalFree(string); + free(token); +#else + std::ostringstream os; + os << ::getuid(); + userID = new std::string(os.str()); +#endif + }); + + return *userID; +} + +std::string const &DefaultUser:: +groupID() const +{ + static std::string const *groupID = nullptr; + + static std::once_flag flag; + std::call_once(flag, []{ +#if _WIN32 + TOKEN_PRIMARY_GROUP *token = CreateToken(TokenPrimaryGroup); + if (token == nullptr) { + abort(); + } + + LPWSTR string = nullptr; + if (!ConvertSidToStringSidW(token->PrimaryGroup, &string)) { + abort(); + } + + WideString wide = WideString(string); + groupID = new std::string(WideStringToString(wide)); + + LocalFree(string); + free(token); +#else + std::ostringstream os; + os << ::getgid(); + groupID = new std::string(os.str()); +#endif + }); + + return *groupID; +} + +std::string const &DefaultUser:: +userName() const +{ + static std::string const *userName = nullptr; + + static std::once_flag flag; + std::call_once(flag, []{ +#if _WIN32 + TOKEN_USER *token = CreateToken(TokenUser); + if (token == nullptr) { + abort(); + } + + DWORD size = 0; + DWORD dsize = 0; + SID_NAME_USE use; + if (!LookupAccountSidW(nullptr, token->User.Sid, nullptr, &size, nullptr, &dsize, &use) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + abort(); + } + + WideString name; + name.resize(size); + WideString domain; + name.resize(dsize); + if (!LookupAccountSidW(nullptr, token->User.Sid, &name[0], &size, &domain[0], &dsize, &use)) { + abort(); + } + + userName = new std::string(WideStringToString(name)); + + free(token); +#else + if (struct passwd const *pw = ::getpwuid(::getuid())) { + if (pw->pw_name != nullptr) { + userName = new std::string(pw->pw_name); + } + } + + if (userName == nullptr) { + std::ostringstream os; + os << ::getuid(); + userName = new std::string(os.str()); + } +#endif + }); + + return *userName; +} + +std::string const &DefaultUser:: +groupName() const +{ + static std::string const *groupName = nullptr; + + static std::once_flag flag; + std::call_once(flag, []{ +#if _WIN32 + TOKEN_PRIMARY_GROUP *token = CreateToken(TokenPrimaryGroup); + if (token == nullptr) { + abort(); + } + + DWORD size = 0; + DWORD dsize = 0; + SID_NAME_USE use; + if (!LookupAccountSidW(nullptr, token->PrimaryGroup, nullptr, &size, nullptr, &dsize, &use) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + abort(); + } + + WideString name; + name.resize(size); + WideString domain; + name.resize(dsize); + if (!LookupAccountSidW(nullptr, token->PrimaryGroup, &name[0], &size, &domain[0], &dsize, &use)) { + abort(); + } + + groupName = new std::string(WideStringToString(name)); + + free(token); +#else + if (struct group const *gr = ::getgrgid(::getgid())) { + if (gr->gr_name != nullptr) { + groupName = new std::string(gr->gr_name); + } + } + + if (groupName == nullptr) { + std::ostringstream os; + os << ::getgid(); + groupName = new std::string(os.str()); + } +#endif + }); + + return *groupName; +} + +ext::optional DefaultUser:: +userHomeDirectory() const +{ +#if _WIN32 + HANDLE process = nullptr; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &process) == 0) { + return ext::nullopt; + } + + /* Size includes NUL terminator. */ + DWORD size = 0; + if (!GetUserProfileDirectoryW(process, nullptr, &size) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + CloseHandle(process); + return ext::nullopt; + } + + auto buffer = WideString(); + buffer.resize(size - 1); + if (!GetUserProfileDirectoryW(process, &buffer[0], &size)) { + CloseHandle(process); + return ext::nullopt; + } + + CloseHandle(process); + return WideStringToString(buffer); +#else + char *home = ::getpwuid(::getuid())->pw_dir; + if (home != nullptr) { + return std::string(home); + } else { + return ext::nullopt; + } +#endif +} diff --git a/Libraries/process/Sources/MemoryContext.cpp b/Libraries/process/Sources/MemoryContext.cpp index 33fb8189..948c5593 100644 --- a/Libraries/process/Sources/MemoryContext.cpp +++ b/Libraries/process/Sources/MemoryContext.cpp @@ -16,20 +16,12 @@ MemoryContext( std::string const &executablePath, std::string const ¤tDirectory, std::vector const &commandLineArguments, - std::unordered_map const &environmentVariables, - int32_t userID, - int32_t groupID, - std::string const &userName, - std::string const &groupName) : - Context (), + std::unordered_map const &environmentVariables) : + Context (), _executablePath (executablePath), _currentDirectory (currentDirectory), _commandLineArguments(commandLineArguments), - _environmentVariables(environmentVariables), - _userID (userID), - _groupID (groupID), - _userName (userName), - _groupName (groupName) + _environmentVariables(environmentVariables) { } @@ -39,11 +31,7 @@ MemoryContext(Context const *context) : context->executablePath(), context->currentDirectory(), context->commandLineArguments(), - context->environmentVariables(), - context->userID(), - context->groupID(), - context->userName(), - context->groupName()) + context->environmentVariables()) { } diff --git a/Libraries/process/Sources/MemoryUser.cpp b/Libraries/process/Sources/MemoryUser.cpp new file mode 100644 index 00000000..b8ae2d70 --- /dev/null +++ b/Libraries/process/Sources/MemoryUser.cpp @@ -0,0 +1,42 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#include + +using process::MemoryUser; + +MemoryUser:: +MemoryUser( + std::string const &userID, + std::string const &groupID, + std::string const &userName, + std::string const &groupName) : + User (), + _userID (userID), + _groupID (groupID), + _userName (userName), + _groupName(groupName) +{ +} + +MemoryUser:: +MemoryUser(User const *user) : + MemoryUser( + user->userID(), + user->groupID(), + user->userName(), + user->groupName()) +{ +} + +MemoryUser:: +~MemoryUser() +{ +} + diff --git a/Libraries/process/Sources/User.cpp b/Libraries/process/Sources/User.cpp new file mode 100644 index 00000000..73e4ec74 --- /dev/null +++ b/Libraries/process/Sources/User.cpp @@ -0,0 +1,23 @@ +/** + Copyright (c) 2015-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#include + +using process::User; + +User:: +User() +{ +} + +User:: +~User() +{ +} + diff --git a/Libraries/xcdriver/Headers/xcdriver/BuildAction.h b/Libraries/xcdriver/Headers/xcdriver/BuildAction.h index 84f580fc..087e0d27 100644 --- a/Libraries/xcdriver/Headers/xcdriver/BuildAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/BuildAction.h @@ -13,6 +13,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } namespace process { class Launcher; } +namespace process { class User; } namespace xcdriver { @@ -25,7 +26,7 @@ private: public: static int - Run(process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/Driver.h b/Libraries/xcdriver/Headers/xcdriver/Driver.h index b1ca13b0..6b42487c 100644 --- a/Libraries/xcdriver/Headers/xcdriver/Driver.h +++ b/Libraries/xcdriver/Headers/xcdriver/Driver.h @@ -13,6 +13,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } namespace process { class Launcher; } +namespace process { class User; } namespace xcdriver { @@ -23,7 +24,7 @@ private: public: static int - Run(process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem); + Run(process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/FindAction.h b/Libraries/xcdriver/Headers/xcdriver/FindAction.h index dbde956c..e2391008 100644 --- a/Libraries/xcdriver/Headers/xcdriver/FindAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/FindAction.h @@ -12,6 +12,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcdriver { @@ -24,7 +25,7 @@ private: public: static int - Run(process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/ListAction.h b/Libraries/xcdriver/Headers/xcdriver/ListAction.h index b0fb37fe..d29f2eaa 100644 --- a/Libraries/xcdriver/Headers/xcdriver/ListAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/ListAction.h @@ -12,6 +12,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcdriver { @@ -24,7 +25,7 @@ private: public: static int - Run(process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/ShowBuildSettingsAction.h b/Libraries/xcdriver/Headers/xcdriver/ShowBuildSettingsAction.h index ee276b82..9cf47339 100644 --- a/Libraries/xcdriver/Headers/xcdriver/ShowBuildSettingsAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/ShowBuildSettingsAction.h @@ -12,6 +12,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcdriver { @@ -24,7 +25,7 @@ private: public: static int - Run(process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/ShowSDKsAction.h b/Libraries/xcdriver/Headers/xcdriver/ShowSDKsAction.h index 3e2b5ff0..ca61d246 100644 --- a/Libraries/xcdriver/Headers/xcdriver/ShowSDKsAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/ShowSDKsAction.h @@ -12,6 +12,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcdriver { @@ -24,7 +25,7 @@ private: public: static int - Run(process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Headers/xcdriver/VersionAction.h b/Libraries/xcdriver/Headers/xcdriver/VersionAction.h index 3a5abdfb..0bf38847 100644 --- a/Libraries/xcdriver/Headers/xcdriver/VersionAction.h +++ b/Libraries/xcdriver/Headers/xcdriver/VersionAction.h @@ -12,6 +12,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcdriver { @@ -24,7 +25,7 @@ private: public: static int - Run(process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); + Run(process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem, Options const &options); }; } diff --git a/Libraries/xcdriver/Sources/BuildAction.cpp b/Libraries/xcdriver/Sources/BuildAction.cpp index 201df5e1..f6253cd8 100644 --- a/Libraries/xcdriver/Sources/BuildAction.cpp +++ b/Libraries/xcdriver/Sources/BuildAction.cpp @@ -116,7 +116,7 @@ VerifySupportedOptions(Options const &options) } int BuildAction:: -Run(process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem, Options const &options) { // TODO(grp): Implement these options. if (!VerifySupportedOptions(options)) { @@ -149,7 +149,7 @@ Run(process::Context const *processContext, process::Launcher *processLauncher, /* * Use the default build environment. We don't need anything custom here. */ - ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem); + ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(user, processContext, filesystem); if (!buildEnvironment) { fprintf(stderr, "error: couldn't create build environment\n"); return -1; @@ -172,7 +172,7 @@ Run(process::Context const *processContext, process::Launcher *processLauncher, /* * Perform the build! */ - bool success = executor->build(processContext, processLauncher, filesystem, *buildEnvironment, parameters); + bool success = executor->build(user, processContext, processLauncher, filesystem, *buildEnvironment, parameters); if (!success) { return 1; } diff --git a/Libraries/xcdriver/Sources/Driver.cpp b/Libraries/xcdriver/Sources/Driver.cpp index edd9b398..772290fc 100644 --- a/Libraries/xcdriver/Sources/Driver.cpp +++ b/Libraries/xcdriver/Sources/Driver.cpp @@ -41,7 +41,7 @@ Driver:: } int Driver:: -Run(process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem) +Run(process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem) { Options options; std::pair result = libutil::Options::Parse(&options, processContext->commandLineArguments()); @@ -53,13 +53,13 @@ Run(process::Context const *processContext, process::Launcher *processLauncher, Action::Type action = Action::Determine(options); switch (action) { case Action::Build: - return BuildAction::Run(processContext, processLauncher, filesystem, options); + return BuildAction::Run(user, processContext, processLauncher, filesystem, options); case Action::ShowBuildSettings: - return ShowBuildSettingsAction::Run(processContext, filesystem, options); + return ShowBuildSettingsAction::Run(user, processContext, filesystem, options); case Action::List: - return ListAction::Run(processContext, filesystem, options); + return ListAction::Run(user, processContext, filesystem, options); case Action::Version: - return VersionAction::Run(processContext, filesystem, options); + return VersionAction::Run(user, processContext, filesystem, options); case Action::Usage: return UsageAction::Run(processContext); case Action::Help: @@ -70,9 +70,9 @@ Run(process::Context const *processContext, process::Launcher *processLauncher, fprintf(stderr, "warning: check first launch not implemented\n"); break; case Action::ShowSDKs: - return ShowSDKsAction::Run(processContext, filesystem, options); + return ShowSDKsAction::Run(user, processContext, filesystem, options); case Action::Find: - return FindAction::Run(processContext, filesystem, options); + return FindAction::Run(user, processContext, filesystem, options); case Action::ExportArchive: fprintf(stderr, "warning: export archive not implemented\n"); break; diff --git a/Libraries/xcdriver/Sources/FindAction.cpp b/Libraries/xcdriver/Sources/FindAction.cpp index 7e75479e..65198fc0 100644 --- a/Libraries/xcdriver/Sources/FindAction.cpp +++ b/Libraries/xcdriver/Sources/FindAction.cpp @@ -31,15 +31,15 @@ FindAction:: } int FindAction:: -Run(process::Context const *processContext, Filesystem const *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, Filesystem const *filesystem, Options const &options) { - ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem); + ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(user, processContext, filesystem); if (!developerRoot) { fprintf(stderr, "error: unable to find developer dir\n"); return 1; } - auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(processContext)); + auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(user, processContext)); auto manager = xcsdk::SDK::Manager::Open(filesystem, *developerRoot, configuration); if (manager == nullptr) { fprintf(stderr, "error: unable to open developer directory\n"); diff --git a/Libraries/xcdriver/Sources/ListAction.cpp b/Libraries/xcdriver/Sources/ListAction.cpp index 721a79ee..fd88f15d 100644 --- a/Libraries/xcdriver/Sources/ListAction.cpp +++ b/Libraries/xcdriver/Sources/ListAction.cpp @@ -13,6 +13,7 @@ #include #include #include +#include using xcdriver::ListAction; using xcdriver::Options; @@ -29,9 +30,9 @@ ListAction:: } int ListAction:: -Run(process::Context const *processContext, Filesystem const *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, Filesystem const *filesystem, Options const &options) { - ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem); + ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(user, processContext, filesystem); if (!buildEnvironment) { fprintf(stderr, "error: couldn't create build environment\n"); return -1; @@ -40,7 +41,7 @@ Run(process::Context const *processContext, Filesystem const *filesystem, Option std::vector overrideLevels = Action::CreateOverrideLevels(processContext, filesystem, buildEnvironment->baseEnvironment(), options, processContext->currentDirectory()); xcexecution::Parameters parameters = Action::CreateParameters(options, overrideLevels); - ext::optional context = parameters.loadWorkspace(filesystem, processContext->userName(), *buildEnvironment, processContext->currentDirectory()); + ext::optional context = parameters.loadWorkspace(filesystem, user->userName(), *buildEnvironment, processContext->currentDirectory()); if (!context) { return -1; } diff --git a/Libraries/xcdriver/Sources/ShowBuildSettingsAction.cpp b/Libraries/xcdriver/Sources/ShowBuildSettingsAction.cpp index fcbfe25e..ff5ed449 100644 --- a/Libraries/xcdriver/Sources/ShowBuildSettingsAction.cpp +++ b/Libraries/xcdriver/Sources/ShowBuildSettingsAction.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using xcdriver::ShowBuildSettingsAction; using xcdriver::Options; @@ -28,13 +29,13 @@ ShowBuildSettingsAction:: } int ShowBuildSettingsAction:: -Run(process::Context const *processContext, Filesystem const *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, Filesystem const *filesystem, Options const &options) { if (!Action::VerifyBuildActions(options.actions())) { return -1; } - ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem); + ext::optional buildEnvironment = pbxbuild::Build::Environment::Default(user, processContext, filesystem); if (!buildEnvironment) { fprintf(stderr, "error: couldn't create build environment\n"); return -1; @@ -43,7 +44,7 @@ Run(process::Context const *processContext, Filesystem const *filesystem, Option std::vector overrideLevels = Action::CreateOverrideLevels(processContext, filesystem, buildEnvironment->baseEnvironment(), options, processContext->currentDirectory()); xcexecution::Parameters parameters = Action::CreateParameters(options, overrideLevels); - ext::optional workspaceContext = parameters.loadWorkspace(filesystem, processContext->userName(), *buildEnvironment, processContext->currentDirectory()); + ext::optional workspaceContext = parameters.loadWorkspace(filesystem, user->userName(), *buildEnvironment, processContext->currentDirectory()); if (!workspaceContext) { return -1; } diff --git a/Libraries/xcdriver/Sources/ShowSDKsAction.cpp b/Libraries/xcdriver/Sources/ShowSDKsAction.cpp index 3945ea74..d0679925 100644 --- a/Libraries/xcdriver/Sources/ShowSDKsAction.cpp +++ b/Libraries/xcdriver/Sources/ShowSDKsAction.cpp @@ -32,15 +32,15 @@ ShowSDKsAction:: } int ShowSDKsAction:: -Run(process::Context const *processContext, Filesystem const *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, Filesystem const *filesystem, Options const &options) { - ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem); + ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(user, processContext, filesystem); if (!developerRoot) { fprintf(stderr, "error: unable to find developer dir\n"); return 1; } - auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(processContext)); + auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(user, processContext)); auto manager = xcsdk::SDK::Manager::Open(filesystem, *developerRoot, configuration); if (manager == nullptr) { fprintf(stderr, "error: unable to open developer directory\n"); diff --git a/Libraries/xcdriver/Sources/VersionAction.cpp b/Libraries/xcdriver/Sources/VersionAction.cpp index a8656ced..bd4fac4f 100644 --- a/Libraries/xcdriver/Sources/VersionAction.cpp +++ b/Libraries/xcdriver/Sources/VersionAction.cpp @@ -36,20 +36,20 @@ VersionAction:: } int VersionAction:: -Run(process::Context const *processContext, Filesystem const *filesystem, Options const &options) +Run(process::User const *user, process::Context const *processContext, Filesystem const *filesystem, Options const &options) { if (!options.sdk()) { // TODO(grp): Real version numbers. printf("xcbuild version 0.1\n"); printf("Build version 1\n"); } else { - ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem); + ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(user, processContext, filesystem); if (!developerRoot) { fprintf(stderr, "error: unable to find developer dir\n"); return 1; } - auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(processContext)); + auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(user, processContext)); auto manager = xcsdk::SDK::Manager::Open(filesystem, *developerRoot, configuration); if (manager == nullptr) { fprintf(stderr, "error: unable to open developer directory\n"); diff --git a/Libraries/xcdriver/Tools/xcbuild.cpp b/Libraries/xcdriver/Tools/xcbuild.cpp index 2dc12381..b585b25f 100644 --- a/Libraries/xcdriver/Tools/xcbuild.cpp +++ b/Libraries/xcdriver/Tools/xcbuild.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using libutil::DefaultFilesystem; @@ -20,5 +21,6 @@ main(int argc, char **argv) DefaultFilesystem filesystem = DefaultFilesystem(); process::DefaultContext processContext = process::DefaultContext(); process::DefaultLauncher processLauncher = process::DefaultLauncher(); - return xcdriver::Driver::Run(&processContext, &processLauncher, &filesystem); + process::DefaultUser user = process::DefaultUser(); + return xcdriver::Driver::Run(&user, &processContext, &processLauncher, &filesystem); } diff --git a/Libraries/xcexecution/Headers/xcexecution/Executor.h b/Libraries/xcexecution/Headers/xcexecution/Executor.h index a2b8ef1e..50498e3a 100644 --- a/Libraries/xcexecution/Headers/xcexecution/Executor.h +++ b/Libraries/xcexecution/Headers/xcexecution/Executor.h @@ -17,6 +17,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } namespace process { class Launcher; } +namespace process { class User; } namespace pbxbuild { namespace Build { class Context; } @@ -50,6 +51,7 @@ public: * Abstract build method. Override to implement the build. */ virtual bool build( + process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem, diff --git a/Libraries/xcexecution/Headers/xcexecution/NinjaExecutor.h b/Libraries/xcexecution/Headers/xcexecution/NinjaExecutor.h index 71439c67..89ad380e 100644 --- a/Libraries/xcexecution/Headers/xcexecution/NinjaExecutor.h +++ b/Libraries/xcexecution/Headers/xcexecution/NinjaExecutor.h @@ -29,6 +29,7 @@ public: public: virtual bool build( + process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem, diff --git a/Libraries/xcexecution/Headers/xcexecution/SimpleExecutor.h b/Libraries/xcexecution/Headers/xcexecution/SimpleExecutor.h index 79aed8ba..8cb0669a 100644 --- a/Libraries/xcexecution/Headers/xcexecution/SimpleExecutor.h +++ b/Libraries/xcexecution/Headers/xcexecution/SimpleExecutor.h @@ -30,6 +30,7 @@ public: public: virtual bool build( + process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, libutil::Filesystem *filesystem, diff --git a/Libraries/xcexecution/Sources/NinjaExecutor.cpp b/Libraries/xcexecution/Sources/NinjaExecutor.cpp index 140f1875..e5ea011f 100644 --- a/Libraries/xcexecution/Sources/NinjaExecutor.cpp +++ b/Libraries/xcexecution/Sources/NinjaExecutor.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -358,6 +359,7 @@ ShouldGenerateNinja(Filesystem const *filesystem, bool generate, Parameters cons bool NinjaExecutor:: build( + process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem, @@ -403,7 +405,7 @@ build( * Load the workspace. This can be quite slow, so only do it if it's needed to generate * the Ninja file. Similarly, only resolve dependencies in that case. */ - ext::optional workspaceContext = buildParameters.loadWorkspace(filesystem, processContext->userName(), buildEnvironment, processContext->currentDirectory()); + ext::optional workspaceContext = buildParameters.loadWorkspace(filesystem, user->userName(), buildEnvironment, processContext->currentDirectory()); if (!workspaceContext) { fprintf(stderr, "error: unable to load workspace\n"); return false; @@ -503,12 +505,7 @@ build( *executable, intermediatesDirectory, arguments, - processContext->environmentVariables(), - processContext->userID(), - processContext->groupID(), - processContext->userName(), - processContext->groupName()); - + processContext->environmentVariables()); ext::optional exitCode = processLauncher->launch(filesystem, &ninja); if (!exitCode || *exitCode != 0) { return false; diff --git a/Libraries/xcexecution/Sources/SimpleExecutor.cpp b/Libraries/xcexecution/Sources/SimpleExecutor.cpp index d9818b2b..6a974af5 100644 --- a/Libraries/xcexecution/Sources/SimpleExecutor.cpp +++ b/Libraries/xcexecution/Sources/SimpleExecutor.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -44,13 +45,14 @@ SimpleExecutor:: bool SimpleExecutor:: build( + process::User const *user, process::Context const *processContext, process::Launcher *processLauncher, Filesystem *filesystem, pbxbuild::Build::Environment const &buildEnvironment, Parameters const &buildParameters) { - ext::optional workspaceContext = buildParameters.loadWorkspace(filesystem, processContext->userName(), buildEnvironment, processContext->currentDirectory()); + ext::optional workspaceContext = buildParameters.loadWorkspace(filesystem, user->userName(), buildEnvironment, processContext->currentDirectory()); if (!workspaceContext) { return false; } @@ -264,11 +266,7 @@ performInvocations( *builtin, invocation.workingDirectory(), invocation.arguments(), - invocation.environment(), - processContext->userID(), - processContext->groupID(), - processContext->userName(), - processContext->groupName()); + invocation.environment()); int exitCode = driver->run(&context, filesystem); success = (exitCode == 0); @@ -299,11 +297,7 @@ performInvocations( *path, invocation.workingDirectory(), invocation.arguments(), - environment, - processContext->userID(), - processContext->groupID(), - processContext->userName(), - processContext->groupName()); + environment); ext::optional exitCode = processLauncher->launch(filesystem, &context); success = (exitCode && *exitCode == 0); diff --git a/Libraries/xcexecution/Tests/test_SimpleExecutor.cpp b/Libraries/xcexecution/Tests/test_SimpleExecutor.cpp index d7afa6e8..61f1371b 100644 --- a/Libraries/xcexecution/Tests/test_SimpleExecutor.cpp +++ b/Libraries/xcexecution/Tests/test_SimpleExecutor.cpp @@ -75,11 +75,7 @@ TEST(SimpleExecutor, PropagateToolResult) "", "/", std::vector(), - std::unordered_map(), - 0, - 0, - "user", - "group"); + std::unordered_map()); /* Create invocations to execute. */ auto builtinSuccess = pbxbuild::Tool::Invocation(); diff --git a/Libraries/xcsdk/Headers/xcsdk/Configuration.h b/Libraries/xcsdk/Headers/xcsdk/Configuration.h index 0a655282..6e584f5b 100644 --- a/Libraries/xcsdk/Headers/xcsdk/Configuration.h +++ b/Libraries/xcsdk/Headers/xcsdk/Configuration.h @@ -16,6 +16,7 @@ namespace libutil { class Filesystem; } namespace process { class Context; } +namespace process { class User; } namespace xcsdk { @@ -50,6 +51,7 @@ public: * The default paths for the configuration. */ static std::vector DefaultPaths( + process::User const *user, process::Context const *processContext); /* diff --git a/Libraries/xcsdk/Headers/xcsdk/Environment.h b/Libraries/xcsdk/Headers/xcsdk/Environment.h index 978bab25..13c3a634 100644 --- a/Libraries/xcsdk/Headers/xcsdk/Environment.h +++ b/Libraries/xcsdk/Headers/xcsdk/Environment.h @@ -15,6 +15,7 @@ namespace libutil { class Filesystem; }; namespace process { class Context; }; +namespace process { class User; }; namespace xcsdk { @@ -25,6 +26,7 @@ private: public: static ext::optional DeveloperRoot( + process::User const *user, process::Context const *processContext, libutil::Filesystem const *filesystem); diff --git a/Libraries/xcsdk/Sources/Configuration.cpp b/Libraries/xcsdk/Sources/Configuration.cpp index 7dc317f8..b0e022c6 100644 --- a/Libraries/xcsdk/Sources/Configuration.cpp +++ b/Libraries/xcsdk/Sources/Configuration.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using xcsdk::Configuration; using libutil::Filesystem; @@ -28,13 +29,13 @@ Configuration( } std::vector Configuration:: -DefaultPaths(process::Context const *processContext) +DefaultPaths(process::User const *user, process::Context const *processContext) { std::vector defaultPaths; if (ext::optional environmentPath = processContext->environmentVariable("XCSDK_CONFIGURATION_PATH")) { defaultPaths.push_back(*environmentPath); } else { - ext::optional homePath = processContext->userHomeDirectory(); + ext::optional homePath = user->userHomeDirectory(); if (homePath) { defaultPaths.push_back(*homePath + "/.xcsdk/xcsdk_configuration.plist"); } diff --git a/Libraries/xcsdk/Sources/Environment.cpp b/Libraries/xcsdk/Sources/Environment.cpp index a42513f1..91159d21 100644 --- a/Libraries/xcsdk/Sources/Environment.cpp +++ b/Libraries/xcsdk/Sources/Environment.cpp @@ -12,6 +12,7 @@ #include #include #include +#include using xcsdk::Environment; using libutil::Filesystem; @@ -50,13 +51,13 @@ ResolveDeveloperRoot(Filesystem const *filesystem, std::string const &path) } ext::optional Environment:: -DeveloperRoot(process::Context const *processContext, Filesystem const *filesystem) +DeveloperRoot(process::User const *user, process::Context const *processContext, Filesystem const *filesystem) { if (auto path = processContext->environmentVariable("DEVELOPER_DIR")) { return ResolveDeveloperRoot(filesystem, *path); } - if (ext::optional userHomeDirectory = processContext->userHomeDirectory()) { + if (ext::optional userHomeDirectory = user->userHomeDirectory()) { if (auto path = filesystem->readSymbolicLink(UserDeveloperRootLink(*userHomeDirectory))) { return path; } diff --git a/Libraries/xcsdk/Tools/xcode-select.cpp b/Libraries/xcsdk/Tools/xcode-select.cpp index f7b87d1e..12b925e3 100644 --- a/Libraries/xcsdk/Tools/xcode-select.cpp +++ b/Libraries/xcsdk/Tools/xcode-select.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include @@ -131,6 +133,7 @@ main(int argc, char **argv) { DefaultFilesystem filesystem = DefaultFilesystem(); process::DefaultContext processContext = process::DefaultContext(); + process::DefaultUser user = process::DefaultUser(); /* * Parse out the options, or print help & exit. @@ -149,7 +152,7 @@ main(int argc, char **argv) } else if (options.version()) { return Version(); } else if (options.printPath()) { - ext::optional developer = xcsdk::Environment::DeveloperRoot(&processContext, &filesystem); + ext::optional developer = xcsdk::Environment::DeveloperRoot(&user, &processContext, &filesystem); if (!developer) { fprintf(stderr, "error: no developer directory found\n"); return 1; diff --git a/Libraries/xcsdk/Tools/xcrun.cpp b/Libraries/xcsdk/Tools/xcrun.cpp index 980858ee..70f16d29 100644 --- a/Libraries/xcsdk/Tools/xcrun.cpp +++ b/Libraries/xcsdk/Tools/xcrun.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include using libutil::DefaultFilesystem; @@ -222,7 +224,7 @@ Version() return 0; } -static int Run(Filesystem *filesystem, process::Context const *processContext, process::Launcher *processLauncher) +static int Run(Filesystem *filesystem, process::User const *user, process::Context const *processContext, process::Launcher *processLauncher) { /* * Parse out the options, or print help & exit. @@ -269,12 +271,12 @@ static int Run(Filesystem *filesystem, process::Context const *processContext, p /* * Load the SDK manager from the developer root. */ - ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem); + ext::optional developerRoot = xcsdk::Environment::DeveloperRoot(user, processContext, filesystem); if (!developerRoot) { fprintf(stderr, "error: unable to find developer root\n"); return -1; } - auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(processContext)); + auto configuration = xcsdk::Configuration::Load(filesystem, xcsdk::Configuration::DefaultPaths(user, processContext)); auto manager = xcsdk::SDK::Manager::Open(filesystem, *developerRoot, configuration); if (manager == nullptr) { fprintf(stderr, "error: unable to load manager from '%s'\n", developerRoot->c_str()); @@ -445,11 +447,7 @@ static int Run(Filesystem *filesystem, process::Context const *processContext, p *executable, processContext->currentDirectory(), options.args(), - environment, - processContext->userID(), - processContext->groupID(), - processContext->userName(), - processContext->groupName()); + environment); ext::optional exitCode = processLauncher->launch(filesystem, &context); if (!exitCode) { @@ -468,6 +466,7 @@ main(int argc, char **argv) DefaultFilesystem filesystem = DefaultFilesystem(); process::DefaultContext processContext = process::DefaultContext(); process::DefaultLauncher processLauncher = process::DefaultLauncher(); - return Run(&filesystem, &processContext, &processLauncher); + process::DefaultUser user = process::DefaultUser(); + return Run(&filesystem, &user, &processContext, &processLauncher); } diff --git a/Libraries/xcworkspace/Tools/dump_xcworkspace.cpp b/Libraries/xcworkspace/Tools/dump_xcworkspace.cpp index 544561a1..a8676e72 100644 --- a/Libraries/xcworkspace/Tools/dump_xcworkspace.cpp +++ b/Libraries/xcworkspace/Tools/dump_xcworkspace.cpp @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -154,6 +156,7 @@ int main(int argc, char **argv) { DefaultFilesystem filesystem = DefaultFilesystem(); + process::DefaultUser user = process::DefaultUser(); process::DefaultContext processContext = process::DefaultContext(); if (argc < 2) { @@ -174,7 +177,7 @@ main(int argc, char **argv) printf("Base Path: %s\n", workspace->basePath().c_str()); printf("Name: %s\n", workspace->name().c_str()); - auto workspaceGroup = xcscheme::SchemeGroup::Open(&filesystem, processContext.userName(), workspace->basePath(), workspace->projectFile(), workspace->name()); + auto workspaceGroup = xcscheme::SchemeGroup::Open(&filesystem, user.userName(), workspace->basePath(), workspace->projectFile(), workspace->name()); printf("Schemes:\n"); if (workspaceGroup) { @@ -219,7 +222,7 @@ main(int argc, char **argv) std::string path = MakePath(&filesystem, *workspace, g, fref.location(), false); auto project = PBX::Project::Open(&filesystem, path); if (project) { - auto projectGroup = xcscheme::SchemeGroup::Open(&filesystem, processContext.userName(), project->basePath(), project->projectFile(), project->name()); + auto projectGroup = xcscheme::SchemeGroup::Open(&filesystem, user.userName(), project->basePath(), project->projectFile(), project->name()); if (projectGroup) { schemes.insert(schemes.end(), projectGroup->schemes().begin(),