mirror of
https://github.com/darlinghq/xcbuild.git
synced 2024-11-30 07:20:46 +00:00
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.
This commit is contained in:
parent
a1f792a720
commit
0e1d1ed246
@ -34,11 +34,7 @@ Process(std::string const &executable, std::vector<std::string> const &arguments
|
||||
executable,
|
||||
"/",
|
||||
arguments,
|
||||
std::unordered_map<std::string, std::string>(),
|
||||
0,
|
||||
0,
|
||||
"root",
|
||||
"wheel");
|
||||
std::unordered_map<std::string, std::string>());
|
||||
}
|
||||
|
||||
TEST(copy, Name)
|
||||
|
@ -65,11 +65,7 @@ TEST(copyPlist, CopyMultiple)
|
||||
"--outdir", "output",
|
||||
"--convert", "ascii1",
|
||||
},
|
||||
std::unordered_map<std::string, std::string>(),
|
||||
0,
|
||||
0,
|
||||
"root",
|
||||
"wheel");
|
||||
std::unordered_map<std::string, std::string>());
|
||||
EXPECT_EQ(0, driver.run(&processContext, &filesystem));
|
||||
|
||||
contents.clear();
|
||||
|
@ -47,11 +47,7 @@ TEST(copyStrings, CopyMultiple)
|
||||
"--outdir", "output",
|
||||
"--outputencoding", "utf-8",
|
||||
},
|
||||
std::unordered_map<std::string, std::string>(),
|
||||
0,
|
||||
0,
|
||||
"root",
|
||||
"wheel");
|
||||
std::unordered_map<std::string, std::string>());
|
||||
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<std::string, std::string>(),
|
||||
0,
|
||||
0,
|
||||
"root",
|
||||
"wheel");
|
||||
std::unordered_map<std::string, std::string>());
|
||||
EXPECT_EQ(0, driver.run(&processContext, &filesystem));
|
||||
|
||||
std::vector<uint8_t> contents;
|
||||
|
@ -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<Environment>
|
||||
Default(
|
||||
process::User const *user,
|
||||
process::Context const *processContext,
|
||||
libutil::Filesystem const *filesystem);
|
||||
};
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <pbxsetting/DefaultSettings.h>
|
||||
#include <pbxsetting/Environment.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
#include <libutil/Filesystem.h>
|
||||
|
||||
namespace Build = pbxbuild::Build;
|
||||
@ -32,9 +33,9 @@ Environment(
|
||||
}
|
||||
|
||||
ext::optional<Build::Environment> Build::Environment::
|
||||
Default(process::Context const *processContext, Filesystem const *filesystem)
|
||||
Default(process::User const *user, process::Context const *processContext, Filesystem const *filesystem)
|
||||
{
|
||||
ext::optional<std::string> developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem);
|
||||
ext::optional<std::string> 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<pbxsetting::Level> defaultLevels = pbxsetting::DefaultSettings::Levels(processContext);
|
||||
std::vector<pbxsetting::Level> defaultLevels = pbxsetting::DefaultSettings::Levels(user, processContext);
|
||||
for (pbxsetting::Level const &level : defaultLevels) {
|
||||
baseEnvironment.insertBack(level, false);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <process/DefaultContext.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/DefaultUser.h>
|
||||
#include <process/User.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
@ -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()) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <vector>
|
||||
|
||||
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<Level>
|
||||
Levels(process::Context const *processContext);
|
||||
Levels(process::User const *user, process::Context const *processContext);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <pbxsetting/Type.h>
|
||||
#include <libutil/FSUtil.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
@ -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<Setting> 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<Level> DefaultSettings::
|
||||
Levels(process::Context const *processContext)
|
||||
Levels(process::User const *user, process::Context const *processContext)
|
||||
{
|
||||
return {
|
||||
Environment(processContext),
|
||||
Environment(user, processContext),
|
||||
Internal(),
|
||||
Local(),
|
||||
System(),
|
||||
|
@ -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)
|
||||
|
@ -52,37 +52,11 @@ public:
|
||||
*/
|
||||
virtual ext::optional<std::string> 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<std::string> executableSearchPaths() const;
|
||||
|
||||
/*
|
||||
* The home directory from the environment.
|
||||
*/
|
||||
virtual ext::optional<std::string> userHomeDirectory() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,15 +31,6 @@ public:
|
||||
virtual std::vector<std::string> const &commandLineArguments() const;
|
||||
virtual std::unordered_map<std::string, std::string> const &environmentVariables() const;
|
||||
virtual ext::optional<std::string> 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<std::string> userHomeDirectory() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
38
Libraries/process/Headers/process/DefaultUser.h
Normal file
38
Libraries/process/Headers/process/DefaultUser.h
Normal file
@ -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 <process/User.h>
|
||||
|
||||
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<std::string> userHomeDirectory() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !__process_DefaultUser_h
|
@ -26,22 +26,12 @@ private:
|
||||
std::vector<std::string> _commandLineArguments;
|
||||
std::unordered_map<std::string, std::string> _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<std::string> const &commandLineArguments,
|
||||
std::unordered_map<std::string, std::string> const &environmentVariables,
|
||||
int32_t userID,
|
||||
int32_t groupID,
|
||||
std::string const &userName,
|
||||
std::string const &groupName);
|
||||
std::unordered_map<std::string, std::string> const &environmentVariables);
|
||||
explicit MemoryContext(Context const *context);
|
||||
virtual ~MemoryContext();
|
||||
|
||||
@ -68,27 +58,6 @@ public:
|
||||
{ return _environmentVariables; }
|
||||
|
||||
virtual ext::optional<std::string> 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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
60
Libraries/process/Headers/process/MemoryUser.h
Normal file
60
Libraries/process/Headers/process/MemoryUser.h
Normal file
@ -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 <process/User.h>
|
||||
|
||||
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
|
57
Libraries/process/Headers/process/User.h
Normal file
57
Libraries/process/Headers/process/User.h
Normal file
@ -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 <string>
|
||||
#include <ext/optional>
|
||||
|
||||
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<std::string> userHomeDirectory() const = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !__process_User_h
|
@ -47,9 +47,3 @@ executableSearchPaths() const
|
||||
return paths;
|
||||
}
|
||||
|
||||
ext::optional<std::string> Context::
|
||||
userHomeDirectory() const
|
||||
{
|
||||
return environmentVariable("HOME");
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,9 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#include <errno.h>
|
||||
@ -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<std::string> DefaultContext::
|
||||
userHomeDirectory() const
|
||||
{
|
||||
if (ext::optional<std::string> value = Context::userHomeDirectory()) {
|
||||
return value;
|
||||
} else {
|
||||
char *home = ::getpwuid(::getuid())->pw_dir;
|
||||
return std::string(home);
|
||||
}
|
||||
}
|
||||
|
@ -188,10 +188,6 @@ launch(Filesystem *filesystem, Context const *context)
|
||||
execEnv.push_back(nullptr);
|
||||
char *const *cExecEnv = const_cast<char *const *>(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);
|
||||
|
||||
|
280
Libraries/process/Sources/DefaultUser.cpp
Normal file
280
Libraries/process/Sources/DefaultUser.cpp
Normal file
@ -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 <process/DefaultUser.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#include <userenv.h>
|
||||
#include <sddl.h>
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
using process::DefaultUser;
|
||||
|
||||
#if _WIN32
|
||||
using WideString = std::basic_string<std::remove_const<std::remove_pointer<LPCWSTR>::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<typename T>
|
||||
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<T *>(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<TOKEN_USER>(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<TOKEN_PRIMARY_GROUP>(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<TOKEN_USER>(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<TOKEN_PRIMARY_GROUP>(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<std::string> 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
|
||||
}
|
@ -16,20 +16,12 @@ MemoryContext(
|
||||
std::string const &executablePath,
|
||||
std::string const ¤tDirectory,
|
||||
std::vector<std::string> const &commandLineArguments,
|
||||
std::unordered_map<std::string, std::string> const &environmentVariables,
|
||||
int32_t userID,
|
||||
int32_t groupID,
|
||||
std::string const &userName,
|
||||
std::string const &groupName) :
|
||||
Context (),
|
||||
std::unordered_map<std::string, std::string> 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())
|
||||
{
|
||||
}
|
||||
|
||||
|
42
Libraries/process/Sources/MemoryUser.cpp
Normal file
42
Libraries/process/Sources/MemoryUser.cpp
Normal file
@ -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 <process/MemoryUser.h>
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
23
Libraries/process/Sources/User.cpp
Normal file
23
Libraries/process/Sources/User.cpp
Normal file
@ -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 <process/User.h>
|
||||
|
||||
using process::User;
|
||||
|
||||
User::
|
||||
User()
|
||||
{
|
||||
}
|
||||
|
||||
User::
|
||||
~User()
|
||||
{
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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<pbxbuild::Build::Environment> buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem);
|
||||
ext::optional<pbxbuild::Build::Environment> 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;
|
||||
}
|
||||
|
@ -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<bool, std::string> result = libutil::Options::Parse<Options>(&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;
|
||||
|
@ -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<std::string> developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem);
|
||||
ext::optional<std::string> 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");
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <libutil/Strings.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
|
||||
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<pbxbuild::Build::Environment> buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem);
|
||||
ext::optional<pbxbuild::Build::Environment> 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<pbxsetting::Level> overrideLevels = Action::CreateOverrideLevels(processContext, filesystem, buildEnvironment->baseEnvironment(), options, processContext->currentDirectory());
|
||||
xcexecution::Parameters parameters = Action::CreateParameters(options, overrideLevels);
|
||||
|
||||
ext::optional<pbxbuild::WorkspaceContext> context = parameters.loadWorkspace(filesystem, processContext->userName(), *buildEnvironment, processContext->currentDirectory());
|
||||
ext::optional<pbxbuild::WorkspaceContext> context = parameters.loadWorkspace(filesystem, user->userName(), *buildEnvironment, processContext->currentDirectory());
|
||||
if (!context) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <xcdriver/Action.h>
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
|
||||
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<pbxbuild::Build::Environment> buildEnvironment = pbxbuild::Build::Environment::Default(processContext, filesystem);
|
||||
ext::optional<pbxbuild::Build::Environment> 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<pbxsetting::Level> overrideLevels = Action::CreateOverrideLevels(processContext, filesystem, buildEnvironment->baseEnvironment(), options, processContext->currentDirectory());
|
||||
xcexecution::Parameters parameters = Action::CreateParameters(options, overrideLevels);
|
||||
|
||||
ext::optional<pbxbuild::WorkspaceContext> workspaceContext = parameters.loadWorkspace(filesystem, processContext->userName(), *buildEnvironment, processContext->currentDirectory());
|
||||
ext::optional<pbxbuild::WorkspaceContext> workspaceContext = parameters.loadWorkspace(filesystem, user->userName(), *buildEnvironment, processContext->currentDirectory());
|
||||
if (!workspaceContext) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -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<std::string> developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem);
|
||||
ext::optional<std::string> 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");
|
||||
|
@ -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<std::string> developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem);
|
||||
ext::optional<std::string> 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");
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <libutil/DefaultFilesystem.h>
|
||||
#include <process/DefaultContext.h>
|
||||
#include <process/DefaultLauncher.h>
|
||||
#include <process/DefaultUser.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
|
||||
public:
|
||||
virtual bool build(
|
||||
process::User const *user,
|
||||
process::Context const *processContext,
|
||||
process::Launcher *processLauncher,
|
||||
libutil::Filesystem *filesystem,
|
||||
|
@ -30,6 +30,7 @@ public:
|
||||
|
||||
public:
|
||||
virtual bool build(
|
||||
process::User const *user,
|
||||
process::Context const *processContext,
|
||||
process::Launcher *processLauncher,
|
||||
libutil::Filesystem *filesystem,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <process/Context.h>
|
||||
#include <process/MemoryContext.h>
|
||||
#include <process/Launcher.h>
|
||||
#include <process/User.h>
|
||||
#include <libutil/md5.h>
|
||||
|
||||
#include <sstream>
|
||||
@ -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<pbxbuild::WorkspaceContext> workspaceContext = buildParameters.loadWorkspace(filesystem, processContext->userName(), buildEnvironment, processContext->currentDirectory());
|
||||
ext::optional<pbxbuild::WorkspaceContext> 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<int> exitCode = processLauncher->launch(filesystem, &ninja);
|
||||
if (!exitCode || *exitCode != 0) {
|
||||
return false;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <process/Context.h>
|
||||
#include <process/MemoryContext.h>
|
||||
#include <process/Launcher.h>
|
||||
#include <process/User.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -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<pbxbuild::WorkspaceContext> workspaceContext = buildParameters.loadWorkspace(filesystem, processContext->userName(), buildEnvironment, processContext->currentDirectory());
|
||||
ext::optional<pbxbuild::WorkspaceContext> 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<int> exitCode = processLauncher->launch(filesystem, &context);
|
||||
success = (exitCode && *exitCode == 0);
|
||||
|
||||
|
@ -75,11 +75,7 @@ TEST(SimpleExecutor, PropagateToolResult)
|
||||
"",
|
||||
"/",
|
||||
std::vector<std::string>(),
|
||||
std::unordered_map<std::string, std::string>(),
|
||||
0,
|
||||
0,
|
||||
"user",
|
||||
"group");
|
||||
std::unordered_map<std::string, std::string>());
|
||||
|
||||
/* Create invocations to execute. */
|
||||
auto builtinSuccess = pbxbuild::Tool::Invocation();
|
||||
|
@ -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<std::string> DefaultPaths(
|
||||
process::User const *user,
|
||||
process::Context const *processContext);
|
||||
|
||||
/*
|
||||
|
@ -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<std::string> DeveloperRoot(
|
||||
process::User const *user,
|
||||
process::Context const *processContext,
|
||||
libutil::Filesystem const *filesystem);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <plist/Format/Any.h>
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
|
||||
using xcsdk::Configuration;
|
||||
using libutil::Filesystem;
|
||||
@ -28,13 +29,13 @@ Configuration(
|
||||
}
|
||||
|
||||
std::vector<std::string> Configuration::
|
||||
DefaultPaths(process::Context const *processContext)
|
||||
DefaultPaths(process::User const *user, process::Context const *processContext)
|
||||
{
|
||||
std::vector<std::string> defaultPaths;
|
||||
if (ext::optional<std::string> environmentPath = processContext->environmentVariable("XCSDK_CONFIGURATION_PATH")) {
|
||||
defaultPaths.push_back(*environmentPath);
|
||||
} else {
|
||||
ext::optional<std::string> homePath = processContext->userHomeDirectory();
|
||||
ext::optional<std::string> homePath = user->userHomeDirectory();
|
||||
if (homePath) {
|
||||
defaultPaths.push_back(*homePath + "/.xcsdk/xcsdk_configuration.plist");
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <libutil/FSUtil.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/User.h>
|
||||
|
||||
using xcsdk::Environment;
|
||||
using libutil::Filesystem;
|
||||
@ -50,13 +51,13 @@ ResolveDeveloperRoot(Filesystem const *filesystem, std::string const &path)
|
||||
}
|
||||
|
||||
ext::optional<std::string> 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<std::string> userHomeDirectory = processContext->userHomeDirectory()) {
|
||||
if (ext::optional<std::string> userHomeDirectory = user->userHomeDirectory()) {
|
||||
if (auto path = filesystem->readSymbolicLink(UserDeveloperRootLink(*userHomeDirectory))) {
|
||||
return path;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <libutil/Filesystem.h>
|
||||
#include <process/DefaultContext.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/DefaultUser.h>
|
||||
#include <process/User.h>
|
||||
#include <libutil/Options.h>
|
||||
#include <ext/optional>
|
||||
|
||||
@ -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<std::string> developer = xcsdk::Environment::DeveloperRoot(&processContext, &filesystem);
|
||||
ext::optional<std::string> developer = xcsdk::Environment::DeveloperRoot(&user, &processContext, &filesystem);
|
||||
if (!developer) {
|
||||
fprintf(stderr, "error: no developer directory found\n");
|
||||
return 1;
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <process/MemoryContext.h>
|
||||
#include <process/Launcher.h>
|
||||
#include <process/DefaultLauncher.h>
|
||||
#include <process/User.h>
|
||||
#include <process/DefaultUser.h>
|
||||
#include <pbxsetting/Type.h>
|
||||
|
||||
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<std::string> developerRoot = xcsdk::Environment::DeveloperRoot(processContext, filesystem);
|
||||
ext::optional<std::string> 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<int> 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);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include <libutil/Strings.h>
|
||||
#include <process/DefaultContext.h>
|
||||
#include <process/Context.h>
|
||||
#include <process/DefaultUser.h>
|
||||
#include <process/User.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user