libos: Add Process::exec
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
6ce125d286
commit
00832163d4
51
apps/sh.cpp
51
apps/sh.cpp
@ -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(), ©));
|
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)
|
||||||
{
|
{
|
||||||
|
52
libluna/include/luna/Slice.h
Normal file
52
libluna/include/luna/Slice.h
Normal 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;
|
||||||
|
};
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user