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

This commit is contained in:
apio 2023-08-07 22:49:12 +02:00
parent 097353e779
commit 77ebdda2e0
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 86 additions and 0 deletions

View File

@ -59,6 +59,37 @@ namespace os
*/
static Result<void> exec(StringView path, Slice<String> args, Slice<String> env, bool search_in_path = true);
/**
* @brief Spawn a new process from an executable file.
*
* @param path The new executable's path.
* @param args The argument list to pass to the new process.
* @param search_in_path Determines whether to search in the system binary directories if path is just a name.
* @return Result<pid_t> An error, or the process ID of the new process.
*/
static Result<pid_t> spawn(StringView path, Slice<String> args, bool search_in_path = true);
/**
* @brief Spawn a new process from an executable file.
*
* @param path The new executable's path.
* @param args The argument list to pass to the new process.
* @param search_in_path Determines whether to search in the system binary directories if path is just a name.
* @return Result<pid_t> An error, or the process ID of the new process.
*/
static Result<pid_t> spawn(StringView path, Slice<StringView> args, bool search_in_path = true);
/**
* @brief Spawn a new process from an executable file.
*
* @param path The new executable's path.
* @param args The argument list to pass to the new process.
* @param env The environment to pass to the new process, instead of the current environment.
* @param search_in_path Determines whether to search in the system binary directories if path is just a name.
* @return Result<pid_t> An error, or the process ID of the new process.
*/
static Result<pid_t> spawn(StringView path, Slice<String> args, Slice<String> env, bool search_in_path = true);
// To use as the child argument to wait() to wait for any child.
static constexpr pid_t ANY_CHILD = -1;

View File

@ -8,11 +8,14 @@
*/
#include <errno.h>
#include <luna/DebugLog.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()
@ -64,6 +67,58 @@ namespace os
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;
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;
for (const auto& arg : args)
{
TRY(argv.try_append(arg.chars()));
dbgln("os::Process:spawn() adding new argument: %s", arg.chars());
}
TRY(argv.try_append(nullptr));
dbgln("os::Process:spawn() invoking do_spawn(): path=%s, argv=%p, envp=%p", path.chars(),
const_cast<char**>(argv.data()), environ);
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;
for (const auto& arg : args) { TRY(argv.try_append(arg.chars())); }
TRY(argv.try_append(nullptr));
Vector<const char*> envp;
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);