mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 21:57:35 +00:00
Shell: Update shebang handling logic
This bit of code was kept unmodified since it was first implemented, and I'm not entirely convinced that it ever actually worked :P This commit updates the code to use "modern" classes and constructs, and fixes an issue where the shebang would still contain the '#!' when it was passed to execvp(). Fixes #6774.
This commit is contained in:
parent
27bfb01f25
commit
6a9dced790
1 changed files with 17 additions and 13 deletions
|
@ -869,20 +869,24 @@ void Shell::execute_process(Vector<const char*>&& argv)
|
||||||
_exit(126);
|
_exit(126);
|
||||||
}
|
}
|
||||||
if (saved_errno == ENOENT) {
|
if (saved_errno == ENOENT) {
|
||||||
int shebang_fd = open(argv[0], O_RDONLY);
|
do {
|
||||||
auto close_argv = ScopeGuard([shebang_fd]() { if (shebang_fd >= 0) close(shebang_fd); });
|
auto file_result = Core::File::open(argv[0], Core::IODevice::OpenMode::ReadOnly);
|
||||||
char shebang[256] {};
|
if (file_result.is_error())
|
||||||
ssize_t num_read = -1;
|
break;
|
||||||
if ((shebang_fd >= 0) && ((num_read = read(shebang_fd, shebang, sizeof(shebang))) >= 2) && (StringView(shebang).starts_with("#!"))) {
|
auto& file = file_result.value();
|
||||||
StringView shebang_path_view(&shebang[2], num_read - 2);
|
auto line = file->read_line();
|
||||||
Optional<size_t> newline_pos = shebang_path_view.find_first_of("\n\r");
|
if (!line.starts_with("#!"))
|
||||||
shebang[newline_pos.has_value() ? (newline_pos.value() + 2) : num_read] = '\0';
|
break;
|
||||||
argv[0] = shebang;
|
GenericLexer shebang_lexer { line.substring_view(2) };
|
||||||
|
auto shebang = shebang_lexer.consume_until(is_any_of("\n\r")).to_string();
|
||||||
|
argv.prepend(shebang.characters());
|
||||||
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
||||||
if (rc < 0)
|
if (rc < 0) {
|
||||||
fprintf(stderr, "%s: Invalid interpreter \"%s\": %s\n", argv[0], &shebang[2], strerror(errno));
|
fprintf(stderr, "%s: Invalid interpreter \"%s\": %s\n", argv[0], shebang.characters(), strerror(errno));
|
||||||
} else
|
_exit(126);
|
||||||
fprintf(stderr, "%s: Command not found.\n", argv[0]);
|
}
|
||||||
|
} while (false);
|
||||||
|
fprintf(stderr, "%s: Command not found.\n", argv[0]);
|
||||||
} else {
|
} else {
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
fprintf(stderr, "Shell: %s: Is a directory\n", argv[0]);
|
fprintf(stderr, "Shell: %s: Is a directory\n", argv[0]);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue