mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:17:34 +00:00
Kernel: Support passing arguments in shebangged scripts
Add the ability to both pass arguments to scripts with shebangs (./script argument1 argument2) and to specify them in the shebang line (#!/usr/local/bin/bash -x -e) Fixes #585
This commit is contained in:
parent
e2c74762ff
commit
9131134704
2 changed files with 34 additions and 8 deletions
|
@ -550,7 +550,7 @@ int Process::do_exec(String path, Vector<String> arguments, Vector<String> envir
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
KResultOr<String> Process::find_shebang_interpreter_for_executable(const String& executable_path)
|
KResultOr<Vector<String>> Process::find_shebang_interpreter_for_executable(const String& executable_path)
|
||||||
{
|
{
|
||||||
// FIXME: It's a bit sad that we'll open the executable twice (in case there's no shebang)
|
// FIXME: It's a bit sad that we'll open the executable twice (in case there's no shebang)
|
||||||
// Maybe we can find a way to plumb this opened FileDescription to the rest of the
|
// Maybe we can find a way to plumb this opened FileDescription to the rest of the
|
||||||
|
@ -569,16 +569,34 @@ KResultOr<String> Process::find_shebang_interpreter_for_executable(const String&
|
||||||
|
|
||||||
char first_page[PAGE_SIZE];
|
char first_page[PAGE_SIZE];
|
||||||
int nread = description->read((u8*)&first_page, sizeof(first_page));
|
int nread = description->read((u8*)&first_page, sizeof(first_page));
|
||||||
int interpreter_length = 0;
|
int word_start = 2;
|
||||||
|
int word_length = 0;
|
||||||
if (nread > 2 && first_page[0] == '#' && first_page[1] == '!') {
|
if (nread > 2 && first_page[0] == '#' && first_page[1] == '!') {
|
||||||
|
Vector<String> interpreter_words;
|
||||||
|
|
||||||
for (int i = 2; i < nread; ++i) {
|
for (int i = 2; i < nread; ++i) {
|
||||||
if (first_page[i] == '\n') {
|
if (first_page[i] == '\n') {
|
||||||
interpreter_length = i - 2;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (first_page[i] != ' ') {
|
||||||
|
++word_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_page[i] == ' ') {
|
||||||
|
if (word_length > 0) {
|
||||||
|
interpreter_words.append(String(&first_page[word_start], word_length));
|
||||||
|
}
|
||||||
|
word_length = 0;
|
||||||
|
word_start = i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (interpreter_length > 0)
|
|
||||||
return String(&first_page[2], interpreter_length);
|
if (word_length > 0)
|
||||||
|
interpreter_words.append(String(&first_page[word_start], word_length));
|
||||||
|
|
||||||
|
if (!interpreter_words.is_empty())
|
||||||
|
return interpreter_words;
|
||||||
}
|
}
|
||||||
|
|
||||||
return KResult(-ENOEXEC);
|
return KResult(-ENOEXEC);
|
||||||
|
@ -587,8 +605,16 @@ KResultOr<String> Process::find_shebang_interpreter_for_executable(const String&
|
||||||
int Process::exec(String path, Vector<String> arguments, Vector<String> environment)
|
int Process::exec(String path, Vector<String> arguments, Vector<String> environment)
|
||||||
{
|
{
|
||||||
auto result = find_shebang_interpreter_for_executable(path);
|
auto result = find_shebang_interpreter_for_executable(path);
|
||||||
if (!result.is_error())
|
if (!result.is_error()) {
|
||||||
return exec(result.value(), { result.value(), path }, move(environment));
|
Vector<String> new_arguments(result.value());
|
||||||
|
|
||||||
|
new_arguments.append(path);
|
||||||
|
|
||||||
|
arguments.remove(0);
|
||||||
|
new_arguments.append(move(arguments));
|
||||||
|
|
||||||
|
return exec(result.value().first(), move(new_arguments), move(environment));
|
||||||
|
}
|
||||||
|
|
||||||
// The bulk of exec() is done by do_exec(), which ensures that all locals
|
// The bulk of exec() is done by do_exec(), which ensures that all locals
|
||||||
// are cleaned up by the time we yield-teleport below.
|
// are cleaned up by the time we yield-teleport below.
|
||||||
|
|
|
@ -318,7 +318,7 @@ private:
|
||||||
int alloc_fd(int first_candidate_fd = 0);
|
int alloc_fd(int first_candidate_fd = 0);
|
||||||
void disown_all_shared_buffers();
|
void disown_all_shared_buffers();
|
||||||
|
|
||||||
KResultOr<String> find_shebang_interpreter_for_executable(const String& executable_path);
|
KResultOr<Vector<String>> find_shebang_interpreter_for_executable(const String& executable_path);
|
||||||
|
|
||||||
Thread* m_main_thread { nullptr };
|
Thread* m_main_thread { nullptr };
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue