Luna/libos/src/Process.cpp
apio 2abb43d709
Some checks failed
continuous-integration/drone/push Build is failing
kernel+libos: Call Vector::try_reserve where it is appropriate
2023-08-22 11:54:00 +02:00

139 lines
4.4 KiB
C++

/**
* @file Process.cpp
* @author apio (cloudapio.eu)
* @brief Functions to manipulate processes.
*
* @copyright Copyright (c) 2023, the Luna authors.
*
*/
#include <errno.h>
#include <os/Process.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
extern char** environ;
namespace os
{
Result<pid_t> Process::fork()
{
long rc = syscall(SYS_fork);
return Result<pid_t>::from_syscall(rc);
}
Result<void> Process::exec(StringView path, Slice<String> args, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
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);
}
Result<void> Process::exec(StringView path, Slice<StringView> args, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
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);
}
Result<void> Process::exec(StringView path, Slice<String> args, Slice<String> env, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
Vector<const char*> envp;
TRY(envp.try_reserve(env.size() + 1));
for (const auto& arg : env) { TRY(envp.try_append(arg.chars())); }
TRY(envp.try_append(nullptr));
if (search_in_path) execvpe(path.chars(), const_cast<char**>(argv.data()), const_cast<char**>(envp.data()));
else
execve(path.chars(), const_cast<char**>(argv.data()), const_cast<char**>(envp.data()));
return err(errno);
}
static Result<pid_t> do_spawn(const char* path, char** argv, char** envp, bool use_path)
{
pid_t child = fork();
if (child < 0) return err(errno);
if (child == 0)
{
if (use_path) execvpe(path, argv, envp);
else
execve(path, argv, envp);
_exit(127);
}
return child;
}
Result<pid_t> Process::spawn(StringView path, Slice<String> args, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
return do_spawn(path.chars(), const_cast<char**>(argv.data()), environ, search_in_path);
}
Result<pid_t> Process::spawn(StringView path, Slice<StringView> args, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
return do_spawn(path.chars(), const_cast<char**>(argv.data()), environ, search_in_path);
}
Result<pid_t> Process::spawn(StringView path, Slice<String> args, Slice<String> env, bool search_in_path)
{
Vector<const char*> argv;
TRY(argv.try_reserve(args.size() + 1));
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
Vector<const char*> envp;
TRY(envp.try_reserve(env.size() + 1));
for (const auto& arg : env) { TRY(envp.try_append(arg.chars())); }
TRY(envp.try_append(nullptr));
return do_spawn(path.chars(), const_cast<char**>(argv.data()), const_cast<char**>(envp.data()), search_in_path);
}
Result<pid_t> Process::wait(pid_t child, int* status, int options)
{
long rc = syscall(SYS_waitpid, child, status, options);
return Result<pid_t>::from_syscall(rc);
}
Result<void> Process::kill(pid_t pid, int signo)
{
long rc = syscall(SYS_kill, pid, signo);
return Result<void>::from_syscall(rc);
}
[[noreturn]] void Process::exit(int status)
{
::exit(status);
}
}