# HG changeset patch # User František Kučera # Date 1579391842 -3600 # Node ID b5ae619962816f5a71993a9dc74c557578af1689 # Parent f466b4c7d9b1d638d1cad12af21c742dd68bdc22 streamlets: fix command name collisions, do not prepend $RELPIPE_IN_FILESYSTEM_STREAMLET_PATH to the $PATH (a streamlet may call a command with the same name as the streamlet name, which will lead unwanted recursion) diff -r f466b4c7d9b1 -r b5ae61996281 src/StreamletAttributeFinder.h --- a/src/StreamletAttributeFinder.h Sat Jan 18 20:09:34 2020 +0100 +++ b/src/StreamletAttributeFinder.h Sun Jan 19 00:57:22 2020 +0100 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -43,15 +44,31 @@ std::map> subProcesses; std::map> cachedMetadata; - string_t getStreamletPath() { - const char* originalPath = getenv("PATH"); - const char* streamletPath = getenv("RELPIPE_IN_FILESYSTEM_STREAMLET_PATH"); + string_t getStreamletCommand(const RequestedField& field) { + const char* streamletPathChars = getenv("RELPIPE_IN_FILESYSTEM_STREAMLET_PATH"); + if (streamletPathChars) { + std::wstringstream current; + string_t streamletPath = convertor.from_bytes(streamletPathChars); + for (int i = 0, streamletPathSize = streamletPath.size(); i < streamletPathSize; i++) { + if (streamletPath[i] == ':' || i == streamletPathSize - 1) { // FIXME: support \: and \\ escaping + current << L"/" << field.name; + fs::path streamletFile(current.str()); + if (fs::exists(streamletFile)) { // FIXME: check executable bit + return current.str(); + } else { + current.str(L""); + current.clear(); + } + } else { + current.put(streamletPath[i]); + } + } + throw RelpipeWriterException(L"Streamlet „" + field.name + L"“ was not found at $RELPIPE_IN_FILESYSTEM_STREAMLET_PATH"); + } else { + throw RelpipeWriterException(L"Missing environment variable RELPIPE_IN_FILESYSTEM_STREAMLET_PATH → unable to find streamlet."); + } + } - if (originalPath && streamletPath) return convertor.from_bytes(std::string(streamletPath) + ":" + originalPath); - else if (originalPath) return convertor.from_bytes(std::string(originalPath)); - else if (streamletPath) return convertor.from_bytes(std::string(streamletPath)); - else return L""; - } protected: void startFile(const fs::path& file, const string& fileRaw, bool exists) override { @@ -90,7 +107,7 @@ return cachedMetadata[field.id]; } else { - std::vector commandLine = {field.name}; + std::vector commandLine = {getStreamletCommand(field)}; std::map environment; for (auto mn : StreamletMsg::getMessageNames()) { @@ -98,8 +115,6 @@ environment[L"EXEC_MSG_" + std::to_wstring(mn.first)] = mn.second; } - environment[L"PATH"] = getStreamletPath(); - shared_ptr subProcess(SubProcess::create(commandLine, environment)); subProcesses[field.id] = subProcess; diff -r f466b4c7d9b1 -r b5ae61996281 src/SubProcess.cpp --- a/src/SubProcess.cpp Sat Jan 18 20:09:34 2020 +0100 +++ b/src/SubProcess.cpp Sun Jan 19 00:57:22 2020 +0100 @@ -76,7 +76,7 @@ for (size_t i = 0; i < args.size(); i++) a[i] = args[i].c_str(); a[args.size()] = nullptr; - execvp(a[0], (char*const*) a); + execv(a[0], (char*const*) a); delete[] a; throw SubProcess::Exception(L"Unable to do execvp().");