2023-06-09 20:45:06 +00:00
|
|
|
/**
|
|
|
|
* @file Process.cpp
|
|
|
|
* @author apio (cloudapio.eu)
|
|
|
|
* @brief Functions to manipulate processes.
|
|
|
|
*
|
|
|
|
* @copyright Copyright (c) 2023, the Luna authors.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2023-04-18 16:39:37 +00:00
|
|
|
#include <errno.h>
|
2023-05-02 08:50:39 +00:00
|
|
|
#include <os/Process.h>
|
2023-07-21 19:21:08 +00:00
|
|
|
#include <stdlib.h>
|
2023-04-18 16:16:24 +00:00
|
|
|
#include <sys/syscall.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
2023-08-07 20:49:12 +00:00
|
|
|
extern char** environ;
|
|
|
|
|
2023-04-18 16:16:24 +00:00
|
|
|
namespace os
|
|
|
|
{
|
|
|
|
Result<pid_t> Process::fork()
|
|
|
|
{
|
|
|
|
long rc = syscall(SYS_fork);
|
|
|
|
return Result<pid_t>::from_syscall(rc);
|
|
|
|
}
|
2023-04-18 16:39:37 +00:00
|
|
|
|
|
|
|
Result<void> Process::exec(StringView path, Slice<String> args, bool search_in_path)
|
|
|
|
{
|
|
|
|
Vector<const char*> argv;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-05-20 10:47:10 +00:00
|
|
|
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;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-04-18 16:39:37 +00:00
|
|
|
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);
|
|
|
|
}
|
2023-04-22 11:54:47 +00:00
|
|
|
|
|
|
|
Result<void> Process::exec(StringView path, Slice<String> args, Slice<String> env, bool search_in_path)
|
|
|
|
{
|
|
|
|
Vector<const char*> argv;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-04-22 11:54:47 +00:00
|
|
|
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
|
|
|
|
TRY(argv.try_append(nullptr));
|
|
|
|
|
|
|
|
Vector<const char*> envp;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(envp.try_reserve(env.size() + 1));
|
2023-04-22 11:54:47 +00:00
|
|
|
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);
|
|
|
|
}
|
2023-06-09 21:12:31 +00:00
|
|
|
|
2023-08-07 20:49:12 +00:00
|
|
|
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;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-08-07 20:49:12 +00:00
|
|
|
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;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-08-07 20:53:37 +00:00
|
|
|
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
|
2023-08-07 20:49:12 +00:00
|
|
|
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;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(argv.try_reserve(args.size() + 1));
|
2023-08-07 20:49:12 +00:00
|
|
|
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
|
|
|
|
TRY(argv.try_append(nullptr));
|
|
|
|
|
|
|
|
Vector<const char*> envp;
|
2023-08-22 09:54:00 +00:00
|
|
|
TRY(envp.try_reserve(env.size() + 1));
|
2023-08-07 20:49:12 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-06-09 21:12:31 +00:00
|
|
|
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);
|
|
|
|
}
|
2023-07-10 20:17:05 +00:00
|
|
|
|
|
|
|
Result<void> Process::kill(pid_t pid, int signo)
|
|
|
|
{
|
|
|
|
long rc = syscall(SYS_kill, pid, signo);
|
|
|
|
return Result<void>::from_syscall(rc);
|
|
|
|
}
|
2023-07-21 19:21:08 +00:00
|
|
|
|
|
|
|
[[noreturn]] void Process::exit(int status)
|
|
|
|
{
|
|
|
|
::exit(status);
|
|
|
|
}
|
2023-04-18 16:16:24 +00:00
|
|
|
}
|