forked from NixOS/nix
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
339 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
///@file | ||
///@brief A platform-agnostic implementation of the POSIX PATH environment variable logic | ||
#include "environment-posix-path.hh" | ||
#include "util.hh" | ||
#include "strings.hh" | ||
|
||
namespace nix { | ||
|
||
std::string findExecutable( | ||
const std::string & name, | ||
std::optional<std::string> pathValue, | ||
std::function<bool(const std::string &)> isExecutable) | ||
{ | ||
// "If the pathname being sought contains a <slash>, the search through the path prefixes shall not be performed." | ||
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
if (name.empty() || name.find('/') != std::string::npos) { | ||
return name; | ||
} | ||
|
||
// "If PATH is unset or is set to null, the path search is implementation-defined." | ||
// https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
auto path = pathValue.value_or(""); | ||
|
||
for (auto & dir : splitString<Strings>(path, ":")) { | ||
auto combined = dir.empty() ? name : dir + "/" + name; | ||
if (isExecutable(combined)) { | ||
return combined; | ||
} | ||
} | ||
return name; | ||
} | ||
|
||
} // namespace nix |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#pragma once | ||
|
||
///@file | ||
///@brief Cross-platform implementation of the POSIX PATH environment variable | ||
|
||
#include <string> | ||
#include <functional> | ||
#include "environment-variables.hh" | ||
|
||
namespace nix { | ||
|
||
/** | ||
* Interpret path as a location in the ambient file system and return whether | ||
* it exists AND is executable. | ||
*/ | ||
bool isExecutableAmbient(const std::string & path); | ||
|
||
/** | ||
* Search for an executable according to the POSIX spec for `PATH`. | ||
* https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 | ||
* | ||
* Notable additions: | ||
* If `PATH` is unset, `name` is returned verbatim. | ||
* If `PATH` contains a `/` but does not start with one, `name` is returned verbatim. | ||
* | ||
* This is a pure function, except for the default `isExecutable` argument, which | ||
* uses the ambient file system to check if a file is executable (and exists). | ||
* | ||
* @param name A POSIX `pathname` to search for. | ||
* | ||
* @return `name` or path to a resolved executable | ||
* | ||
*/ | ||
std::string findExecutable( | ||
const std::string & name, | ||
std::optional<std::string> pathValue = getEnv("PATH"), | ||
std::function<bool(const std::string &)> isExecutable = isExecutableAmbient); | ||
|
||
} // namespace nix |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "environment-posix-path.hh" | ||
#include <unistd.h> | ||
namespace nix { | ||
|
||
bool isExecutableAmbient(const std::string & path) | ||
{ | ||
const char * cpath = path.c_str(); | ||
return access(cpath, X_OK) == 0; | ||
} | ||
|
||
} // namespace nix |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
#include <string_view> | ||
|
||
namespace nix { | ||
/** | ||
* Split a string, preserving empty strings between separators, as well as at the start and end. | ||
* | ||
* Returns a non-empty collection of strings. | ||
*/ | ||
template<typename C> | ||
C splitString(std::string_view s, std::string_view separators); | ||
|
||
/** | ||
* Concatenate the given strings with a separator between the | ||
* elements. | ||
*/ | ||
template<class C> | ||
std::string concatStringsSep(const std::string_view sep, const C & ss); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.