mirror of
https://github.com/NixOS/nix.git
synced 2024-11-25 08:12:29 +00:00
Remove lookupPathForProgram and implement initial runProgram test
Apparently, CreateProcessW already searches path, so manual path search isn't really necessary.
This commit is contained in:
parent
fcb92b4fa4
commit
8b81d083a7
@ -89,36 +89,6 @@ std::string runProgram(
|
|||||||
|
|
||||||
return res.second;
|
return res.second;
|
||||||
}
|
}
|
||||||
// Looks at the $PATH environment variable to find the program.
|
|
||||||
// Adapted from https://github.com/nix-windows/nix/blob/windows/src/libutil/util.cc#L2276
|
|
||||||
Path lookupPathForProgram(const Path & program)
|
|
||||||
{
|
|
||||||
if (program.find('/') != program.npos || program.find('\\') != program.npos) {
|
|
||||||
throw UsageError("program '%1%' partially specifies its path", program);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Possible extensions.
|
|
||||||
// TODO: This should actually be sourced from $PATHEXT, not hardcoded.
|
|
||||||
static constexpr const char * exts[] = {"", ".exe", ".cmd", ".bat"};
|
|
||||||
|
|
||||||
auto path = getEnv("PATH");
|
|
||||||
if (!path.has_value()) {
|
|
||||||
throw WinError("couldn't find PATH environment variable");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look through each directory listed in $PATH.
|
|
||||||
for (const std::string & dir : tokenizeString<Strings>(*path, ";")) {
|
|
||||||
// TODO: This should actually be canonPath(dir), but that ends up appending two drive paths
|
|
||||||
Path candidate = dir + "/" + program;
|
|
||||||
for (const auto ext : exts) {
|
|
||||||
if (pathExists(candidate + ext)) {
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw WinError("program '%1%' not found on PATH", program);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<Path> getProgramInterpreter(const Path & program)
|
std::optional<Path> getProgramInterpreter(const Path & program)
|
||||||
{
|
{
|
||||||
@ -246,7 +216,7 @@ Pid spawnProcess(const Path & realProgram, const RunOptions & options, Pipe & ou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cmdline = realProgram;
|
std::string cmdline = windowsEscape(realProgram, false);
|
||||||
for (const auto & arg : options.args) {
|
for (const auto & arg : options.args) {
|
||||||
// TODO: This isn't the right way to escape windows command
|
// TODO: This isn't the right way to escape windows command
|
||||||
// See https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw
|
// See https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw
|
||||||
@ -255,7 +225,8 @@ Pid spawnProcess(const Path & realProgram, const RunOptions & options, Pipe & ou
|
|||||||
|
|
||||||
PROCESS_INFORMATION procInfo = {0};
|
PROCESS_INFORMATION procInfo = {0};
|
||||||
if (CreateProcessW(
|
if (CreateProcessW(
|
||||||
string_to_os_string(realProgram).c_str(),
|
// EXE path is provided in the cmdline
|
||||||
|
NULL,
|
||||||
string_to_os_string(cmdline).data(),
|
string_to_os_string(cmdline).data(),
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -335,9 +306,6 @@ void runProgram2(const RunOptions & options)
|
|||||||
in.create();
|
in.create();
|
||||||
|
|
||||||
Path realProgram = options.program;
|
Path realProgram = options.program;
|
||||||
if (options.lookupPath) {
|
|
||||||
realProgram = lookupPathForProgram(realProgram);
|
|
||||||
}
|
|
||||||
// TODO: Implement shebang / program interpreter lookup on Windows
|
// TODO: Implement shebang / program interpreter lookup on Windows
|
||||||
auto interpreter = getProgramInterpreter(realProgram);
|
auto interpreter = getProgramInterpreter(realProgram);
|
||||||
|
|
||||||
|
@ -3,22 +3,15 @@
|
|||||||
#include "processes.hh"
|
#include "processes.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
/*
|
|
||||||
TEST(SpawnTest, spawnEcho)
|
|
||||||
{
|
|
||||||
auto output = runProgram(RunOptions{.program = "cmd", .lookupPath = true, .args = {"/C", "echo \"hello world\""}});
|
|
||||||
std::cout << output.second << std::endl;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Path lookupPathForProgram(const Path & program);
|
TEST(SpawnTest, spawnEcho)
|
||||||
TEST(SpawnTest, pathSearch)
|
|
||||||
{
|
{
|
||||||
ASSERT_NO_THROW(lookupPathForProgram("cmd"));
|
auto output = runProgram(RunOptions{.program = "cmd.exe", .args = {"/C", "echo", "hello world"}});
|
||||||
ASSERT_NO_THROW(lookupPathForProgram("cmd.exe"));
|
ASSERT_EQ(output.first, 0);
|
||||||
ASSERT_THROW(lookupPathForProgram("C:/System32/cmd.exe"), UsageError);
|
ASSERT_EQ(output.second, "\"hello world\"\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string windowsEscape(const std::string & str, bool cmd);
|
std::string windowsEscape(const std::string & str, bool cmd);
|
||||||
|
|
||||||
TEST(SpawnTest, windowsEscape)
|
TEST(SpawnTest, windowsEscape)
|
||||||
|
Loading…
Reference in New Issue
Block a user