62 lines
1.8 KiB
C++
62 lines
1.8 KiB
C++
|
#include "binfmt/Script.h"
|
||
|
#include "binfmt/ELF.h"
|
||
|
#include "thread/Scheduler.h"
|
||
|
|
||
|
#define SHEBANG "#!"
|
||
|
|
||
|
Result<bool> ScriptLoader::sniff()
|
||
|
{
|
||
|
u8 buf[2];
|
||
|
usize nread = TRY(m_inode->read(buf, 0, sizeof buf));
|
||
|
if (nread < 2) return false;
|
||
|
|
||
|
return !memcmp(buf, SHEBANG, 2);
|
||
|
}
|
||
|
|
||
|
Result<u64> ScriptLoader::load(AddressSpace* space)
|
||
|
{
|
||
|
u8 buf[256];
|
||
|
usize nread = TRY(m_inode->read(buf, 2, 255));
|
||
|
if (!nread) return err(ENOEXEC);
|
||
|
for (usize i = 0; i < nread; i++)
|
||
|
{
|
||
|
if (buf[i] == '\n') buf[i] = '\0';
|
||
|
else if (buf[i] == '\r' && (i + 1) < nread && buf[i + 1] == '\n')
|
||
|
buf[i] = buf[i + 1] = '\0';
|
||
|
else
|
||
|
continue;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
auto view = StringView { (const char*)buf };
|
||
|
m_interpreter_cmdline = TRY(view.split(" "));
|
||
|
if (!m_interpreter_cmdline.size()) return err(ENOEXEC);
|
||
|
|
||
|
auto& interpreter_path = m_interpreter_cmdline[0];
|
||
|
auto* current = Scheduler::current();
|
||
|
|
||
|
auto interpreter =
|
||
|
TRY(VFS::resolve_path(interpreter_path.chars(), current->auth, current->current_directory, true));
|
||
|
if (!VFS::can_execute(interpreter, current->auth)) return err(EACCES);
|
||
|
|
||
|
auto loader = TRY(ELFLoader::create(interpreter, nullptr));
|
||
|
return loader->load(space);
|
||
|
}
|
||
|
|
||
|
Result<Vector<String>> ScriptLoader::cmdline(Vector<String> args)
|
||
|
{
|
||
|
Vector<String> new_args;
|
||
|
for (auto& arg : m_interpreter_cmdline) { TRY(new_args.try_append(move(arg))); }
|
||
|
for (auto& arg : args) { TRY(new_args.try_append(move(arg))); }
|
||
|
return new_args;
|
||
|
}
|
||
|
|
||
|
ScriptLoader::ScriptLoader(SharedPtr<VFS::Inode> inode) : BinaryFormatLoader(inode)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
Result<SharedPtr<BinaryFormatLoader>> ScriptLoader::create(SharedPtr<VFS::Inode> inode, void*)
|
||
|
{
|
||
|
return (SharedPtr<BinaryFormatLoader>)TRY(make_shared<ScriptLoader>(inode));
|
||
|
}
|