summaryrefslogtreecommitdiff
path: root/src/shell_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-11-27 22:21:20 +1100
committerMaxime Coste <mawww@kakoune.org>2018-11-27 22:21:20 +1100
commitd1274836cd8f3d3f82759b9c797a8d01f2d4c7c2 (patch)
treebdfb712328c541fbd58e02ff9505c8d830c8ed14 /src/shell_manager.cc
parent5250593129b14feae02fdf449d5bf68b8c12ab70 (diff)
Support KAKOUNE_POSIX_SHELL environment variable to choose the shell path
The shell will always be run with 'sh' as argv[0] to make shells such as busybox sh supported. Closes #2547
Diffstat (limited to 'src/shell_manager.cc')
-rw-r--r--src/shell_manager.cc32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/shell_manager.cc b/src/shell_manager.cc
index be8a8b2f..e774eb33 100644
--- a/src/shell_manager.cc
+++ b/src/shell_manager.cc
@@ -28,22 +28,32 @@ namespace Kakoune
ShellManager::ShellManager(ConstArrayView<EnvVarDesc> builtin_env_vars)
: m_env_vars{builtin_env_vars}
{
- // Get a guaranteed to be POSIX shell binary
+ auto is_executable = [](StringView path) {
+ struct stat st;
+ if (stat(path.zstr(), &st))
+ return false;
+
+ bool executable = (st.st_mode & S_IXUSR)
+ | (st.st_mode & S_IXGRP)
+ | (st.st_mode & S_IXOTH);
+ return S_ISREG(st.st_mode) and executable;
+ };
+
+ if (const char* shell = getenv("KAKOUNE_POSIX_SHELL"))
+ {
+ if (not is_executable(shell))
+ throw runtime_error{format("KAKOUNE_POSIX_SHELL '{}' is not executable", shell)};
+ m_shell = shell;
+ }
+ else // Get a guaranteed to be POSIX shell binary
{
auto size = confstr(_CS_PATH, nullptr, 0);
String path; path.resize(size-1, 0);
confstr(_CS_PATH, path.data(), size);
for (auto dir : StringView{path} | split<StringView>(':'))
{
- String candidate = format("{}/sh", dir);
- struct stat st;
- if (stat(candidate.c_str(), &st))
- continue;
-
- bool executable = (st.st_mode & S_IXUSR)
- | (st.st_mode & S_IXGRP)
- | (st.st_mode & S_IXOTH);
- if (S_ISREG(st.st_mode) and executable)
+ auto candidate = format("{}/sh", dir);
+ if (is_executable(candidate))
{
m_shell = std::move(candidate);
break;
@@ -100,7 +110,7 @@ pid_t spawn_shell(const char* shell, StringView cmdline,
envptrs.push_back(nullptr);
auto cmdlinezstr = cmdline.zstr();
- Vector<const char*> execparams = { shell, "-c", cmdlinezstr };
+ Vector<const char*> execparams = { "sh", "-c", cmdlinezstr };
if (not params.empty())
execparams.push_back(shell);
for (auto& param : params)