script support. scripts run with an independent copy of the environment and aliases. local variables are not imported.
Currently, it for a ".text" extension to check if it's a script; this is a placeholder.
This commit is contained in:
parent
fd94247aec
commit
6f2b59c4d6
22
command.cpp
22
command.cpp
|
@ -107,6 +107,9 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
bool is_script(const fs::path &path) {
|
||||
return path.extension() == ".text";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,8 +362,6 @@ int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
|||
return status;
|
||||
}
|
||||
|
||||
if (env.test()) return 0;
|
||||
|
||||
if (env.startup()) {
|
||||
fprintf(stderr, "### MPW Shell - startup file may not contain external commands.\n");
|
||||
return 0;
|
||||
|
@ -374,6 +375,23 @@ int simple_command::execute(Environment &env, const fdmask &fds, bool throwup) {
|
|||
//fprintf(stderr, "### MPW Shell - Command \"%s\" was not found.\n", name.c_str());
|
||||
//return -1;
|
||||
}
|
||||
|
||||
if (is_script(path)) {
|
||||
// scripts run with an isolated environment.
|
||||
Environment new_env = env.subshell_environment();
|
||||
new_env.set("command", path);
|
||||
new_env.set_argv(path, p.arguments);
|
||||
|
||||
try {
|
||||
return read_file(new_env, path, newfds);
|
||||
} catch (const exit_command_t &ex) {
|
||||
return ex.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (env.test()) return 0;
|
||||
|
||||
env.set("command", path);
|
||||
p.arguments[0] = path;
|
||||
|
||||
|
|
|
@ -23,6 +23,10 @@ namespace {
|
|||
|
||||
bool tf(long v) { return v; }
|
||||
|
||||
bool tf(const EnvironmentEntry &e) {
|
||||
return tf(static_cast<std::string>(e));
|
||||
}
|
||||
|
||||
// used for #. base 10 only, extra chars ignored.
|
||||
int to_pound_int(const std::string &s) {
|
||||
if (s.empty()) return 0;
|
||||
|
@ -38,6 +42,29 @@ namespace {
|
|||
|
||||
}
|
||||
|
||||
|
||||
Environment Environment::subshell_environment() {
|
||||
/* clone the current environment, do not include local variables */
|
||||
Environment env;
|
||||
env._alias_table = _alias_table;
|
||||
|
||||
auto &table = env._table;
|
||||
for (const auto &kv : _table) {
|
||||
const auto &k = kv.first;
|
||||
const auto &value = kv.second;
|
||||
if (!value) continue;
|
||||
|
||||
if (k == "echo") env._echo = tf(value);
|
||||
if (k == "exit") env._exit = tf(value);
|
||||
if (k == "test") env._test = tf(value);
|
||||
|
||||
table.emplace_hint(table.end(), k, value);
|
||||
}
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
|
||||
std::string Environment::get(const std::string & key) const {
|
||||
auto iter = find(key);
|
||||
if (iter == end()) return "";
|
||||
|
|
|
@ -56,7 +56,8 @@ public:
|
|||
typedef std::vector<std::pair<std::string, std::string>> alias_table_type;
|
||||
typedef alias_table_type::const_iterator const_alias_iterator;
|
||||
|
||||
//const EnvironmentEntry & lookup(const std::string &s);
|
||||
|
||||
Environment subshell_environment();
|
||||
|
||||
void set_argv(const std::string &argv0, const std::vector<std::string>& argv);
|
||||
void set_argv(const std::vector<std::string>& argv);
|
||||
|
@ -80,10 +81,6 @@ public:
|
|||
bool startup() const noexcept { return _startup; }
|
||||
void startup(bool tf) noexcept { _startup = tf; }
|
||||
|
||||
|
||||
bool passthrough() const noexcept { return _passthrough; }
|
||||
void passthrough(bool tf) noexcept { _passthrough = tf; }
|
||||
|
||||
template<class FX>
|
||||
void foreach(FX && fx) { for (const auto &kv : _table) { fx(kv.first, kv.second); }}
|
||||
|
||||
|
@ -133,8 +130,6 @@ public:
|
|||
private:
|
||||
// magic variables.
|
||||
|
||||
friend class indent_helper;
|
||||
|
||||
int _indent = 0;
|
||||
int _loop = 0;
|
||||
|
||||
|
@ -145,7 +140,6 @@ private:
|
|||
int _status = 0;
|
||||
int _pound = 0;
|
||||
bool _startup = false;
|
||||
bool _passthrough = false;
|
||||
|
||||
void set_common(const std::string &, const std::string &, bool);
|
||||
void rebuild_aliases();
|
||||
|
@ -155,16 +149,5 @@ private:
|
|||
alias_table_type _alias_table;
|
||||
};
|
||||
|
||||
/*
|
||||
class indent_helper {
|
||||
public:
|
||||
indent_helper(Environment &e) : env(e) { env._indent++; }
|
||||
void release() { if (active) { active = false; env._indent--; }}
|
||||
~indent_helper() { if (active) env._indent--; }
|
||||
private:
|
||||
Environment &env;
|
||||
bool active = true;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue