From 995aec217bbb26c9c2a701cc77edb067ffbf8d36 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 8 Jan 2025 13:49:56 +0100 Subject: add ServiceLevel for service processes: User, AllUsers and Service --- src/zencore/process.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index b1da034d2..11273a2b9 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -443,6 +443,10 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma { CreationFlags |= CREATE_NEW_CONSOLE; } + if (Options.Flags & CreateProcOptions::Flag_NoConsole) + { + CreationFlags |= CREATE_NO_WINDOW; + } const wchar_t* WorkingDir = nullptr; if (Options.WorkingDirectory != nullptr) @@ -588,6 +592,10 @@ CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view C { CreateProcFlags |= CREATE_NEW_CONSOLE; } + if (Options.Flags & CreateProcOptions::Flag_NoConsole) + { + CreateProcFlags |= CREATE_NO_WINDOW; + } ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; -- cgit v1.2.3 From d2669359113583e6329764e5bfebaa0b22731a8e Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Fri, 10 Jan 2025 10:58:26 +0100 Subject: if we can't open a process handle, assume it is running under other user id --- src/zencore/process.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 11273a2b9..3d6a67ada 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -806,6 +806,11 @@ IsProcessRunning(int pid, std::error_code& OutEc) { return false; } + if (Error == ERROR_ACCESS_DENIED) + { + // Process is running under other user probably, assume it is running + return true; + } OutEc = MakeErrorCode(Error); return false; } -- cgit v1.2.3 From 531c59032bbc46bc1f7284859fa8ff8c8b5ede61 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 15 Jan 2025 09:30:12 +0100 Subject: systemd unit file, incomplete --- src/zencore/process.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 3d6a67ada..8049130da 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -853,6 +853,10 @@ IsProcessRunning(int pid, std::error_code& OutEc) { return false; } + else if (Error == EPERM) + { + return true; // Running under a user we don't have access to, assume it is live + } else { OutEc = MakeErrorCode(Error); -- cgit v1.2.3 From 53531a6b22dbb7b690db43964172e9d0f670c3c8 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 15 Jan 2025 10:17:02 +0100 Subject: clang format --- src/zencore/process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 8049130da..8e903f05f 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -855,7 +855,7 @@ IsProcessRunning(int pid, std::error_code& OutEc) } else if (Error == EPERM) { - return true; // Running under a user we don't have access to, assume it is live + return true; // Running under a user we don't have access to, assume it is live } else { -- cgit v1.2.3 From 7e700445334d8d3269bca0bf446ff63211296dce Mon Sep 17 00:00:00 2001 From: Liam Mitchell Date: Wed, 19 Feb 2025 00:08:41 +0000 Subject: Linux compilation fixes --- src/zencore/process.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 8e903f05f..8dc86371e 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -24,7 +24,6 @@ # include # include # include -# include # include # include # include -- cgit v1.2.3 From c49b0a053c5e28de1afa83600ebffd383766e38a Mon Sep 17 00:00:00 2001 From: Liam Mitchell Date: Thu, 27 Feb 2025 02:16:10 +0000 Subject: Implementation of service commands for Linux. --- src/zencore/process.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index 8dc86371e..9f0c9578f 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -40,7 +40,9 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { #if ZEN_PLATFORM_LINUX -const bool bNoZombieChildren = []() { +void +IgnoreChildSignals() +{ // When a child process exits it is put into a zombie state until the parent // collects its result. This doesn't fit the Windows-like model that Zen uses // where there is a less strict familial model and no zombification. Ignoring @@ -51,8 +53,7 @@ const bool bNoZombieChildren = []() { sigemptyset(&Action.sa_mask); Action.sa_handler = SIG_IGN; sigaction(SIGCHLD, &Action, nullptr); - return true; -}(); +} static char GetPidStatus(int Pid, std::error_code& OutEc) -- cgit v1.2.3 From 908f99b749fbbf9754f9485d680914792034334c Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Wed, 12 Mar 2025 18:58:24 +0100 Subject: fix quoted command lines arguments (#306) Handling of quotes and quotes with leading backslash for command line parsing - UE-231677 --- src/zencore/process.cpp | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) (limited to 'src/zencore/process.cpp') diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index c51e8f69d..0761521dc 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -1047,6 +1047,118 @@ FindProcess(const std::filesystem::path& ExecutableImage, ProcessHandle& OutHand #endif // ZEN_PLATFORM_LINUX } +std::vector +ParseCommandLine(std::string_view CommandLine) +{ + auto IsWhitespaceOrEnd = [](std::string_view CommandLine, std::string::size_type Pos) { + if (Pos == CommandLine.length()) + { + return true; + } + if (CommandLine[Pos] == ' ') + { + return true; + } + return false; + }; + + bool IsParsingArg = false; + bool IsInQuote = false; + + std::string::size_type Pos = 0; + std::string::size_type ArgStart = 0; + std::vector Args; + while (Pos < CommandLine.length()) + { + if (IsInQuote) + { + if (CommandLine[Pos] == '"' && IsWhitespaceOrEnd(CommandLine, Pos + 1)) + { + Args.push_back(std::string(CommandLine.substr(ArgStart, Pos - ArgStart + 1))); + Pos++; + IsInQuote = false; + IsParsingArg = false; + } + else + { + Pos++; + } + } + else if (IsParsingArg) + { + ZEN_ASSERT(Pos > ArgStart); + if (CommandLine[Pos] == ' ') + { + Args.push_back(std::string(CommandLine.substr(ArgStart, Pos - ArgStart))); + Pos++; + IsParsingArg = false; + } + else if (CommandLine[Pos] == '"') + { + IsInQuote = true; + Pos++; + } + else + { + Pos++; + } + } + else if (CommandLine[Pos] == '"') + { + IsInQuote = true; + IsParsingArg = true; + ArgStart = Pos; + Pos++; + } + else if (CommandLine[Pos] != ' ') + { + IsParsingArg = true; + ArgStart = Pos; + Pos++; + } + else + { + Pos++; + } + } + if (IsParsingArg) + { + ZEN_ASSERT(Pos > ArgStart); + Args.push_back(std::string(CommandLine.substr(ArgStart))); + } + + return Args; +} + +std::vector +StripCommandlineQuotes(std::vector& InOutArgs) +{ + std::vector RawArgs; + RawArgs.reserve(InOutArgs.size()); + for (std::string& Arg : InOutArgs) + { + std::string::size_type EscapedQuotePos = Arg.find("\\\"", 1); + while (EscapedQuotePos != std::string::npos && Arg.rfind('\"', EscapedQuotePos - 1) != std::string::npos) + { + Arg.erase(EscapedQuotePos, 1); + EscapedQuotePos = Arg.find("\\\"", EscapedQuotePos); + } + + if (Arg.starts_with("\"")) + { + if (Arg.find('"', 1) == Arg.length() - 1) + { + if (Arg.find(' ', 1) == std::string::npos) + { + Arg = Arg.substr(1, Arg.length() - 2); + } + } + } + RawArgs.push_back(const_cast(Arg.c_str())); + } + return RawArgs; +} + #if ZEN_WITH_TESTS void @@ -1123,6 +1235,36 @@ TEST_CASE("BuildArgV") } } +TEST_CASE("CommandLine") +{ + std::vector v1 = ParseCommandLine("c:\\my\\exe.exe \"quoted arg\" \"one\",two,\"three\\\""); + CHECK_EQ(v1[0], "c:\\my\\exe.exe"); + CHECK_EQ(v1[1], "\"quoted arg\""); + CHECK_EQ(v1[2], "\"one\",two,\"three\\\""); + + std::vector v2 = ParseCommandLine( + "--tracehost 127.0.0.1 builds download --url=https://jupiter.devtools.epicgames.com --namespace=ue.oplog " + "--bucket=citysample.packaged-build.fortnite-main.windows \"c:\\just\\a\\path\" " + "--access-token-path=\"C:\\Users\\dan.engelbrecht\\jupiter-token.json\" \"D:\\Dev\\Spaced Folder\\Target\\\" " + "--alt-path=\"D:\\Dev\\Spaced Folder2\\Target\\\" 07dn23ifiwesnvoasjncasab --build-part-name win64,linux,ps5"); + + std::vector v2Stripped = StripCommandlineQuotes(v2); + CHECK_EQ(v2Stripped[0], std::string("--tracehost")); + CHECK_EQ(v2Stripped[1], std::string("127.0.0.1")); + CHECK_EQ(v2Stripped[2], std::string("builds")); + CHECK_EQ(v2Stripped[3], std::string("download")); + CHECK_EQ(v2Stripped[4], std::string("--url=https://jupiter.devtools.epicgames.com")); + CHECK_EQ(v2Stripped[5], std::string("--namespace=ue.oplog")); + CHECK_EQ(v2Stripped[6], std::string("--bucket=citysample.packaged-build.fortnite-main.windows")); + CHECK_EQ(v2Stripped[7], std::string("c:\\just\\a\\path")); + CHECK_EQ(v2Stripped[8], std::string("--access-token-path=\"C:\\Users\\dan.engelbrecht\\jupiter-token.json\"")); + CHECK_EQ(v2Stripped[9], std::string("\"D:\\Dev\\Spaced Folder\\Target\"")); + CHECK_EQ(v2Stripped[10], std::string("--alt-path=\"D:\\Dev\\Spaced Folder2\\Target\"")); + CHECK_EQ(v2Stripped[11], std::string("07dn23ifiwesnvoasjncasab")); + CHECK_EQ(v2Stripped[12], std::string("--build-part-name")); + CHECK_EQ(v2Stripped[13], std::string("win64,linux,ps5")); +} + TEST_SUITE_END(/* core.process */); #endif -- cgit v1.2.3