libos: Add Process::exec
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-04-18 18:39:37 +02:00
parent 6ce125d286
commit 00832163d4
Signed by: apio
GPG Key ID: B8A7D06E42258954
5 changed files with 95 additions and 39 deletions

View File

@ -15,44 +15,17 @@
using os::File; using os::File;
static Result<Vector<char*>> split_command_into_argv(StringView cmd, char** out) static Result<Vector<String>> split_command_into_args(StringView cmd)
{ {
char* str = strdup(cmd.chars()); return cmd.split(" \n"_sv);
Vector<char*> result;
char* segment = strtok(str, " \n");
TRY(result.try_append(segment));
if (segment == NULL) return result;
for (;;)
{
segment = strtok(NULL, " \n");
TRY(result.try_append(segment));
if (segment == NULL) return result;
}
if (out) *out = str;
return result;
} }
[[noreturn]] static void execute_command(StringView command) static Result<void> execute_command(StringView command)
{ {
Vector<char*> argv; auto args = TRY(split_command_into_args(command));
bool ok = split_command_into_argv(command, nullptr).try_move_value_or_error(argv, errno); if (args.size() < 1) exit(0);
if (!ok)
{
perror("failed to parse command");
exit(1);
}
if (argv[0] == NULL) exit(0); return os::Process::exec(args[0].view(), args.slice());
execvp(argv[0], argv.data());
perror(argv[0]);
exit(1);
} }
Result<int> luna_main(int argc, char** argv) Result<int> luna_main(int argc, char** argv)
@ -68,7 +41,7 @@ Result<int> luna_main(int argc, char** argv)
parser.add_value_argument(command, 'c', "command"_sv, true); parser.add_value_argument(command, 'c', "command"_sv, true);
parser.parse(argc, argv); parser.parse(argc, argv);
if (!command.is_empty()) execute_command(command); if (!command.is_empty()) TRY(execute_command(command));
if (path == "-") if (path == "-")
{ {
@ -98,10 +71,10 @@ Result<int> luna_main(int argc, char** argv)
{ {
char* copy = nullptr; char* copy = nullptr;
auto args = TRY(split_command_into_argv(cmd.view(), &copy)); auto args = TRY(split_command_into_args(cmd.view()));
check("cd"_sv == args[0]); check(args[0].view() == "cd");
if (args.size() == 2) if (args.size() == 1)
{ {
auto home = TRY(os::FileSystem::home_directory()); auto home = TRY(os::FileSystem::home_directory());
if (chdir(home.chars()) < 0) perror("cd"); if (chdir(home.chars()) < 0) perror("cd");
@ -109,14 +82,14 @@ Result<int> luna_main(int argc, char** argv)
continue; continue;
} }
if (chdir(args[1]) < 0) perror("cd"); if (chdir(args[1].chars()) < 0) perror("cd");
free(copy); free(copy);
continue; continue;
} }
pid_t child = TRY(os::Process::fork()); pid_t child = TRY(os::Process::fork());
if (child == 0) { execute_command(cmd.view()); } if (child == 0) { TRY(execute_command(cmd.view())); }
if (waitpid(child, NULL, 0) < 0) if (waitpid(child, NULL, 0) < 0)
{ {

View File

@ -0,0 +1,52 @@
#pragma once
#include <luna/Types.h>
template <typename T> class Slice
{
typedef T* Iterator;
typedef const T* ConstIterator;
public:
Slice(T* data, usize size) : m_data(data), m_size(size)
{
}
const T* data() const
{
return m_data;
}
T* data()
{
return m_data;
}
usize size() const
{
return m_size;
}
Iterator begin()
{
return m_data;
}
ConstIterator begin() const
{
return m_data;
}
Iterator end()
{
return m_data + m_size;
}
ConstIterator end() const
{
return m_data + m_size;
}
private:
T* const m_data;
const usize m_size;
};

View File

@ -2,6 +2,7 @@
#include <luna/Alloc.h> #include <luna/Alloc.h>
#include <luna/CString.h> #include <luna/CString.h>
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/Slice.h>
#include <luna/Types.h> #include <luna/Types.h>
template <typename T> class Vector template <typename T> class Vector
@ -156,6 +157,18 @@ template <typename T> class Vector
return m_data; return m_data;
} }
Slice<T> slice()
{
return { m_data, m_size };
}
Slice<T> slice(usize index)
{
check(index < m_size);
return { m_data + index, m_size - index };
}
usize capacity() const usize capacity() const
{ {
return m_capacity; return m_capacity;

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <luna/Result.h> #include <luna/Result.h>
#include <luna/String.h>
#include <sys/types.h> #include <sys/types.h>
namespace os namespace os
@ -8,5 +9,7 @@ namespace os
{ {
public: public:
static Result<pid_t> fork(); static Result<pid_t> fork();
static Result<void> exec(StringView path, Slice<String> args, bool search_in_path = true);
}; };
} }

View File

@ -1,4 +1,6 @@
#include <os/Process.h> #include <os/Process.h>
#include <errno.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <unistd.h> #include <unistd.h>
@ -9,4 +11,17 @@ namespace os
long rc = syscall(SYS_fork); long rc = syscall(SYS_fork);
return Result<pid_t>::from_syscall(rc); return Result<pid_t>::from_syscall(rc);
} }
Result<void> Process::exec(StringView path, Slice<String> args, bool search_in_path)
{
Vector<const char*> argv;
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
if (search_in_path) execvp(path.chars(), const_cast<char**>(argv.data()));
else
execv(path.chars(), const_cast<char**>(argv.data()));
return err(errno);
}
} }