diff options
Diffstat (limited to 'Shell')
-rw-r--r-- | Shell/main.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/Shell/main.cpp b/Shell/main.cpp index f59dcf1850..5a1cbdf578 100644 --- a/Shell/main.cpp +++ b/Shell/main.cpp @@ -28,6 +28,7 @@ #include "Parser.h" #include <AK/FileSystemPath.h> #include <AK/Function.h> +#include <AK/ScopeGuard.h> #include <AK/StringBuilder.h> #include <LibCore/DirIterator.h> #include <LibCore/ElapsedTimer.h> @@ -580,7 +581,7 @@ static bool handle_builtin(int argc, const char** argv, int& retval) class FileDescriptionCollector { public: - FileDescriptionCollector() { } + FileDescriptionCollector() {} ~FileDescriptionCollector() { collect(); } void collect() @@ -906,7 +907,17 @@ static int run_command(const String& cmd) int rc = execvp(argv[0], const_cast<char* const*>(argv.data())); if (rc < 0) { if (errno == ENOENT) { - fprintf(stderr, "%s: Command not found.\n", argv[0]); + int shebang_fd = open(argv[0], O_RDONLY); + auto close_argv = ScopeGuard([shebang_fd]() { if (shebang_fd >= 0) close(shebang_fd); }); + char shebang[256] {}; + ssize_t num_read = -1; + if ((shebang_fd >= 0) && ((num_read = read(shebang_fd, shebang, sizeof(shebang))) >= 2) && (StringView(shebang).starts_with("#!"))) { + StringView shebang_path_view(&shebang[2], num_read - 2); + Optional<size_t> newline_pos = shebang_path_view.find_first_of("\n\r"); + shebang[newline_pos.has_value() ? newline_pos.value() : num_read] = '\0'; + fprintf(stderr, "%s: Invalid interpreter \"%s\": %s\n", argv[0], &shebang[2], strerror(ENOENT)); + } else + fprintf(stderr, "%s: Command not found.\n", argv[0]); } else { struct stat st; if (stat(argv[0], &st) == 0 && S_ISDIR(st.st_mode)) { @@ -915,7 +926,7 @@ static int run_command(const String& cmd) } fprintf(stderr, "execvp(%s): %s\n", argv[0], strerror(errno)); } - _exit(1); + _exit(126); } ASSERT_NOT_REACHED(); } |