Compare commits
31 Commits
939f443e9b
...
d67fcd2ec0
Author | SHA1 | Date | |
---|---|---|---|
d67fcd2ec0 | |||
f5c949733b | |||
ad6df7c142 | |||
77f8fcb32f | |||
2d4c5557b8 | |||
85fe2dbb38 | |||
7f78960698 | |||
e0c34c571a | |||
0c5584913a | |||
4eaf089b87 | |||
8d284defad | |||
92dc8ac177 | |||
225c2c3d66 | |||
8bfdd83669 | |||
82d1fef9f9 | |||
4214c8f826 | |||
cecc82d588 | |||
2620156fb4 | |||
797959a8a5 | |||
b1039f6200 | |||
798cf801a3 | |||
5015703e9d | |||
94d394b75e | |||
bb3b0d6cf9 | |||
5f2c5921ad | |||
654bbbf253 | |||
7567068fbf | |||
52a84c9948 | |||
6295a663f3 | |||
925d327682 | |||
5de0b3f428 |
@ -46,4 +46,3 @@ luna_app(socket-test.cpp socket-test)
|
||||
luna_app(socket-client.cpp socket-client)
|
||||
luna_app(input.cpp input)
|
||||
luna_app(shmem-test.cpp shmem-test)
|
||||
luna_app(gclient.cpp gclient)
|
||||
|
@ -1,20 +0,0 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/LocalClient.h>
|
||||
|
||||
Result<int> luna_main(int argc, char** argv)
|
||||
{
|
||||
StringView socket_path = "/tmp/wind.sock";
|
||||
|
||||
os::ArgumentParser parser;
|
||||
parser.add_description("A graphical user interface client."_sv);
|
||||
parser.add_system_program_info("gclient"_sv);
|
||||
parser.add_value_argument(socket_path, 's', "socket"_sv, "the path for the local IPC socket"_sv);
|
||||
parser.parse(argc, argv);
|
||||
|
||||
auto client = TRY(os::LocalClient::connect(socket_path, false));
|
||||
|
||||
StringView message = "hello";
|
||||
TRY(client->send((const u8*)message.chars(), message.length()));
|
||||
|
||||
return 0;
|
||||
}
|
@ -562,7 +562,7 @@ namespace MemoryManager
|
||||
while (size--)
|
||||
{
|
||||
// Crossed a page boundary, gotta check the page tables again before touching any memory!!
|
||||
if ((user_ptr % ARCH_PAGE_SIZE) == 0)
|
||||
if (user_ptr % ARCH_PAGE_SIZE)
|
||||
{
|
||||
if (!validate_page_access(user_ptr, MMU::ReadWrite | MMU::User)) return false;
|
||||
}
|
||||
@ -590,7 +590,7 @@ namespace MemoryManager
|
||||
while (size--)
|
||||
{
|
||||
// Crossed a page boundary, gotta check the page tables again before touching any memory!!
|
||||
if ((user_ptr % ARCH_PAGE_SIZE) == 0)
|
||||
if (user_ptr % ARCH_PAGE_SIZE)
|
||||
{
|
||||
if (!validate_page_access(user_ptr, MMU::User)) return false;
|
||||
}
|
||||
|
@ -55,8 +55,7 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
|
||||
{
|
||||
auto path = TRY(MemoryManager::strdup_from_user(args[0]));
|
||||
auto argv = TRY(copy_string_vector_from_userspace(args[1]));
|
||||
Vector<String> envp;
|
||||
if (args[2]) envp = TRY(copy_string_vector_from_userspace(args[2]));
|
||||
auto envp = TRY(copy_string_vector_from_userspace(args[2]));
|
||||
|
||||
if ((calculate_userspace_stack_size(argv) + calculate_userspace_stack_size(envp)) > MAX_ARGV_STACK_SIZE)
|
||||
return err(E2BIG);
|
||||
|
@ -14,7 +14,6 @@ set(SOURCES
|
||||
src/Mode.cpp
|
||||
src/Prompt.cpp
|
||||
src/LocalServer.cpp
|
||||
src/LocalClient.cpp
|
||||
)
|
||||
|
||||
add_library(os ${SOURCES})
|
||||
|
@ -1,90 +0,0 @@
|
||||
#pragma once
|
||||
#include <luna/SharedPtr.h>
|
||||
#include <luna/StringView.h>
|
||||
|
||||
namespace os
|
||||
{
|
||||
/**
|
||||
* @brief A client used to connect to a local server socket.
|
||||
*/
|
||||
class LocalClient : public Shareable
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a new client object and connect it to a local server.
|
||||
*
|
||||
* @param path The path of the server socket to connect to.
|
||||
* @param blocking Whether the client should block if no data is available and recv() is called.
|
||||
* @return Result<SharedPtr<LocalClient>> An error, or a new client object.
|
||||
*/
|
||||
static Result<SharedPtr<LocalClient>> connect(StringView path, bool blocking);
|
||||
|
||||
/**
|
||||
* @brief Return the underlying socket file descriptor used by this object.
|
||||
*
|
||||
* @return int The file descriptor.
|
||||
*/
|
||||
int fd() const
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read arbitrary data from the server. The call will block if there is no data and this object has not
|
||||
* been created as non-blocking.
|
||||
*
|
||||
* @param buf The buffer to read data into.
|
||||
* @param length The maximum amount of bytes to read.
|
||||
* @return Result<usize> An error, or the number of bytes read.
|
||||
*/
|
||||
Result<usize> recv(u8* buf, usize length);
|
||||
|
||||
/**
|
||||
* @brief Read an object from the server. The call will block if there is no data and this object has not been
|
||||
* created as non-blocking.
|
||||
*
|
||||
* @tparam T The type of the object.
|
||||
* @param out A reference to the object to read data into.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
template <typename T> Result<void> recv_typed(T& out)
|
||||
{
|
||||
TRY(recv((u8*)&out, sizeof(T)));
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send arbitrary data to the server.
|
||||
*
|
||||
* @param buf The buffer to send data from.
|
||||
* @param length The amount of bytes to send.
|
||||
* @return Result<usize> An error, or the number of bytes actually sent.
|
||||
*/
|
||||
Result<usize> send(const u8* buf, usize length);
|
||||
|
||||
/**
|
||||
* @brief Send an object to the server.
|
||||
*
|
||||
* @tparam T The type of the object.
|
||||
* @param out A reference to the object to send data from.
|
||||
* @return Result<void> Whether the operation succeded.
|
||||
*/
|
||||
template <typename T> Result<void> send_typed(const T& out)
|
||||
{
|
||||
TRY(send((const u8*)&out, sizeof(T)));
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disconnect from the attached server.
|
||||
*
|
||||
* This will make any further reads on this connection return ECONNRESET, and will make this object invalid.
|
||||
*/
|
||||
void disconnect();
|
||||
|
||||
~LocalClient();
|
||||
|
||||
private:
|
||||
int m_fd;
|
||||
};
|
||||
}
|
@ -59,37 +59,6 @@ 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;
|
||||
|
||||
|
@ -1,59 +0,0 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <os/LocalClient.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace os
|
||||
{
|
||||
Result<SharedPtr<LocalClient>> LocalClient::connect(StringView path, bool blocking)
|
||||
{
|
||||
auto client = TRY(make_shared<LocalClient>());
|
||||
|
||||
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sockfd < 0) return err(errno);
|
||||
|
||||
struct sockaddr_un un;
|
||||
un.sun_family = AF_UNIX;
|
||||
strncpy(un.sun_path, path.chars(), sizeof(un.sun_path));
|
||||
|
||||
if (::connect(sockfd, (struct sockaddr*)&un, sizeof(un)) < 0)
|
||||
{
|
||||
close(sockfd);
|
||||
return err(errno);
|
||||
}
|
||||
|
||||
if (!blocking) { fcntl(sockfd, F_SETFL, O_NONBLOCK); }
|
||||
|
||||
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
client->m_fd = sockfd;
|
||||
return client;
|
||||
}
|
||||
|
||||
LocalClient::~LocalClient()
|
||||
{
|
||||
close(m_fd);
|
||||
}
|
||||
|
||||
Result<usize> LocalClient::recv(u8* buf, usize length)
|
||||
{
|
||||
ssize_t nread = read(m_fd, buf, length);
|
||||
if (nread < 0) return err(errno);
|
||||
return nread;
|
||||
}
|
||||
|
||||
Result<usize> LocalClient::send(const u8* buf, usize length)
|
||||
{
|
||||
ssize_t nwrite = write(m_fd, buf, length);
|
||||
if (nwrite < 0) return err(errno);
|
||||
return nwrite;
|
||||
}
|
||||
|
||||
void LocalClient::disconnect()
|
||||
{
|
||||
close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
@ -8,14 +8,11 @@
|
||||
*/
|
||||
|
||||
#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()
|
||||
@ -67,58 +64,6 @@ 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);
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <os/ArgumentParser.h>
|
||||
#include <os/File.h>
|
||||
#include <os/LocalServer.h>
|
||||
#include <os/Process.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -46,6 +45,9 @@ Result<int> luna_main(int argc, char** argv)
|
||||
|
||||
auto screen = TRY(Screen::open());
|
||||
|
||||
auto server = TRY(os::LocalServer::create(socket_path, false));
|
||||
TRY(server->listen(20));
|
||||
|
||||
Mouse mouse_pointer { screen.canvas() };
|
||||
|
||||
ioctl(STDIN_FILENO, TTYSETGFX, 1);
|
||||
@ -71,12 +73,6 @@ Result<int> luna_main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
auto server = TRY(os::LocalServer::create(socket_path, false));
|
||||
TRY(server->listen(20));
|
||||
|
||||
StringView args[] = { "/usr/bin/gclient"_sv };
|
||||
TRY(os::Process::spawn("/usr/bin/gclient"_sv, Slice<StringView> { args, 1 }, false));
|
||||
|
||||
ui::Color background = ui::BLACK;
|
||||
|
||||
TRY(make<Window>(ui::Rect { 200, 200, 600, 400 }, ui::GREEN, "Calculator"_sv));
|
||||
@ -100,7 +96,7 @@ Result<int> luna_main(int argc, char** argv)
|
||||
|
||||
int rc = poll(fds, 3, 1000);
|
||||
if (!rc) continue;
|
||||
if (rc < 0 && errno != EINTR) { os::println("poll: error: %s", strerror(errno)); }
|
||||
if (rc < 0) { os::println("poll: error: %s", strerror(errno)); }
|
||||
|
||||
if (fds[0].revents & POLLIN)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user