libc: unify use of namespaces
This patch unifies the patterns of using the 'Genode' and 'Libc' namespaces. Types defined in the 'internal/' headers reside in the 'Libc' namespace. The code in the headers does not need to use the 'Libc::' prefix. Compilation units import the 'Libc' namespace after the definition of local types. Local types reside in the 'Libc' namespace (and should eventually move to an 'internal/' header). Since the 'Libc' namespace imports the 'Genode' namespace, there is no need to use the 'Genode::' prefix. Consequently, code in the compilation units rarely need to qualify the 'Genode' or 'Libc' namespaces. There are a few cases where the 'Libc', the 'Genode', and the global (libc) namespaces are ambigious. In these cases, an explicit clarification is needed: - 'Genode::Allocator' differs from 'Libc::Allocator'. - 'Genode::Env' differs from 'Libc::Env'. - Genode's string functions (strcmp, memcpy, strcpy) conflict with the names of the (global) libc functions. - There exist both 'Genode::uint64_t' and the libc'c 'uint64_t'. Issue #3497
This commit is contained in:
parent
bf92232698
commit
648bcd1505
|
@ -962,9 +962,9 @@ _ZN4Libc19Select_handler_baseD2Ev T
|
||||||
_ZN4Libc10resume_allEv T
|
_ZN4Libc10resume_allEv T
|
||||||
_ZN4Libc7suspendERNS_15Suspend_functorEm T
|
_ZN4Libc7suspendERNS_15Suspend_functorEm T
|
||||||
_Z16pthread_registryv T
|
_Z16pthread_registryv T
|
||||||
_ZN16Pthread_registry6insertEP7pthread T
|
_ZN4Libc16Pthread_registry6insertERNS_7PthreadE T
|
||||||
_ZN16Pthread_registry6removeEP7pthread T
|
_ZN4Libc16Pthread_registry6removeERNS_7PthreadE T
|
||||||
_ZN16Pthread_registry8containsEP7pthread T
|
_ZN4Libc16Pthread_registry8containsERNS_7PthreadE T
|
||||||
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
|
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
|
||||||
_ZN4Libc14pthread_createEPP7pthreadRN6Genode6ThreadE T
|
_ZN4Libc14pthread_createEPP7pthreadRN6Genode6ThreadE T
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
|
|
||||||
using namespace Libc;
|
using namespace Libc;
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
|
|
||||||
static Allocator *_alloc_ptr;
|
static Allocator *_alloc_ptr;
|
||||||
|
@ -149,7 +148,7 @@ void File_descriptor::path(char const *newpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newpath) {
|
if (newpath) {
|
||||||
Genode::size_t const path_size = ::strlen(newpath) + 1;
|
size_t const path_size = ::strlen(newpath) + 1;
|
||||||
char *buf = (char*)_alloc_ptr->alloc(path_size);
|
char *buf = (char*)_alloc_ptr->alloc(path_size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
error("could not allocate path buffer for libc_fd ", libc_fd);
|
error("could not allocate path buffer for libc_fd ", libc_fd);
|
||||||
|
|
|
@ -56,7 +56,7 @@ using namespace Libc;
|
||||||
|
|
||||||
Libc::Mmap_registry *Libc::mmap_registry()
|
Libc::Mmap_registry *Libc::mmap_registry()
|
||||||
{
|
{
|
||||||
static Libc::Mmap_registry registry;
|
static Mmap_registry registry;
|
||||||
return ®istry;
|
return ®istry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ struct Scanner_policy_path_element
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Genode::Token<Scanner_policy_path_element> Path_element_token;
|
typedef Token<Scanner_policy_path_element> Path_element_token;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +126,7 @@ void Libc::resolve_symlinks(char const *path, Absolute_path &resolved_path)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
next_iteration_working_path.append_element(path_element);
|
next_iteration_working_path.append_element(path_element);
|
||||||
} catch (Genode::Path_base::Path_too_long) {
|
} catch (Path_base::Path_too_long) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
throw Symlink_resolve_error();
|
throw Symlink_resolve_error();
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ void Libc::resolve_symlinks(char const *path, Absolute_path &resolved_path)
|
||||||
next_iteration_working_path.strip_last_element();
|
next_iteration_working_path.strip_last_element();
|
||||||
try {
|
try {
|
||||||
next_iteration_working_path.append_element(symlink_target);
|
next_iteration_working_path.append_element(symlink_target);
|
||||||
} catch (Genode::Path_base::Path_too_long) {
|
} catch (Path_base::Path_too_long) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
throw Symlink_resolve_error();
|
throw Symlink_resolve_error();
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ static void resolve_symlinks_except_last_element(char const *path, Absolute_path
|
||||||
absolute_path_last_element.keep_only_last_element();
|
absolute_path_last_element.keep_only_last_element();
|
||||||
try {
|
try {
|
||||||
resolved_path.append_element(absolute_path_last_element.base());
|
resolved_path.append_element(absolute_path_last_element.base());
|
||||||
} catch (Genode::Path_base::Path_too_long) {
|
} catch (Path_base::Path_too_long) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
throw Symlink_resolve_error();
|
throw Symlink_resolve_error();
|
||||||
}
|
}
|
||||||
|
@ -233,10 +233,9 @@ extern "C" int chdir(const char *path)
|
||||||
*/
|
*/
|
||||||
__SYS_(int, close, (int libc_fd),
|
__SYS_(int, close, (int libc_fd),
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
return (!fd || !fd->plugin)
|
return (!fd || !fd->plugin)
|
||||||
? Libc::Errno(EBADF)
|
? Errno(EBADF)
|
||||||
: fd->plugin->close(fd);
|
: fd->plugin->close(fd);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -317,14 +316,13 @@ __SYS_(int, fstatat, (int libc_fd, char const *path, struct stat *buf, int flags
|
||||||
return stat(path, buf);
|
return stat(path, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
Libc::Absolute_path abs_path;
|
Absolute_path abs_path;
|
||||||
|
|
||||||
if (libc_fd == AT_FDCWD) {
|
if (libc_fd == AT_FDCWD) {
|
||||||
abs_path = cwd();
|
abs_path = cwd();
|
||||||
abs_path.append_element(path);
|
abs_path.append_element(path);
|
||||||
} else {
|
} else {
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -398,7 +396,7 @@ __SYS_(void *, mmap, (void *addr, ::size_t length,
|
||||||
/* handle requests for anonymous memory */
|
/* handle requests for anonymous memory */
|
||||||
if (!addr && libc_fd == -1) {
|
if (!addr && libc_fd == -1) {
|
||||||
bool const executable = prot & PROT_EXEC;
|
bool const executable = prot & PROT_EXEC;
|
||||||
void *start = Libc::mem_alloc(executable)->alloc(length, PAGE_SHIFT);
|
void *start = mem_alloc(executable)->alloc(length, PAGE_SHIFT);
|
||||||
if (!start) {
|
if (!start) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
|
@ -410,7 +408,7 @@ __SYS_(void *, mmap, (void *addr, ::size_t length,
|
||||||
/* lookup plugin responsible for file descriptor */
|
/* lookup plugin responsible for file descriptor */
|
||||||
File_descriptor *fd = libc_fd_to_fd(libc_fd, "mmap");
|
File_descriptor *fd = libc_fd_to_fd(libc_fd, "mmap");
|
||||||
if (!fd || !fd->plugin || !fd->plugin->supports_mmap()) {
|
if (!fd || !fd->plugin || !fd->plugin->supports_mmap()) {
|
||||||
Genode::warning("mmap not supported for file descriptor ", libc_fd);
|
warning("mmap not supported for file descriptor ", libc_fd);
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +422,7 @@ __SYS_(void *, mmap, (void *addr, ::size_t length,
|
||||||
extern "C" int munmap(void *start, ::size_t length)
|
extern "C" int munmap(void *start, ::size_t length)
|
||||||
{
|
{
|
||||||
if (!mmap_registry()->registered(start)) {
|
if (!mmap_registry()->registered(start)) {
|
||||||
Genode::warning("munmap: could not lookup plugin for address ", start);
|
warning("munmap: could not lookup plugin for address ", start);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -442,8 +440,8 @@ extern "C" int munmap(void *start, ::size_t length)
|
||||||
else {
|
else {
|
||||||
bool const executable = true;
|
bool const executable = true;
|
||||||
/* XXX another metadata handling required to track anonymous memory */
|
/* XXX another metadata handling required to track anonymous memory */
|
||||||
Libc::mem_alloc(!executable)->free(start);
|
mem_alloc(!executable)->free(start);
|
||||||
Libc::mem_alloc(executable)->free(start);
|
mem_alloc(executable)->free(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmap_registry()->remove(start);
|
mmap_registry()->remove(start);
|
||||||
|
@ -454,7 +452,7 @@ extern "C" int munmap(void *start, ::size_t length)
|
||||||
__SYS_(int, msync, (void *start, ::size_t len, int flags),
|
__SYS_(int, msync, (void *start, ::size_t len, int flags),
|
||||||
{
|
{
|
||||||
if (!mmap_registry()->registered(start)) {
|
if (!mmap_registry()->registered(start)) {
|
||||||
Genode::warning("munmap: could not lookup plugin for address ", start);
|
warning("munmap: could not lookup plugin for address ", start);
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -503,13 +501,13 @@ __SYS_(int, open, (const char *pathname, int flags, ...),
|
||||||
plugin = plugin_registry()->get_plugin_for_open(resolved_path.base(), flags);
|
plugin = plugin_registry()->get_plugin_for_open(resolved_path.base(), flags);
|
||||||
|
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
Genode::error("no plugin found for open(\"", pathname, "\", ", flags, ")");
|
error("no plugin found for open(\"", pathname, "\", ", flags, ")");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_fdo = plugin->open(resolved_path.base(), flags);
|
new_fdo = plugin->open(resolved_path.base(), flags);
|
||||||
if (!new_fdo) {
|
if (!new_fdo) {
|
||||||
Genode::error("plugin()->open(\"", pathname, "\") failed");
|
error("plugin()->open(\"", pathname, "\") failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
new_fdo->path(resolved_path.base());
|
new_fdo->path(resolved_path.base());
|
||||||
|
@ -530,14 +528,13 @@ __SYS_(int, openat, (int libc_fd, const char *path, int flags, ...),
|
||||||
return open(path, flags, mode);
|
return open(path, flags, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Libc::Absolute_path abs_path;
|
Absolute_path abs_path;
|
||||||
|
|
||||||
if (libc_fd == AT_FDCWD) {
|
if (libc_fd == AT_FDCWD) {
|
||||||
abs_path = cwd();
|
abs_path = cwd();
|
||||||
abs_path.append_element(path);
|
abs_path.append_element(path);
|
||||||
} else {
|
} else {
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
errno = EBADF;
|
errno = EBADF;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -561,12 +558,12 @@ extern "C" int pipe2(int pipefd[2], int flags)
|
||||||
plugin = plugin_registry()->get_plugin_for_pipe();
|
plugin = plugin_registry()->get_plugin_for_pipe();
|
||||||
|
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
Genode::error("no plugin found for pipe()");
|
error("no plugin found for pipe()");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin->pipe(pipefdo) == -1) {
|
if (plugin->pipe(pipefdo) == -1) {
|
||||||
Genode::error("plugin()->pipe() failed");
|
error("plugin()->pipe() failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +571,7 @@ extern "C" int pipe2(int pipefd[2], int flags)
|
||||||
int err = plugin->fcntl(pipefdo[0], F_SETFL, O_NONBLOCK)
|
int err = plugin->fcntl(pipefdo[0], F_SETFL, O_NONBLOCK)
|
||||||
| plugin->fcntl(pipefdo[1], F_SETFL, O_NONBLOCK);
|
| plugin->fcntl(pipefdo[1], F_SETFL, O_NONBLOCK);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
Genode::warning("pipe plugin does not support O_NONBLOCK");
|
warning("pipe plugin does not support O_NONBLOCK");
|
||||||
}
|
}
|
||||||
|
|
||||||
pipefd[0] = pipefdo[0]->libc_fd;
|
pipefd[0] = pipefdo[0]->libc_fd;
|
||||||
|
|
|
@ -39,23 +39,22 @@
|
||||||
#include <internal/suspend.h>
|
#include <internal/suspend.h>
|
||||||
#include <internal/resume.h>
|
#include <internal/resume.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
static pid_t fork_result;
|
static pid_t fork_result;
|
||||||
|
|
||||||
static Env *_env_ptr;
|
static Env *_env_ptr;
|
||||||
static Allocator *_alloc_ptr;
|
static Allocator *_alloc_ptr;
|
||||||
static Libc::Suspend *_suspend_ptr;
|
static Suspend *_suspend_ptr;
|
||||||
static Libc::Resume *_resume_ptr;
|
static Resume *_resume_ptr;
|
||||||
static Libc::Kernel_routine_scheduler *_kernel_routine_scheduler_ptr;
|
static Kernel_routine_scheduler *_kernel_routine_scheduler_ptr;
|
||||||
static Heap *_malloc_heap_ptr;
|
static Heap *_malloc_heap_ptr;
|
||||||
static void *_user_stack_base_ptr;
|
static void *_user_stack_base_ptr;
|
||||||
static size_t _user_stack_size;
|
static size_t _user_stack_size;
|
||||||
static int _pid;
|
static int _pid;
|
||||||
static int _pid_cnt;
|
static int _pid_cnt;
|
||||||
|
static Config_accessor const *_config_accessor_ptr;
|
||||||
static Libc::Config_accessor const *_config_accessor_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_fork(Env &env, Config_accessor const &config_accessor,
|
void Libc::init_fork(Env &env, Config_accessor const &config_accessor,
|
||||||
|
@ -420,18 +419,18 @@ struct Libc::Forked_child : Child_policy, Child_ready
|
||||||
|
|
||||||
void _handle_exit() { _resume.resume_all(); }
|
void _handle_exit() { _resume.resume_all(); }
|
||||||
|
|
||||||
Libc::Child_config _child_config;
|
Child_config _child_config;
|
||||||
|
|
||||||
Parent_services &_parent_services;
|
Parent_services &_parent_services;
|
||||||
Local_rom_services &_local_rom_services;
|
Local_rom_services &_local_rom_services;
|
||||||
Local_clone_service _local_clone_service;
|
Local_clone_service _local_clone_service;
|
||||||
Local_rom_service _config_rom_service;
|
Local_rom_service _config_rom_service;
|
||||||
|
|
||||||
struct Wait_fork_ready : Libc::Kernel_routine
|
struct Wait_fork_ready : Kernel_routine
|
||||||
{
|
{
|
||||||
Libc::Forked_child const &child;
|
Forked_child const &child;
|
||||||
|
|
||||||
Wait_fork_ready(Libc::Forked_child const &child) : child(child) { }
|
Wait_fork_ready(Forked_child const &child) : child(child) { }
|
||||||
|
|
||||||
void execute_in_kernel() override
|
void execute_in_kernel() override
|
||||||
{
|
{
|
||||||
|
@ -562,9 +561,9 @@ static void fork_kernel_routine()
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
Env &env = *_env_ptr;
|
Env &env = *_env_ptr;
|
||||||
Allocator &alloc = *_alloc_ptr;
|
Allocator &alloc = *_alloc_ptr;
|
||||||
Libc::Resume &resume = *_resume_ptr;
|
Resume &resume = *_resume_ptr;
|
||||||
|
|
||||||
pid_t const child_pid = ++_pid_cnt;
|
pid_t const child_pid = ++_pid_cnt;
|
||||||
|
|
||||||
|
@ -573,15 +572,15 @@ static void fork_kernel_routine()
|
||||||
|
|
||||||
static Libc::Parent_services parent_services(env, alloc);
|
static Libc::Parent_services parent_services(env, alloc);
|
||||||
|
|
||||||
static Libc::Local_rom_services local_rom_services(env, fork_ep, alloc);
|
static Local_rom_services local_rom_services(env, fork_ep, alloc);
|
||||||
|
|
||||||
static Forked_children forked_children { };
|
static Forked_children forked_children { };
|
||||||
_forked_children_ptr = &forked_children;
|
_forked_children_ptr = &forked_children;
|
||||||
|
|
||||||
Registered<Libc::Forked_child> &child = *new (alloc)
|
Registered<Forked_child> &child = *new (alloc)
|
||||||
Registered<Libc::Forked_child>(forked_children, env, fork_ep, alloc, resume,
|
Registered<Forked_child>(forked_children, env, fork_ep, alloc, resume,
|
||||||
child_pid, *_config_accessor_ptr,
|
child_pid, *_config_accessor_ptr,
|
||||||
parent_services, local_rom_services);
|
parent_services, local_rom_services);
|
||||||
|
|
||||||
fork_result = child_pid;
|
fork_result = child_pid;
|
||||||
|
|
||||||
|
@ -607,7 +606,7 @@ extern "C" pid_t __sys_fork(void)
|
||||||
_user_stack_base_ptr = (void *)mystack.base;
|
_user_stack_base_ptr = (void *)mystack.base;
|
||||||
_user_stack_size = mystack.top - mystack.base;
|
_user_stack_size = mystack.top - mystack.base;
|
||||||
|
|
||||||
struct Fork_kernel_routine : Libc::Kernel_routine
|
struct Fork_kernel_routine : Kernel_routine
|
||||||
{
|
{
|
||||||
void execute_in_kernel() override { fork_kernel_routine(); }
|
void execute_in_kernel() override { fork_kernel_routine(); }
|
||||||
|
|
||||||
|
@ -619,7 +618,7 @@ extern "C" pid_t __sys_fork(void)
|
||||||
|
|
||||||
_kernel_routine_scheduler_ptr->register_kernel_routine(kernel_routine);
|
_kernel_routine_scheduler_ptr->register_kernel_routine(kernel_routine);
|
||||||
|
|
||||||
struct Suspend_functor_impl : Libc::Suspend_functor
|
struct Suspend_functor_impl : Suspend_functor
|
||||||
{
|
{
|
||||||
bool suspend() override { return false; }
|
bool suspend() override { return false; }
|
||||||
|
|
||||||
|
@ -695,7 +694,6 @@ extern "C" pid_t __sys_wait4(pid_t pid, int *status, int options, rusage *rusage
|
||||||
pid_t result = -1;
|
pid_t result = -1;
|
||||||
int exit_code = 0; /* code and status */
|
int exit_code = 0; /* code and status */
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
using namespace Libc;
|
using namespace Libc;
|
||||||
|
|
||||||
if (!_forked_children_ptr) {
|
if (!_forked_children_ptr) {
|
||||||
|
@ -703,7 +701,7 @@ extern "C" pid_t __sys_wait4(pid_t pid, int *status, int options, rusage *rusage
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Missing_call_of_init_fork : Genode::Exception { };
|
struct Missing_call_of_init_fork : Exception { };
|
||||||
if (!_suspend_ptr)
|
if (!_suspend_ptr)
|
||||||
throw Missing_call_of_init_fork();
|
throw Missing_call_of_init_fork();
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,9 @@
|
||||||
#include <internal/legacy.h>
|
#include <internal/legacy.h>
|
||||||
#include <internal/errno.h>
|
#include <internal/errno.h>
|
||||||
|
|
||||||
typedef Genode::String<128> Passwd_string;
|
using namespace Libc;
|
||||||
|
|
||||||
|
typedef String<128> Passwd_string;
|
||||||
|
|
||||||
struct Passwd_fields {
|
struct Passwd_fields {
|
||||||
Passwd_string name { "root" };
|
Passwd_string name { "root" };
|
||||||
|
@ -46,14 +48,13 @@ struct Passwd_fields {
|
||||||
|
|
||||||
static void _fill_passwd(struct passwd &db, Passwd_fields &fields)
|
static void _fill_passwd(struct passwd &db, Passwd_fields &fields)
|
||||||
{
|
{
|
||||||
using namespace Genode;
|
|
||||||
|
|
||||||
/* reset buffers */
|
/* reset buffers */
|
||||||
Genode::memset(&db, 0x00, sizeof(struct passwd));
|
::memset(&db, 0x00, sizeof(struct passwd));
|
||||||
fields = Passwd_fields();
|
fields = Passwd_fields();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Xml_node const passwd = Libc::libc_config().sub_node("passwd");
|
Xml_node const passwd = libc_config().sub_node("passwd");
|
||||||
|
|
||||||
fields.name = passwd.attribute_value("name", fields.name);
|
fields.name = passwd.attribute_value("name", fields.name);
|
||||||
fields.uid = passwd.attribute_value("uid", 0UL);
|
fields.uid = passwd.attribute_value("uid", 0UL);
|
||||||
|
@ -88,8 +89,8 @@ static int _fill_r(struct passwd *in,
|
||||||
char *buffer, size_t bufsize,
|
char *buffer, size_t bufsize,
|
||||||
struct passwd **out)
|
struct passwd **out)
|
||||||
{
|
{
|
||||||
if (!in || !buffer) return Libc::Errno(EINVAL);
|
if (!in || !buffer) return Errno(EINVAL);
|
||||||
if (bufsize < sizeof(Passwd_fields)) return Libc::Errno(ERANGE);
|
if (bufsize < sizeof(Passwd_fields)) return Errno(ERANGE);
|
||||||
|
|
||||||
Passwd_fields *fields = (Passwd_fields *)buffer;
|
Passwd_fields *fields = (Passwd_fields *)buffer;
|
||||||
_fill_passwd(*in, *fields);
|
_fill_passwd(*in, *fields);
|
||||||
|
|
|
@ -22,6 +22,7 @@ extern "C" {
|
||||||
|
|
||||||
/* libc-internal includes */
|
/* libc-internal includes */
|
||||||
#include <internal/errno.h>
|
#include <internal/errno.h>
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <trace/timestamp.h>
|
#include <trace/timestamp.h>
|
||||||
|
@ -30,8 +31,9 @@ extern "C" {
|
||||||
|
|
||||||
namespace Libc { extern char const *config_rng(); }
|
namespace Libc { extern char const *config_rng(); }
|
||||||
|
|
||||||
static
|
using namespace Libc;
|
||||||
ssize_t read_rng(char *buf, size_t buflen)
|
|
||||||
|
static ssize_t read_rng(char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
static int rng_fd { -1 };
|
static int rng_fd { -1 };
|
||||||
static bool fallback { false };
|
static bool fallback { false };
|
||||||
|
@ -41,27 +43,27 @@ ssize_t read_rng(char *buf, size_t buflen)
|
||||||
while (off < buflen) {
|
while (off < buflen) {
|
||||||
/* collect 31 bits of random */
|
/* collect 31 bits of random */
|
||||||
unsigned const nonce = random();
|
unsigned const nonce = random();
|
||||||
size_t n = Genode::min(4U, buflen-off);
|
size_t n = min(4U, buflen-off);
|
||||||
memcpy(buf+off, &nonce, n);
|
::memcpy(buf+off, &nonce, n);
|
||||||
off += n;
|
off += n;
|
||||||
}
|
}
|
||||||
return buflen;
|
return buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rng_fd == -1) {
|
if (rng_fd == -1) {
|
||||||
if (!Genode::strcmp(Libc::config_rng(), "")) {
|
if (!::strcmp(config_rng(), "")) {
|
||||||
Genode::warning("Libc RNG not configured");
|
warning("Libc RNG not configured");
|
||||||
|
|
||||||
/* initialize the FreeBSD random facility */
|
/* initialize the FreeBSD random facility */
|
||||||
srandom(Genode::Trace::timestamp()|1);
|
srandom(Trace::timestamp()|1);
|
||||||
fallback = true;
|
fallback = true;
|
||||||
|
|
||||||
return read_rng(buf, buflen);
|
return read_rng(buf, buflen);
|
||||||
}
|
}
|
||||||
|
|
||||||
rng_fd = open(Libc::config_rng(), O_RDONLY);
|
rng_fd = open(config_rng(), O_RDONLY);
|
||||||
if (rng_fd == -1) {
|
if (rng_fd == -1) {
|
||||||
Genode::error("RNG device ", Genode::Cstring(Libc::config_rng()), " not readable!");
|
error("RNG device ", Cstring(config_rng()), " not readable!");
|
||||||
exit(~0);
|
exit(~0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +78,7 @@ getrandom(void *buf, size_t buflen, unsigned int flags)
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
while (off < buflen && off < 256) {
|
while (off < buflen && off < 256) {
|
||||||
ssize_t n = read_rng((char*)buf+off, buflen-off);
|
ssize_t n = read_rng((char*)buf+off, buflen-off);
|
||||||
if (n < 1) return Libc::Errno(EIO);
|
if (n < 1) return Errno(EIO);
|
||||||
off += n;
|
off += n;
|
||||||
}
|
}
|
||||||
return off;
|
return off;
|
||||||
|
@ -87,12 +89,12 @@ extern "C" int __attribute__((weak))
|
||||||
getentropy(void *buf, size_t buflen)
|
getentropy(void *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
/* maximum permitted value for the length argument is 256 */
|
/* maximum permitted value for the length argument is 256 */
|
||||||
if (256 < buflen) return Libc::Errno(EIO);
|
if (256 < buflen) return Errno(EIO);
|
||||||
|
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
while (off < buflen) {
|
while (off < buflen) {
|
||||||
ssize_t n = read_rng((char*)buf+off, buflen-off);
|
ssize_t n = read_rng((char*)buf+off, buflen-off);
|
||||||
if (n < 1) return Libc::Errno(EIO);
|
if (n < 1) return Errno(EIO);
|
||||||
off += n;
|
off += n;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace Libc {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Libc::Clone_session : Genode::Session
|
struct Libc::Clone_session : Session
|
||||||
{
|
{
|
||||||
static const char *service_name() { return "Clone"; }
|
static const char *service_name() { return "Clone"; }
|
||||||
|
|
||||||
|
@ -43,25 +43,25 @@ struct Libc::Clone_session : Genode::Session
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
GENODE_RPC(Rpc_dataspace, Genode::Dataspace_capability, dataspace);
|
GENODE_RPC(Rpc_dataspace, Dataspace_capability, dataspace);
|
||||||
GENODE_RPC(Rpc_memory_content, void, memory_content, Memory_range);
|
GENODE_RPC(Rpc_memory_content, void, memory_content, Memory_range);
|
||||||
|
|
||||||
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_memory_content);
|
GENODE_RPC_INTERFACE(Rpc_dataspace, Rpc_memory_content);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Libc::Clone_connection : Genode::Connection<Clone_session>,
|
struct Libc::Clone_connection : Connection<Clone_session>,
|
||||||
Genode::Rpc_client<Clone_session>
|
Rpc_client<Clone_session>
|
||||||
{
|
{
|
||||||
Genode::Attached_dataspace const _buffer;
|
Attached_dataspace const _buffer;
|
||||||
|
|
||||||
Clone_connection(Genode::Env &env)
|
Clone_connection(Genode::Env &env)
|
||||||
:
|
:
|
||||||
Genode::Connection<Clone_session>(env,
|
Connection<Clone_session>(env,
|
||||||
session(env.parent(),
|
session(env.parent(),
|
||||||
"ram_quota=%ld, cap_quota=%ld",
|
"ram_quota=%ld, cap_quota=%ld",
|
||||||
RAM_QUOTA, CAP_QUOTA)),
|
RAM_QUOTA, CAP_QUOTA)),
|
||||||
Genode::Rpc_client<Clone_session>(cap()),
|
Rpc_client<Clone_session>(cap()),
|
||||||
_buffer(env.rm(), call<Rpc_dataspace>())
|
_buffer(env.rm(), call<Rpc_dataspace>())
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ struct Libc::Clone_connection : Genode::Connection<Clone_session>,
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
|
|
||||||
size_t const chunk_len = Genode::min((size_t)BUFFER_SIZE, remaining);
|
size_t const chunk_len = min((size_t)BUFFER_SIZE, remaining);
|
||||||
|
|
||||||
/* instruct server to fill shared buffer */
|
/* instruct server to fill shared buffer */
|
||||||
call<Rpc_memory_content>(Memory_range{ ptr, chunk_len });
|
call<Rpc_memory_content>(Memory_range{ ptr, chunk_len });
|
||||||
|
|
|
@ -25,15 +25,15 @@ namespace Libc { struct Cloned_malloc_heap_range; }
|
||||||
|
|
||||||
struct Libc::Cloned_malloc_heap_range
|
struct Libc::Cloned_malloc_heap_range
|
||||||
{
|
{
|
||||||
Genode::Ram_allocator &ram;
|
Ram_allocator &ram;
|
||||||
Genode::Region_map &rm;
|
Region_map &rm;
|
||||||
|
|
||||||
Genode::Ram_dataspace_capability ds;
|
Ram_dataspace_capability ds;
|
||||||
|
|
||||||
size_t const size;
|
size_t const size;
|
||||||
addr_t const local_addr;
|
addr_t const local_addr;
|
||||||
|
|
||||||
Cloned_malloc_heap_range(Genode::Ram_allocator &ram, Genode::Region_map &rm,
|
Cloned_malloc_heap_range(Ram_allocator &ram, Region_map &rm,
|
||||||
void *start, size_t size)
|
void *start, size_t size)
|
||||||
try :
|
try :
|
||||||
ram(ram), rm(rm), ds(ram.alloc(size)), size(size),
|
ram(ram), rm(rm), ds(ram.alloc(size)), size(size),
|
||||||
|
|
|
@ -32,40 +32,39 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
|
||||||
|
|
||||||
Genode::Env &_env;
|
Genode::Env &_env;
|
||||||
|
|
||||||
Genode::Attached_rom_dataspace _config { _env, "config" };
|
Attached_rom_dataspace _config { _env, "config" };
|
||||||
|
|
||||||
Genode::Xml_node _vfs_config()
|
Xml_node _vfs_config()
|
||||||
{
|
{
|
||||||
try { return _config.xml().sub_node("vfs"); }
|
try { return _config.xml().sub_node("vfs"); }
|
||||||
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
try {
|
try {
|
||||||
Genode::Xml_node node =
|
Xml_node node = _config.xml().sub_node("libc").sub_node("vfs");
|
||||||
_config.xml().sub_node("libc").sub_node("vfs");
|
warning("'<config> <libc> <vfs/>' is deprecated, "
|
||||||
Genode::warning("'<config> <libc> <vfs/>' is deprecated, "
|
"please move to '<config> <vfs/>'");
|
||||||
"please move to '<config> <vfs/>'");
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
|
|
||||||
return Genode::Xml_node("<vfs/>");
|
return Xml_node("<vfs/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Xml_node _libc_config()
|
Xml_node _libc_config()
|
||||||
{
|
{
|
||||||
try { return _config.xml().sub_node("libc"); }
|
try { return _config.xml().sub_node("libc"); }
|
||||||
catch (Genode::Xml_node::Nonexistent_sub_node) { }
|
catch (Xml_node::Nonexistent_sub_node) { }
|
||||||
|
|
||||||
return Genode::Xml_node("<libc/>");
|
return Xml_node("<libc/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
Vfs::Simple_env _vfs_env;
|
Vfs::Simple_env _vfs_env;
|
||||||
|
|
||||||
Genode::Xml_node _config_xml() const override {
|
Xml_node _config_xml() const override {
|
||||||
return _config.xml(); };
|
return _config.xml(); };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Env_implementation(Genode::Env &env, Genode::Allocator &alloc)
|
Env_implementation(Genode::Env &env, Allocator &alloc)
|
||||||
: _env(env), _vfs_env(_env, alloc, _vfs_config()) { }
|
: _env(env), _vfs_env(_env, alloc, _vfs_config()) { }
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
|
||||||
Vfs::File_system &vfs() override {
|
Vfs::File_system &vfs() override {
|
||||||
return _vfs_env.root_dir(); }
|
return _vfs_env.root_dir(); }
|
||||||
|
|
||||||
Genode::Xml_node libc_config() override {
|
Xml_node libc_config() override {
|
||||||
return _libc_config(); }
|
return _libc_config(); }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ namespace Libc {
|
||||||
/**
|
/**
|
||||||
* Set libc config node
|
* Set libc config node
|
||||||
*/
|
*/
|
||||||
void libc_config_init(Genode::Xml_node node);
|
void libc_config_init(Xml_node node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Malloc allocator
|
* Malloc allocator
|
||||||
|
@ -106,19 +106,19 @@ namespace Libc {
|
||||||
*/
|
*/
|
||||||
void init_pthread_support(Genode::Env &env, Suspend &, Resume &);
|
void init_pthread_support(Genode::Env &env, Suspend &, Resume &);
|
||||||
|
|
||||||
struct Config_accessor : Genode::Interface
|
struct Config_accessor : Interface
|
||||||
{
|
{
|
||||||
virtual Genode::Xml_node config() const = 0;
|
virtual Xml_node config() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fork mechanism
|
* Fork mechanism
|
||||||
*/
|
*/
|
||||||
void init_fork(Genode::Env &, Config_accessor const &,
|
void init_fork(Genode::Env &, Config_accessor const &,
|
||||||
Genode::Allocator &heap, Genode::Heap &malloc_heap, int pid,
|
Genode::Allocator &heap, Heap &malloc_heap, int pid,
|
||||||
Suspend &, Resume &, Kernel_routine_scheduler &);
|
Suspend &, Resume &, Kernel_routine_scheduler &);
|
||||||
|
|
||||||
struct Reset_malloc_heap : Genode::Interface
|
struct Reset_malloc_heap : Interface
|
||||||
{
|
{
|
||||||
virtual void reset_malloc_heap() = 0;
|
virtual void reset_malloc_heap() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -203,7 +203,7 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
|
||||||
*
|
*
|
||||||
* This function is called by the main thread.
|
* This function is called by the main thread.
|
||||||
*/
|
*/
|
||||||
static void _user_entry(Libc::Kernel *kernel)
|
static void _user_entry(Kernel *kernel)
|
||||||
{
|
{
|
||||||
struct Check : Suspend_functor {
|
struct Check : Suspend_functor {
|
||||||
bool suspend() override { return true; }
|
bool suspend() override { return true; }
|
||||||
|
@ -305,7 +305,7 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
|
||||||
*
|
*
|
||||||
* This function is called by the component thread on with_libc().
|
* This function is called by the component thread on with_libc().
|
||||||
*/
|
*/
|
||||||
void run(Libc::Application_code &app_code)
|
void run(Application_code &app_code)
|
||||||
{
|
{
|
||||||
if (!_main_context() || _state != KERNEL) {
|
if (!_main_context() || _state != KERNEL) {
|
||||||
error(__PRETTY_FUNCTION__, " called from non-kernel context");
|
error(__PRETTY_FUNCTION__, " called from non-kernel context");
|
||||||
|
@ -496,7 +496,7 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
|
||||||
/**
|
/**
|
||||||
* Execute application code while already executing in run()
|
* Execute application code while already executing in run()
|
||||||
*/
|
*/
|
||||||
void nested_execution(Libc::Application_code &app_code)
|
void nested_execution(Application_code &app_code)
|
||||||
{
|
{
|
||||||
_nested_app_code = &app_code;
|
_nested_app_code = &app_code;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Libc {
|
||||||
/**
|
/**
|
||||||
* Access libc configuration Xml_node.
|
* Access libc configuration Xml_node.
|
||||||
*/
|
*/
|
||||||
Genode::Xml_node libc_config();
|
Xml_node libc_config();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _LIBC__INTERNAL__LEGACY_H_ */
|
#endif /* _LIBC__INTERNAL__LEGACY_H_ */
|
||||||
|
|
|
@ -22,21 +22,23 @@
|
||||||
namespace Libc { struct Malloc_ram_allocator; }
|
namespace Libc { struct Malloc_ram_allocator; }
|
||||||
|
|
||||||
|
|
||||||
struct Libc::Malloc_ram_allocator : Genode::Ram_allocator
|
struct Libc::Malloc_ram_allocator : Ram_allocator
|
||||||
{
|
{
|
||||||
Genode::Allocator &_md_alloc;
|
typedef Genode::Allocator Allocator;
|
||||||
Genode::Ram_allocator &_ram;
|
|
||||||
|
Allocator &_md_alloc;
|
||||||
|
Ram_allocator &_ram;
|
||||||
|
|
||||||
struct Dataspace
|
struct Dataspace
|
||||||
{
|
{
|
||||||
Genode::Ram_dataspace_capability cap;
|
Ram_dataspace_capability cap;
|
||||||
Dataspace(Genode::Ram_dataspace_capability cap) : cap(cap) { }
|
Dataspace(Ram_dataspace_capability cap) : cap(cap) { }
|
||||||
virtual ~Dataspace() { }
|
virtual ~Dataspace() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Registry<Genode::Registered<Dataspace> > _dataspaces { };
|
Registry<Registered<Dataspace> > _dataspaces { };
|
||||||
|
|
||||||
void _release(Genode::Registered<Dataspace> &ds)
|
void _release(Registered<Dataspace> &ds)
|
||||||
{
|
{
|
||||||
_ram.free(ds.cap);
|
_ram.free(ds.cap);
|
||||||
destroy(_md_alloc, &ds);
|
destroy(_md_alloc, &ds);
|
||||||
|
|
|
@ -21,13 +21,16 @@
|
||||||
#include <util/list.h>
|
#include <util/list.h>
|
||||||
#include <rm_session/rm_session.h>
|
#include <rm_session/rm_session.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
|
|
||||||
struct Mem_alloc
|
struct Mem_alloc
|
||||||
{
|
{
|
||||||
virtual void *alloc(Genode::size_t size, Genode::size_t align_log2) = 0;
|
virtual void *alloc(size_t size, size_t align_log2) = 0;
|
||||||
virtual void free(void *ptr) = 0;
|
virtual void free(void *ptr) = 0;
|
||||||
virtual Genode::size_t size_at(void const *ptr) const = 0;
|
virtual size_t size_at(void const *ptr) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,14 +47,14 @@ namespace Libc {
|
||||||
MAX_CHUNK_SIZE = 1024*1024
|
MAX_CHUNK_SIZE = 1024*1024
|
||||||
};
|
};
|
||||||
|
|
||||||
class Dataspace : public Genode::List<Dataspace>::Element
|
class Dataspace : public List<Dataspace>::Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Genode::Ram_dataspace_capability cap;
|
Ram_dataspace_capability cap;
|
||||||
void *local_addr;
|
void *local_addr;
|
||||||
|
|
||||||
Dataspace(Genode::Ram_dataspace_capability c, void *a)
|
Dataspace(Ram_dataspace_capability c, void *a)
|
||||||
: cap(c), local_addr(a) {}
|
: cap(c), local_addr(a) {}
|
||||||
|
|
||||||
inline void * operator new(__SIZE_TYPE__, void* addr) {
|
inline void * operator new(__SIZE_TYPE__, void* addr) {
|
||||||
|
@ -60,21 +63,21 @@ namespace Libc {
|
||||||
inline void operator delete(void*) { }
|
inline void operator delete(void*) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Dataspace_pool : public Genode::List<Dataspace>
|
class Dataspace_pool : public List<Dataspace>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Ram_allocator *_ram; /* ram session for backing store */
|
Ram_allocator *_ram; /* RAM session for backing store */
|
||||||
Genode::Region_map *_region_map; /* region map of address space */
|
Region_map *_region_map; /* region map of address space */
|
||||||
bool const _executable; /* whether to allocate executable dataspaces */
|
bool const _executable; /* whether to allocate executable dataspaces */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
Dataspace_pool(Genode::Ram_allocator *ram,
|
Dataspace_pool(Ram_allocator *ram,
|
||||||
Genode::Region_map *rm, bool executable) :
|
Region_map *rm, bool executable) :
|
||||||
_ram(ram), _region_map(rm),
|
_ram(ram), _region_map(rm),
|
||||||
_executable(executable)
|
_executable(executable)
|
||||||
{ }
|
{ }
|
||||||
|
@ -95,16 +98,16 @@ namespace Libc {
|
||||||
* Region_map::Region_conflict
|
* Region_map::Region_conflict
|
||||||
* \return 0 on success or negative error code
|
* \return 0 on success or negative error code
|
||||||
*/
|
*/
|
||||||
int expand(Genode::size_t size, Genode::Range_allocator *alloc);
|
int expand(size_t size, Range_allocator *alloc);
|
||||||
|
|
||||||
void reassign_resources(Genode::Ram_allocator *ram, Genode::Region_map *rm) {
|
void reassign_resources(Ram_allocator *ram, Region_map *rm) {
|
||||||
_ram = ram, _region_map = rm; }
|
_ram = ram, _region_map = rm; }
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Lock mutable _lock;
|
Lock mutable _lock;
|
||||||
Dataspace_pool _ds_pool; /* list of dataspaces */
|
Dataspace_pool _ds_pool; /* list of dataspaces */
|
||||||
Genode::Allocator_avl _alloc; /* local allocator */
|
Allocator_avl _alloc; /* local allocator */
|
||||||
Genode::size_t _chunk_size;
|
size_t _chunk_size;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to allocate block at our local allocator
|
* Try to allocate block at our local allocator
|
||||||
|
@ -114,12 +117,11 @@ namespace Libc {
|
||||||
* This function is a utility used by 'alloc' to avoid
|
* This function is a utility used by 'alloc' to avoid
|
||||||
* code duplication.
|
* code duplication.
|
||||||
*/
|
*/
|
||||||
bool _try_local_alloc(Genode::size_t size, void **out_addr);
|
bool _try_local_alloc(size_t size, void **out_addr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Mem_alloc_impl(Genode::Region_map &rm,
|
Mem_alloc_impl(Region_map &rm, Ram_allocator &ram,
|
||||||
Genode::Ram_allocator &ram,
|
|
||||||
bool executable = false)
|
bool executable = false)
|
||||||
:
|
:
|
||||||
_ds_pool(&ram, &rm, executable),
|
_ds_pool(&ram, &rm, executable),
|
||||||
|
@ -127,9 +129,9 @@ namespace Libc {
|
||||||
_chunk_size(MIN_CHUNK_SIZE)
|
_chunk_size(MIN_CHUNK_SIZE)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void *alloc(Genode::size_t size, Genode::size_t align_log2);
|
void *alloc(size_t size, size_t align_log2);
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
Genode::size_t size_at(void const *ptr) const;
|
size_t size_at(void const *ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <libc-plugin/plugin.h>
|
#include <libc-plugin/plugin.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
|
|
||||||
class Mmap_registry;
|
class Mmap_registry;
|
||||||
|
@ -39,7 +42,7 @@ class Libc::Mmap_registry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Entry : Genode::List<Entry>::Element
|
struct Entry : List<Entry>::Element
|
||||||
{
|
{
|
||||||
void * const start;
|
void * const start;
|
||||||
Plugin * const plugin;
|
Plugin * const plugin;
|
||||||
|
@ -52,9 +55,9 @@ class Libc::Mmap_registry
|
||||||
|
|
||||||
Libc::Allocator _md_alloc;
|
Libc::Allocator _md_alloc;
|
||||||
|
|
||||||
Genode::List<Mmap_registry::Entry> _list;
|
List<Mmap_registry::Entry> _list;
|
||||||
|
|
||||||
Genode::Lock mutable _lock;
|
Lock mutable _lock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common for both const and non-const lookup functions
|
* Common for both const and non-const lookup functions
|
||||||
|
@ -81,13 +84,13 @@ class Libc::Mmap_registry
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void insert(void *start, Genode::size_t len, Plugin *plugin)
|
void insert(void *start, size_t len, Plugin *plugin)
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
if (_lookup_by_addr_unsynchronized(start)) {
|
if (_lookup_by_addr_unsynchronized(start)) {
|
||||||
Genode::warning(__func__, ": mmap region at ", start, " "
|
warning(__func__, ": mmap region at ", start, " "
|
||||||
"is already registered");
|
"is already registered");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +99,7 @@ class Libc::Mmap_registry
|
||||||
|
|
||||||
Plugin *lookup_plugin_by_addr(void *start) const
|
Plugin *lookup_plugin_by_addr(void *start) const
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
Entry const * const e = _lookup_by_addr_unsynchronized(start);
|
Entry const * const e = _lookup_by_addr_unsynchronized(start);
|
||||||
return e ? e->plugin : 0;
|
return e ? e->plugin : 0;
|
||||||
|
@ -104,20 +107,20 @@ class Libc::Mmap_registry
|
||||||
|
|
||||||
bool registered(void *start) const
|
bool registered(void *start) const
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
return _lookup_by_addr_unsynchronized(start) != 0;
|
return _lookup_by_addr_unsynchronized(start) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(void *start)
|
void remove(void *start)
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard guard(_lock);
|
Lock::Guard guard(_lock);
|
||||||
|
|
||||||
Entry *e = _lookup_by_addr_unsynchronized(start);
|
Entry *e = _lookup_by_addr_unsynchronized(start);
|
||||||
|
|
||||||
if (!e) {
|
if (!e) {
|
||||||
Genode::warning("lookup for address ", start, " "
|
warning("lookup for address ", start, " "
|
||||||
"in in mmap registry failed");
|
"in in mmap registry failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,29 +23,39 @@
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
namespace Libc {
|
||||||
|
|
||||||
|
struct Pthread;
|
||||||
|
struct Pthread_registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used by 'pthread_self()' to find out if the current thread is an alien
|
* Used by 'pthread_self()' to find out if the current thread is an alien
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
class Pthread_registry
|
class Libc::Pthread_registry
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
enum { MAX_NUM_PTHREADS = 128 };
|
enum { MAX_NUM_PTHREADS = 128 };
|
||||||
|
|
||||||
pthread_t _array[MAX_NUM_PTHREADS] = { 0 };
|
Pthread *_array[MAX_NUM_PTHREADS] = { 0 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void insert(pthread_t thread);
|
void insert(Pthread &thread);
|
||||||
|
|
||||||
void remove(pthread_t thread);
|
void remove(Pthread &thread);
|
||||||
|
|
||||||
bool contains(pthread_t thread);
|
bool contains(Pthread &thread);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Pthread_registry &pthread_registry();
|
Libc::Pthread_registry &pthread_registry();
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -69,7 +79,7 @@ struct Genode::Thread::Tls::Base
|
||||||
/**
|
/**
|
||||||
* Register thread-local-storage object at Genode thread
|
* Register thread-local-storage object at Genode thread
|
||||||
*/
|
*/
|
||||||
static void tls(Genode::Thread &thread, Tls::Base &tls)
|
static void tls(Thread &thread, Tls::Base &tls)
|
||||||
{
|
{
|
||||||
thread._tls = Tls { &tls };
|
thread._tls = Tls { &tls };
|
||||||
}
|
}
|
||||||
|
@ -93,13 +103,13 @@ struct Genode::Thread::Tls::Base
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
struct Libc::Pthread : Noncopyable, Thread::Tls::Base
|
||||||
{
|
{
|
||||||
typedef void *(*start_routine_t) (void *);
|
typedef void *(*start_routine_t) (void *);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct Thread_object : Genode::Thread
|
struct Thread_object : Thread
|
||||||
{
|
{
|
||||||
start_routine_t _start_routine;
|
start_routine_t _start_routine;
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
@ -107,16 +117,16 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
void *&_stack_addr;
|
void *&_stack_addr;
|
||||||
size_t &_stack_size;
|
size_t &_stack_size;
|
||||||
|
|
||||||
enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT };
|
enum { WEIGHT = Cpu_session::Weight::DEFAULT_WEIGHT };
|
||||||
|
|
||||||
/* 'stack_addr_out' and 'stack_size_out' are written when the thread starts */
|
/* 'stack_addr_out' and 'stack_size_out' are written when the thread starts */
|
||||||
Thread_object(char const *name, size_t stack_size,
|
Thread_object(char const *name, size_t stack_size,
|
||||||
Genode::Cpu_session *cpu,
|
Cpu_session *cpu,
|
||||||
Genode::Affinity::Location location,
|
Affinity::Location location,
|
||||||
start_routine_t start_routine, void *arg,
|
start_routine_t start_routine, void *arg,
|
||||||
void *&stack_addr_out, size_t &stack_size_out)
|
void *&stack_addr_out, size_t &stack_size_out)
|
||||||
:
|
:
|
||||||
Genode::Thread(WEIGHT, name, stack_size, Type::NORMAL, cpu, location),
|
Thread(WEIGHT, name, stack_size, Type::NORMAL, cpu, location),
|
||||||
_start_routine(start_routine), _arg(arg),
|
_start_routine(start_routine), _arg(arg),
|
||||||
_stack_addr(stack_addr_out), _stack_size(stack_size_out)
|
_stack_addr(stack_addr_out), _stack_size(stack_size_out)
|
||||||
{ }
|
{ }
|
||||||
|
@ -124,27 +134,27 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
void entry() override;
|
void entry() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Constructible<Thread_object> _thread_object;
|
Constructible<Thread_object> _thread_object;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper to construct '_thread_object' in class initializer
|
* Helper to construct '_thread_object' in class initializer
|
||||||
*/
|
*/
|
||||||
template <typename... ARGS>
|
template <typename... ARGS>
|
||||||
Genode::Thread &_construct_thread_object(ARGS &&... args)
|
Thread &_construct_thread_object(ARGS &&... args)
|
||||||
{
|
{
|
||||||
_thread_object.construct(args...);
|
_thread_object.construct(args...);
|
||||||
return *_thread_object;
|
return *_thread_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Refers to '_thread_object' or an external 'Genode::Thread' object
|
* Refers to '_thread_object' or an external 'Thread' object
|
||||||
*/
|
*/
|
||||||
Genode::Thread &_thread;
|
Thread &_thread;
|
||||||
|
|
||||||
void _associate_thread_with_pthread()
|
void _associate_thread_with_pthread()
|
||||||
{
|
{
|
||||||
Genode::Thread::Tls::Base::tls(_thread, *this);
|
Thread::Tls::Base::tls(_thread, *this);
|
||||||
pthread_registry().insert(this);
|
pthread_registry().insert(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _exiting = false;
|
bool _exiting = false;
|
||||||
|
@ -155,11 +165,11 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
* capability, which needs to be released before the thread can be
|
* capability, which needs to be released before the thread can be
|
||||||
* destroyed.
|
* destroyed.
|
||||||
*
|
*
|
||||||
* Also, we cannot use 'Genode::Thread::join()', because it only
|
* Also, we cannot use 'Thread::join()', because it only
|
||||||
* returns when the thread entry function returns, which does not
|
* returns when the thread entry function returns, which does not
|
||||||
* happen with 'pthread_cancel()'.
|
* happen with 'pthread_cancel()'.
|
||||||
*/
|
*/
|
||||||
Genode::Lock _join_lock { Genode::Lock::LOCKED };
|
Lock _join_lock { Lock::LOCKED };
|
||||||
|
|
||||||
/* return value for 'pthread_join()' */
|
/* return value for 'pthread_join()' */
|
||||||
void *_retval = PTHREAD_CANCELED;
|
void *_retval = PTHREAD_CANCELED;
|
||||||
|
@ -173,9 +183,9 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
/**
|
/**
|
||||||
* Constructor for threads created via 'pthread_create'
|
* Constructor for threads created via 'pthread_create'
|
||||||
*/
|
*/
|
||||||
pthread(start_routine_t start_routine,
|
Pthread(start_routine_t start_routine,
|
||||||
void *arg, size_t stack_size, char const * name,
|
void *arg, size_t stack_size, char const * name,
|
||||||
Genode::Cpu_session * cpu, Genode::Affinity::Location location)
|
Cpu_session * cpu, Affinity::Location location)
|
||||||
:
|
:
|
||||||
_thread(_construct_thread_object(name, stack_size, cpu, location,
|
_thread(_construct_thread_object(name, stack_size, cpu, location,
|
||||||
start_routine, arg,
|
start_routine, arg,
|
||||||
|
@ -188,21 +198,21 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
* Constructor to create pthread object out of existing thread,
|
* Constructor to create pthread object out of existing thread,
|
||||||
* i.e., the main thread
|
* i.e., the main thread
|
||||||
*/
|
*/
|
||||||
pthread(Genode::Thread &existing_thread)
|
Pthread(Thread &existing_thread)
|
||||||
:
|
:
|
||||||
_thread(existing_thread)
|
_thread(existing_thread)
|
||||||
{
|
{
|
||||||
/* obtain stack attributes of main thread */
|
/* obtain stack attributes of main thread */
|
||||||
Genode::Thread::Stack_info info = Genode::Thread::mystack();
|
Thread::Stack_info info = Thread::mystack();
|
||||||
_stack_addr = (void *)info.base;
|
_stack_addr = (void *)info.base;
|
||||||
_stack_size = info.top - info.base;
|
_stack_size = info.top - info.base;
|
||||||
|
|
||||||
_associate_thread_with_pthread();
|
_associate_thread_with_pthread();
|
||||||
}
|
}
|
||||||
|
|
||||||
~pthread()
|
~Pthread()
|
||||||
{
|
{
|
||||||
pthread_registry().remove(this);
|
pthread_registry().remove(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() { _thread.start(); }
|
void start() { _thread.start(); }
|
||||||
|
@ -226,6 +236,12 @@ struct pthread : Genode::Noncopyable, Genode::Thread::Tls::Base
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct pthread : Libc::Pthread
|
||||||
|
{
|
||||||
|
using Libc::Pthread::Pthread;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace Libc { void init_pthread_support(Env &env); }
|
namespace Libc { void init_pthread_support(Env &env); }
|
||||||
|
|
||||||
#endif /* _LIBC__INTERNAL__PTHREAD_H_ */
|
#endif /* _LIBC__INTERNAL__PTHREAD_H_ */
|
||||||
|
|
|
@ -26,8 +26,8 @@ struct Libc::Pthread_pool
|
||||||
{
|
{
|
||||||
struct Pthread : Timeout_handler
|
struct Pthread : Timeout_handler
|
||||||
{
|
{
|
||||||
Genode::Lock lock { Genode::Lock::LOCKED };
|
Lock lock { Lock::LOCKED };
|
||||||
Pthread *next { nullptr };
|
Pthread *next { nullptr };
|
||||||
|
|
||||||
Timer_accessor &_timer_accessor;
|
Timer_accessor &_timer_accessor;
|
||||||
Constructible<Timeout> _timeout;
|
Constructible<Timeout> _timeout;
|
||||||
|
@ -38,7 +38,7 @@ struct Libc::Pthread_pool
|
||||||
_timeout.construct(_timer_accessor, *this);
|
_timeout.construct(_timer_accessor, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Pthread(Timer_accessor &timer_accessor, Genode::uint64_t timeout_ms)
|
Pthread(Timer_accessor &timer_accessor, uint64_t timeout_ms)
|
||||||
: _timer_accessor(timer_accessor)
|
: _timer_accessor(timer_accessor)
|
||||||
{
|
{
|
||||||
if (timeout_ms > 0) {
|
if (timeout_ms > 0) {
|
||||||
|
@ -47,7 +47,7 @@ struct Libc::Pthread_pool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::uint64_t duration_left()
|
uint64_t duration_left()
|
||||||
{
|
{
|
||||||
_construct_timeout_once();
|
_construct_timeout_once();
|
||||||
return _timeout->duration_left();
|
return _timeout->duration_left();
|
||||||
|
@ -59,7 +59,7 @@ struct Libc::Pthread_pool
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Genode::Lock mutex;
|
Lock mutex;
|
||||||
Pthread *pthreads = nullptr;
|
Pthread *pthreads = nullptr;
|
||||||
Timer_accessor &timer_accessor;
|
Timer_accessor &timer_accessor;
|
||||||
|
|
||||||
|
@ -69,17 +69,17 @@ struct Libc::Pthread_pool
|
||||||
|
|
||||||
void resume_all()
|
void resume_all()
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard g(mutex);
|
Lock::Guard g(mutex);
|
||||||
|
|
||||||
for (Pthread *p = pthreads; p; p = p->next)
|
for (Pthread *p = pthreads; p; p = p->next)
|
||||||
p->lock.unlock();
|
p->lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::uint64_t suspend_myself(Suspend_functor & check, Genode::uint64_t timeout_ms)
|
uint64_t suspend_myself(Suspend_functor & check, uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
Pthread myself { timer_accessor, timeout_ms };
|
Pthread myself { timer_accessor, timeout_ms };
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard g(mutex);
|
Lock::Guard g(mutex);
|
||||||
|
|
||||||
myself.next = pthreads;
|
myself.next = pthreads;
|
||||||
pthreads = &myself;
|
pthreads = &myself;
|
||||||
|
@ -89,7 +89,7 @@ struct Libc::Pthread_pool
|
||||||
myself.lock.lock();
|
myself.lock.lock();
|
||||||
|
|
||||||
{
|
{
|
||||||
Genode::Lock::Guard g(mutex);
|
Lock::Guard g(mutex);
|
||||||
|
|
||||||
/* address of pointer to next pthread allows to change the head */
|
/* address of pointer to next pthread allows to change the head */
|
||||||
for (Pthread **next = &pthreads; *next; next = &(*next)->next) {
|
for (Pthread **next = &pthreads; *next; next = &(*next)->next) {
|
||||||
|
|
|
@ -29,8 +29,6 @@ namespace Libc {
|
||||||
|
|
||||||
struct Suspend : Interface
|
struct Suspend : Interface
|
||||||
{
|
{
|
||||||
typedef Genode::uint64_t uint64_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspend the execution of the calling user context
|
* Suspend the execution of the calling user context
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,13 +22,17 @@
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
|
|
||||||
int pthread_create(pthread_t *thread,
|
int pthread_create(pthread_t *thread,
|
||||||
void *(*start_routine) (void *), void *arg,
|
void *(*start_routine) (void *), void *arg,
|
||||||
size_t stack_size, char const * name,
|
size_t stack_size, char const * name,
|
||||||
Genode::Cpu_session * cpu, Genode::Affinity::Location location);
|
Cpu_session * cpu, Affinity::Location location);
|
||||||
|
|
||||||
int pthread_create(pthread_t *, Genode::Thread &);
|
int pthread_create(pthread_t *, Thread &);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _LIBC__INTERNAL__THREAD_CREATE_H_ */
|
#endif /* _LIBC__INTERNAL__THREAD_CREATE_H_ */
|
||||||
|
|
|
@ -31,17 +31,17 @@ struct Libc::Timer
|
||||||
|
|
||||||
Timer(Genode::Env &env) : _timer(env) { }
|
Timer(Genode::Env &env) : _timer(env) { }
|
||||||
|
|
||||||
Genode::Duration curr_time()
|
Duration curr_time()
|
||||||
{
|
{
|
||||||
return _timer.curr_time();
|
return _timer.curr_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Microseconds microseconds(Genode::uint64_t timeout_ms)
|
static Microseconds microseconds(uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
return Microseconds(1000*timeout_ms);
|
return Microseconds(1000*timeout_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Genode::uint64_t max_timeout()
|
static uint64_t max_timeout()
|
||||||
{
|
{
|
||||||
return ~0UL/1000;
|
return ~0UL/1000;
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,12 @@ struct Libc::Timeout_handler
|
||||||
*/
|
*/
|
||||||
struct Libc::Timeout
|
struct Libc::Timeout
|
||||||
{
|
{
|
||||||
Libc::Timer_accessor &_timer_accessor;
|
Timer_accessor &_timer_accessor;
|
||||||
Timeout_handler &_handler;
|
Timeout_handler &_handler;
|
||||||
::Timer::One_shot_timeout<Timeout> _timeout;
|
::Timer::One_shot_timeout<Timeout> _timeout;
|
||||||
|
|
||||||
bool _expired = true;
|
bool _expired = true;
|
||||||
Genode::uint64_t _absolute_timeout_ms = 0;
|
uint64_t _absolute_timeout_ms = 0;
|
||||||
|
|
||||||
void _handle(Duration now)
|
void _handle(Duration now)
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ struct Libc::Timeout
|
||||||
_timeout(_timer_accessor.timer()._timer, *this, &Timeout::_handle)
|
_timeout(_timer_accessor.timer()._timer, *this, &Timeout::_handle)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void start(Genode::uint64_t timeout_ms)
|
void start(uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
|
Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ struct Libc::Timeout
|
||||||
_timeout.schedule(_timer_accessor.timer().microseconds(timeout_ms));
|
_timeout.schedule(_timer_accessor.timer().microseconds(timeout_ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::uint64_t duration_left() const
|
uint64_t duration_left() const
|
||||||
{
|
{
|
||||||
Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
|
Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@
|
||||||
|
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
namespace Libc { using namespace Genode; }
|
namespace Libc {
|
||||||
|
|
||||||
|
using namespace Genode;
|
||||||
|
|
||||||
|
typedef Genode::uint64_t uint64_t;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LIBC__INTERNAL__TYPES_H_ */
|
#endif /* _LIBC__INTERNAL__TYPES_H_ */
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
namespace Libc { class Vfs_plugin; }
|
namespace Libc { class Vfs_plugin; }
|
||||||
|
|
||||||
|
|
||||||
class Libc::Vfs_plugin : public Libc::Plugin
|
class Libc::Vfs_plugin : public Plugin
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -77,35 +77,35 @@ class Libc::Vfs_plugin : public Libc::Plugin
|
||||||
fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
struct timeval *timeout) override;
|
struct timeval *timeout) override;
|
||||||
|
|
||||||
Libc::File_descriptor *open(const char *, int, int libc_fd);
|
File_descriptor *open(const char *, int, int libc_fd);
|
||||||
|
|
||||||
Libc::File_descriptor *open(const char *path, int flags) override
|
File_descriptor *open(const char *path, int flags) override
|
||||||
{
|
{
|
||||||
return open(path, flags, Libc::ANY_FD);
|
return open(path, flags, ANY_FD);
|
||||||
}
|
}
|
||||||
|
|
||||||
int access(char const *, int) override;
|
int access(char const *, int) override;
|
||||||
int close(Libc::File_descriptor *) override;
|
int close(File_descriptor *) override;
|
||||||
int dup2(Libc::File_descriptor *, Libc::File_descriptor *) override;
|
int dup2(File_descriptor *, File_descriptor *) override;
|
||||||
int fcntl(Libc::File_descriptor *, int, long) override;
|
int fcntl(File_descriptor *, int, long) override;
|
||||||
int fstat(Libc::File_descriptor *, struct stat *) override;
|
int fstat(File_descriptor *, struct stat *) override;
|
||||||
int fstatfs(Libc::File_descriptor *, struct statfs *) override;
|
int fstatfs(File_descriptor *, struct statfs *) override;
|
||||||
int fsync(Libc::File_descriptor *fd) override;
|
int fsync(File_descriptor *fd) override;
|
||||||
int ftruncate(Libc::File_descriptor *, ::off_t) override;
|
int ftruncate(File_descriptor *, ::off_t) override;
|
||||||
ssize_t getdirentries(Libc::File_descriptor *, char *, ::size_t , ::off_t *) override;
|
ssize_t getdirentries(File_descriptor *, char *, ::size_t , ::off_t *) override;
|
||||||
int ioctl(Libc::File_descriptor *, int , char *) override;
|
int ioctl(File_descriptor *, int , char *) override;
|
||||||
::off_t lseek(Libc::File_descriptor *fd, ::off_t offset, int whence) override;
|
::off_t lseek(File_descriptor *fd, ::off_t offset, int whence) override;
|
||||||
int mkdir(const char *, mode_t) override;
|
int mkdir(const char *, mode_t) override;
|
||||||
bool poll(File_descriptor &fdo, struct pollfd &pfd) override;
|
bool poll(File_descriptor &fdo, struct pollfd &pfd) override;
|
||||||
ssize_t read(Libc::File_descriptor *, void *, ::size_t) override;
|
ssize_t read(File_descriptor *, void *, ::size_t) override;
|
||||||
ssize_t readlink(const char *, char *, ::size_t) override;
|
ssize_t readlink(const char *, char *, ::size_t) override;
|
||||||
int rename(const char *, const char *) override;
|
int rename(const char *, const char *) override;
|
||||||
int rmdir(const char *) override;
|
int rmdir(const char *) override;
|
||||||
int stat(const char *, struct stat *) override;
|
int stat(const char *, struct stat *) override;
|
||||||
int symlink(const char *, const char *) override;
|
int symlink(const char *, const char *) override;
|
||||||
int unlink(const char *) override;
|
int unlink(const char *) override;
|
||||||
ssize_t write(Libc::File_descriptor *, const void *, ::size_t ) override;
|
ssize_t write(File_descriptor *, const void *, ::size_t ) override;
|
||||||
void *mmap(void *, ::size_t, int, int, Libc::File_descriptor *, ::off_t) override;
|
void *mmap(void *, ::size_t, int, int, File_descriptor *, ::off_t) override;
|
||||||
int munmap(void *, ::size_t) override;
|
int munmap(void *, ::size_t) override;
|
||||||
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) override;
|
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,7 +57,7 @@ size_t Libc::Kernel::_user_stack_size()
|
||||||
void Libc::Kernel::schedule_suspend(void(*original_suspended_callback) ())
|
void Libc::Kernel::schedule_suspend(void(*original_suspended_callback) ())
|
||||||
{
|
{
|
||||||
if (_state != USER) {
|
if (_state != USER) {
|
||||||
Genode::error(__PRETTY_FUNCTION__, " called from non-user context");
|
error(__PRETTY_FUNCTION__, " called from non-user context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ void Libc::Kernel::reset_malloc_heap()
|
||||||
destroy(_heap, &r); });
|
destroy(_heap, &r); });
|
||||||
|
|
||||||
Heap &raw_malloc_heap = *_malloc_heap;
|
Heap &raw_malloc_heap = *_malloc_heap;
|
||||||
Genode::construct_at<Heap>(&raw_malloc_heap, *_malloc_ram, _env.rm());
|
construct_at<Heap>(&raw_malloc_heap, *_malloc_ram, _env.rm());
|
||||||
|
|
||||||
reinit_malloc(raw_malloc_heap);
|
reinit_malloc(raw_malloc_heap);
|
||||||
}
|
}
|
||||||
|
@ -95,23 +95,23 @@ void Libc::Kernel::reset_malloc_heap()
|
||||||
|
|
||||||
void Libc::Kernel::_init_file_descriptors()
|
void Libc::Kernel::_init_file_descriptors()
|
||||||
{
|
{
|
||||||
auto init_fd = [&] (Genode::Xml_node const &node, char const *attr,
|
auto init_fd = [&] (Xml_node const &node, char const *attr,
|
||||||
int libc_fd, unsigned flags)
|
int libc_fd, unsigned flags)
|
||||||
{
|
{
|
||||||
if (!node.has_attribute(attr))
|
if (!node.has_attribute(attr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
typedef Genode::String<Vfs::MAX_PATH_LEN> Path;
|
typedef String<Vfs::MAX_PATH_LEN> Path;
|
||||||
Path const path = node.attribute_value(attr, Path());
|
Path const path = node.attribute_value(attr, Path());
|
||||||
|
|
||||||
struct stat out_stat { };
|
struct stat out_stat { };
|
||||||
if (stat(path.string(), &out_stat) != 0)
|
if (stat(path.string(), &out_stat) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Libc::File_descriptor *fd = _vfs.open(path.string(), flags, libc_fd);
|
File_descriptor *fd = _vfs.open(path.string(), flags, libc_fd);
|
||||||
if (fd->libc_fd != libc_fd) {
|
if (fd->libc_fd != libc_fd) {
|
||||||
Genode::error("could not allocate fd ",libc_fd," for ",path,", "
|
error("could not allocate fd ",libc_fd," for ",path,", "
|
||||||
"got fd ",fd->libc_fd);
|
"got fd ",fd->libc_fd);
|
||||||
_vfs.close(fd);
|
_vfs.close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ void Libc::Kernel::_init_file_descriptors()
|
||||||
* because we want to explicitly specify the libc fd ID.
|
* because we want to explicitly specify the libc fd ID.
|
||||||
*/
|
*/
|
||||||
if (fd->fd_path)
|
if (fd->fd_path)
|
||||||
Genode::warning("may leak former FD path memory");
|
warning("may leak former FD path memory");
|
||||||
|
|
||||||
{
|
{
|
||||||
char *dst = (char *)_heap.alloc(path.length());
|
char *dst = (char *)_heap.alloc(path.length());
|
||||||
|
@ -139,7 +139,7 @@ void Libc::Kernel::_init_file_descriptors()
|
||||||
|
|
||||||
Xml_node const node = _libc_env.libc_config();
|
Xml_node const node = _libc_env.libc_config();
|
||||||
|
|
||||||
typedef Genode::String<Vfs::MAX_PATH_LEN> Path;
|
typedef String<Vfs::MAX_PATH_LEN> Path;
|
||||||
|
|
||||||
if (node.has_attribute("cwd"))
|
if (node.has_attribute("cwd"))
|
||||||
chdir(node.attribute_value("cwd", Path()).string());
|
chdir(node.attribute_value("cwd", Path()).string());
|
||||||
|
@ -166,7 +166,7 @@ void Libc::Kernel::_init_file_descriptors()
|
||||||
|
|
||||||
/* prevent use of IDs of stdin, stdout, and stderr for other files */
|
/* prevent use of IDs of stdin, stdout, and stderr for other files */
|
||||||
for (unsigned fd = 0; fd <= 2; fd++)
|
for (unsigned fd = 0; fd <= 2; fd++)
|
||||||
Libc::file_descriptor_allocator()->preserve(fd);
|
file_descriptor_allocator()->preserve(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ void Libc::Kernel::handle_io_progress()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Libc::execute_in_application_context(Libc::Application_code &app_code)
|
void Libc::execute_in_application_context(Application_code &app_code)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The libc execution model builds on the main entrypoint, which handles
|
* The libc execution model builds on the main entrypoint, which handles
|
||||||
|
|
|
@ -72,7 +72,7 @@ int Libc::Mem_alloc_impl::Dataspace_pool::expand(size_t size, Range_allocator *a
|
||||||
|
|
||||||
/* now that we have new backing store, allocate Dataspace structure */
|
/* now that we have new backing store, allocate Dataspace structure */
|
||||||
if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).error()) {
|
if (alloc->alloc_aligned(sizeof(Dataspace), &ds_addr, 2).error()) {
|
||||||
Genode::warning("libc: could not allocate meta data - this should never happen");
|
warning("libc: could not allocate meta data - this should never happen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ void *Libc::Mem_alloc_impl::alloc(size_t size, size_t align_log2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ds_pool.expand(align_addr(request_size, 12), &_alloc) < 0) {
|
if (_ds_pool.expand(align_addr(request_size, 12), &_alloc) < 0) {
|
||||||
Genode::warning("libc: could not expand dataspace pool");
|
warning("libc: could not expand dataspace pool");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ void Libc::Mem_alloc_impl::free(void *addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Genode::size_t Libc::Mem_alloc_impl::size_at(void const *addr) const
|
size_t Libc::Mem_alloc_impl::size_at(void const *addr) const
|
||||||
{
|
{
|
||||||
/* serialize access of heap functions */
|
/* serialize access of heap functions */
|
||||||
Lock::Guard lock_guard(_lock);
|
Lock::Guard lock_guard(_lock);
|
||||||
|
@ -147,7 +147,7 @@ static Libc::Mem_alloc *_libc_mem_alloc_rw = nullptr;
|
||||||
static Libc::Mem_alloc *_libc_mem_alloc_rwx = nullptr;
|
static Libc::Mem_alloc *_libc_mem_alloc_rwx = nullptr;
|
||||||
|
|
||||||
|
|
||||||
static void _init_mem_alloc(Genode::Region_map &rm, Genode::Ram_allocator &ram)
|
static void _init_mem_alloc(Region_map &rm, Ram_allocator &ram)
|
||||||
{
|
{
|
||||||
enum { MEMORY_EXECUTABLE = true };
|
enum { MEMORY_EXECUTABLE = true };
|
||||||
|
|
||||||
|
@ -159,12 +159,9 @@ static void _init_mem_alloc(Genode::Region_map &rm, Genode::Ram_allocator &ram)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Libc {
|
void Libc::init_mem_alloc(Genode::Env &env)
|
||||||
|
{
|
||||||
void init_mem_alloc(Genode::Env &env)
|
_init_mem_alloc(env.rm(), env.ram());
|
||||||
{
|
|
||||||
_init_mem_alloc(env.rm(), env.ram());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,6 @@ extern "C" {
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
class Slab_alloc;
|
class Slab_alloc;
|
||||||
class Malloc;
|
class Malloc;
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -226,7 +224,10 @@ class Libc::Malloc
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static Libc::Malloc *mallocator;
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
|
static Malloc *mallocator;
|
||||||
|
|
||||||
|
|
||||||
extern "C" void *malloc(size_t size)
|
extern "C" void *malloc(size_t size)
|
||||||
|
@ -263,16 +264,16 @@ extern "C" void *realloc(void *ptr, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Genode::Constructible<Libc::Malloc> &constructible_malloc()
|
static Genode::Constructible<Malloc> &constructible_malloc()
|
||||||
{
|
{
|
||||||
return *unmanaged_singleton<Genode::Constructible<Libc::Malloc> >();
|
return *unmanaged_singleton<Genode::Constructible<Malloc> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_malloc(Genode::Allocator &heap)
|
void Libc::init_malloc(Genode::Allocator &heap)
|
||||||
{
|
{
|
||||||
|
|
||||||
Genode::Constructible<Libc::Malloc> &_malloc = constructible_malloc();
|
Constructible<Malloc> &_malloc = constructible_malloc();
|
||||||
|
|
||||||
_malloc.construct(heap);
|
_malloc.construct(heap);
|
||||||
|
|
||||||
|
@ -290,7 +291,7 @@ void Libc::init_malloc_cloned(Clone_connection &clone_connection)
|
||||||
|
|
||||||
void Libc::reinit_malloc(Genode::Allocator &heap)
|
void Libc::reinit_malloc(Genode::Allocator &heap)
|
||||||
{
|
{
|
||||||
Libc::Malloc &malloc = *constructible_malloc();
|
Malloc &malloc = *constructible_malloc();
|
||||||
|
|
||||||
Genode::construct_at<Libc::Malloc>(&malloc, heap);
|
construct_at<Malloc>(&malloc, heap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,10 @@
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
#include <internal/resume.h>
|
#include <internal/resume.h>
|
||||||
|
|
||||||
using namespace Genode;
|
|
||||||
using namespace Libc;
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
static Libc::Resume *_resume_ptr;
|
static Resume *_resume_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_plugin(Resume &resume)
|
void Libc::init_plugin(Resume &resume)
|
||||||
|
@ -156,7 +155,7 @@ bool Plugin::supports_mmap()
|
||||||
#define DUMMY(ret_type, ret_val, name, args) \
|
#define DUMMY(ret_type, ret_val, name, args) \
|
||||||
ret_type Plugin::name args \
|
ret_type Plugin::name args \
|
||||||
{ \
|
{ \
|
||||||
Genode::error(__func__, ": " #name " not implemented"); \
|
error(__func__, ": " #name " not implemented"); \
|
||||||
return ret_val; \
|
return ret_val; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
#include <internal/suspend.h>
|
#include <internal/suspend.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
static Libc::Suspend *_suspend_ptr;
|
|
||||||
|
static Suspend *_suspend_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_poll(Suspend &suspend)
|
void Libc::init_poll(Suspend &suspend)
|
||||||
|
@ -36,11 +38,11 @@ void Libc::init_poll(Suspend &suspend)
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
int poll(struct pollfd fds[], nfds_t nfds, int timeout_ms)
|
int poll(struct pollfd fds[], nfds_t nfds, int timeout_ms)
|
||||||
{
|
{
|
||||||
using namespace Libc;
|
using Genode::uint64_t;
|
||||||
|
|
||||||
if (!fds || nfds == 0) return Errno(EINVAL);
|
if (!fds || nfds == 0) return Errno(EINVAL);
|
||||||
|
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
pollfd *_fds;
|
pollfd *_fds;
|
||||||
nfds_t const _nfds;
|
nfds_t const _nfds;
|
||||||
|
@ -65,7 +67,7 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout_ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!libc_fd->plugin || !libc_fd->plugin->supports_poll()) {
|
if (!libc_fd->plugin || !libc_fd->plugin->supports_poll()) {
|
||||||
Genode::warning("poll not supported for file descriptor ", pfd.fd);
|
warning("poll not supported for file descriptor ", pfd.fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +86,7 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout_ms)
|
||||||
return check.nready;
|
return check.nready;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto suspend = [&] (Genode::uint64_t timeout_ms)
|
auto suspend = [&] (uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
struct Missing_call_of_init_poll : Exception { };
|
struct Missing_call_of_init_poll : Exception { };
|
||||||
if (!_suspend_ptr)
|
if (!_suspend_ptr)
|
||||||
|
@ -98,7 +100,7 @@ int poll(struct pollfd fds[], nfds_t nfds, int timeout_ms)
|
||||||
suspend(0);
|
suspend(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Genode::uint64_t remaining_ms = timeout_ms;
|
uint64_t remaining_ms = timeout_ms;
|
||||||
while (check.nready == 0 && remaining_ms > 0) {
|
while (check.nready == 0 && remaining_ms > 0) {
|
||||||
remaining_ms = suspend(remaining_ms);
|
remaining_ms = suspend(remaining_ms);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
|
||||||
struct Read
|
struct Read
|
||||||
{
|
{
|
||||||
|
@ -39,16 +42,19 @@ struct Write
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
template <typename Rw_func, typename Buf_type>
|
template <typename Rw_func, typename Buf_type>
|
||||||
static ssize_t pread_pwrite_impl(Rw_func rw_func, int fd, Buf_type buf, ::size_t count, ::off_t offset)
|
static ssize_t pread_pwrite_impl(Rw_func rw_func, int fd, Buf_type buf, ::size_t count, ::off_t offset)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fdesc = Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
File_descriptor *fdesc = file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
if (fdesc == 0)
|
if (fdesc == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
Genode::Lock_guard<Genode::Lock> rw_lock_guard(fdesc->lock);
|
Lock_guard<Lock> rw_lock_guard(fdesc->lock);
|
||||||
|
|
||||||
off_t old_offset = lseek(fd, 0, SEEK_CUR);
|
::off_t old_offset = lseek(fd, 0, SEEK_CUR);
|
||||||
|
|
||||||
if (old_offset == -1)
|
if (old_offset == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -31,16 +31,16 @@
|
||||||
#include <internal/suspend.h>
|
#include <internal/suspend.h>
|
||||||
#include <internal/resume.h>
|
#include <internal/resume.h>
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
static Env *_env_ptr; /* solely needed to spawn the timeout thread for the
|
static Genode::Env *_env_ptr; /* solely needed to spawn the timeout thread for the
|
||||||
timed semaphore */
|
timed semaphore */
|
||||||
|
|
||||||
static Thread *_main_thread_ptr;
|
static Thread *_main_thread_ptr;
|
||||||
|
|
||||||
static Libc::Suspend *_suspend_ptr;
|
static Suspend *_suspend_ptr;
|
||||||
static Libc::Resume *_resume_ptr;
|
static Resume *_resume_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_pthread_support(Genode::Env &env, Suspend &suspend, Resume &resume)
|
void Libc::init_pthread_support(Genode::Env &env, Suspend &suspend, Resume &resume)
|
||||||
|
@ -58,15 +58,16 @@ static Libc::Timeout_entrypoint &_global_timeout_ep()
|
||||||
if (!_env_ptr)
|
if (!_env_ptr)
|
||||||
throw Missing_call_of_init_pthread_support();
|
throw Missing_call_of_init_pthread_support();
|
||||||
|
|
||||||
static Libc::Timeout_entrypoint timeout_ep { *_env_ptr };
|
static Timeout_entrypoint timeout_ep { *_env_ptr };
|
||||||
return timeout_ep;
|
return timeout_ep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*************
|
||||||
* pthread
|
** Pthread **
|
||||||
*/
|
*************/
|
||||||
void pthread::Thread_object::entry()
|
|
||||||
|
void Libc::Pthread::Thread_object::entry()
|
||||||
{
|
{
|
||||||
/* obtain stack attributes of new thread */
|
/* obtain stack attributes of new thread */
|
||||||
Thread::Stack_info info = Thread::mystack();
|
Thread::Stack_info info = Thread::mystack();
|
||||||
|
@ -77,15 +78,15 @@ void pthread::Thread_object::entry()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pthread::join(void **retval)
|
void Libc::Pthread::join(void **retval)
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
pthread &_thread;
|
Pthread &_thread;
|
||||||
|
|
||||||
Check(pthread &thread) : _thread(thread) { }
|
Check(Pthread &thread) : _thread(thread) { }
|
||||||
|
|
||||||
bool suspend() override
|
bool suspend() override
|
||||||
{
|
{
|
||||||
|
@ -109,7 +110,7 @@ void pthread::join(void **retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void pthread::cancel()
|
void Libc::Pthread::cancel()
|
||||||
{
|
{
|
||||||
_exiting = true;
|
_exiting = true;
|
||||||
|
|
||||||
|
@ -127,49 +128,49 @@ void pthread::cancel()
|
||||||
* Registry
|
* Registry
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Pthread_registry::insert(pthread_t thread)
|
void Libc::Pthread_registry::insert(Pthread &thread)
|
||||||
{
|
{
|
||||||
/* prevent multiple insertions at the same location */
|
/* prevent multiple insertions at the same location */
|
||||||
static Genode::Lock insert_lock;
|
static Lock insert_lock;
|
||||||
Genode::Lock::Guard insert_lock_guard(insert_lock);
|
Lock::Guard insert_lock_guard(insert_lock);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
|
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
|
||||||
if (_array[i] == 0) {
|
if (_array[i] == 0) {
|
||||||
_array[i] = thread;
|
_array[i] = &thread;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::error("pthread registry overflow, pthread_self() might fail");
|
error("pthread registry overflow, pthread_self() might fail");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Pthread_registry::remove(pthread_t thread)
|
void Libc::Pthread_registry::remove(Pthread &thread)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
|
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++) {
|
||||||
if (_array[i] == thread) {
|
if (_array[i] == &thread) {
|
||||||
_array[i] = 0;
|
_array[i] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::error("could not remove unknown pthread from registry");
|
error("could not remove unknown pthread from registry");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Pthread_registry::contains(pthread_t thread)
|
bool Libc::Pthread_registry::contains(Pthread &thread)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++)
|
for (unsigned int i = 0; i < MAX_NUM_PTHREADS; i++)
|
||||||
if (_array[i] == thread)
|
if (_array[i] == &thread)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Pthread_registry &pthread_registry()
|
Libc::Pthread_registry &pthread_registry()
|
||||||
{
|
{
|
||||||
static Pthread_registry instance;
|
static Libc::Pthread_registry instance;
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +225,7 @@ extern "C" {
|
||||||
void pthread_exit(void *value_ptr)
|
void pthread_exit(void *value_ptr)
|
||||||
{
|
{
|
||||||
pthread_self()->exit(value_ptr);
|
pthread_self()->exit(value_ptr);
|
||||||
Genode::sleep_forever();
|
sleep_forever();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ extern "C" {
|
||||||
pthread_t pthread_myself =
|
pthread_t pthread_myself =
|
||||||
static_cast<pthread_t>(&Thread::Tls::Base::tls());
|
static_cast<pthread_t>(&Thread::Tls::Base::tls());
|
||||||
|
|
||||||
if (pthread_registry().contains(pthread_myself))
|
if (pthread_registry().contains(*pthread_myself))
|
||||||
return pthread_myself;
|
return pthread_myself;
|
||||||
}
|
}
|
||||||
catch (Thread::Tls::Base::Undefined) { }
|
catch (Thread::Tls::Base::Undefined) { }
|
||||||
|
@ -290,7 +291,7 @@ extern "C" {
|
||||||
stacksize = max_stack;
|
stacksize = max_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*attr)->stack_size = Genode::align_addr(stacksize, 12);
|
(*attr)->stack_size = align_addr(stacksize, 12);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -622,7 +623,7 @@ extern "C" {
|
||||||
int num_waiters;
|
int num_waiters;
|
||||||
int num_signallers;
|
int num_signallers;
|
||||||
Lock counter_lock;
|
Lock counter_lock;
|
||||||
Libc::Timed_semaphore signal_sem { _global_timeout_ep() };
|
Timed_semaphore signal_sem { _global_timeout_ep() };
|
||||||
Semaphore handshake_sem;
|
Semaphore handshake_sem;
|
||||||
|
|
||||||
pthread_cond() : num_waiters(0), num_signallers(0) { }
|
pthread_cond() : num_waiters(0), num_signallers(0) { }
|
||||||
|
@ -666,13 +667,13 @@ extern "C" {
|
||||||
static int cond_init(pthread_cond_t *__restrict cond,
|
static int cond_init(pthread_cond_t *__restrict cond,
|
||||||
const pthread_condattr_t *__restrict attr)
|
const pthread_condattr_t *__restrict attr)
|
||||||
{
|
{
|
||||||
static Genode::Lock cond_init_lock { };
|
static Lock cond_init_lock { };
|
||||||
|
|
||||||
if (!cond)
|
if (!cond)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Genode::Lock::Guard g(cond_init_lock);
|
Lock::Guard g(cond_init_lock);
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
*cond = new (alloc) pthread_cond;
|
*cond = new (alloc) pthread_cond;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -771,9 +772,9 @@ extern "C" {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
c->signal_sem.down(timeout);
|
c->signal_sem.down(timeout);
|
||||||
} catch (Libc::Timeout_exception) {
|
} catch (Timeout_exception) {
|
||||||
result = ETIMEDOUT;
|
result = ETIMEDOUT;
|
||||||
} catch (Libc::Nonblocking_exception) {
|
} catch (Nonblocking_exception) {
|
||||||
errno = ETIMEDOUT;
|
errno = ETIMEDOUT;
|
||||||
result = ETIMEDOUT;
|
result = ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
int Libc::pthread_create(pthread_t *thread,
|
int Libc::pthread_create(pthread_t *thread,
|
||||||
void *(*start_routine) (void *), void *arg,
|
void *(*start_routine) (void *), void *arg,
|
||||||
size_t stack_size, char const * name,
|
size_t stack_size, char const * name,
|
||||||
Genode::Cpu_session * cpu, Genode::Affinity::Location location)
|
Cpu_session * cpu, Affinity::Location location)
|
||||||
{
|
{
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
pthread_t thread_obj = new (alloc)
|
pthread_t thread_obj = new (alloc)
|
||||||
|
@ -43,7 +43,7 @@ int Libc::pthread_create(pthread_t *thread,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::pthread_create(pthread_t *thread, Genode::Thread &t)
|
int Libc::pthread_create(pthread_t *thread, Thread &t)
|
||||||
{
|
{
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
pthread_t thread_obj = new (alloc) pthread(t);
|
pthread_t thread_obj = new (alloc) pthread(t);
|
||||||
|
|
|
@ -22,28 +22,33 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
struct Read
|
struct Read
|
||||||
{
|
{
|
||||||
ssize_t operator()(int fd, void *buf, size_t count)
|
ssize_t operator()(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
return read(fd, buf, count);
|
return read(fd, buf, count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Write
|
struct Write
|
||||||
{
|
{
|
||||||
ssize_t operator()(int fd, const void *buf, size_t count)
|
ssize_t operator()(int fd, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
return write(fd, buf, count);
|
return write(fd, buf, count);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static Genode::Lock &rw_lock()
|
static Lock &rw_lock()
|
||||||
{
|
{
|
||||||
static Genode::Lock rw_lock;
|
static Lock rw_lock;
|
||||||
return rw_lock;
|
return rw_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +56,7 @@ static Genode::Lock &rw_lock()
|
||||||
template <typename Rw_func>
|
template <typename Rw_func>
|
||||||
static ssize_t readv_writev_impl(Rw_func rw_func, int fd, const struct iovec *iov, int iovcnt)
|
static ssize_t readv_writev_impl(Rw_func rw_func, int fd, const struct iovec *iov, int iovcnt)
|
||||||
{
|
{
|
||||||
Genode::Lock_guard<Genode::Lock> rw_lock_guard(rw_lock());
|
Lock_guard<Lock> rw_lock_guard(rw_lock());
|
||||||
|
|
||||||
char *v;
|
char *v;
|
||||||
ssize_t bytes_transfered_total = 0;
|
ssize_t bytes_transfered_total = 0;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* \brief POSIX readers/writer lock (rwlock) implementation
|
* \brief POSIX readers/writer lock (rwlock) implementation
|
||||||
* \author Alexander Senier
|
* \author Alexander Senier
|
||||||
* \date 2018-01-25
|
* \date 2018-01-25
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -19,10 +18,15 @@
|
||||||
#include <base/thread.h>
|
#include <base/thread.h>
|
||||||
#include <libc/allocator.h>
|
#include <libc/allocator.h>
|
||||||
|
|
||||||
/* Libc includes */
|
/* libc includes */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A reader-preferring implementation of a readers-writer lock as described
|
* A reader-preferring implementation of a readers-writer lock as described
|
||||||
|
@ -40,16 +44,16 @@ extern "C" {
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Genode::Thread *_owner = nullptr;
|
Thread *_owner = nullptr;
|
||||||
Genode::Lock _nbr_mutex {};
|
Lock _nbr_mutex {};
|
||||||
Genode::Lock _global_mutex {};
|
Lock _global_mutex {};
|
||||||
int _nbr = 0;
|
int _nbr = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void rdlock()
|
void rdlock()
|
||||||
{
|
{
|
||||||
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
Lock_guard<Lock> guard(_nbr_mutex);
|
||||||
++_nbr;
|
++_nbr;
|
||||||
if (_nbr == 1) {
|
if (_nbr == 1) {
|
||||||
_global_mutex.lock();
|
_global_mutex.lock();
|
||||||
|
@ -60,14 +64,14 @@ extern "C" {
|
||||||
void wrlock()
|
void wrlock()
|
||||||
{
|
{
|
||||||
_global_mutex.lock();
|
_global_mutex.lock();
|
||||||
_owner = Genode::Thread::myself();
|
_owner = Thread::myself();
|
||||||
}
|
}
|
||||||
|
|
||||||
int unlock()
|
int unlock()
|
||||||
{
|
{
|
||||||
/* Read lock */
|
/* Read lock */
|
||||||
if (_owner == nullptr) {
|
if (_owner == nullptr) {
|
||||||
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
Lock_guard<Lock> guard(_nbr_mutex);
|
||||||
_nbr--;
|
_nbr--;
|
||||||
if (_nbr == 0) {
|
if (_nbr == 0) {
|
||||||
_owner = nullptr;
|
_owner = nullptr;
|
||||||
|
@ -76,8 +80,8 @@ extern "C" {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_owner != Genode::Thread::myself()) {
|
if (_owner != Thread::myself()) {
|
||||||
Genode::error("Unlocking writer lock owned by other thread");
|
error("Unlocking writer lock owned by other thread");
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
@ -95,13 +99,13 @@ extern "C" {
|
||||||
|
|
||||||
static int rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
static int rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
||||||
{
|
{
|
||||||
static Genode::Lock rwlock_init_lock { };
|
static Lock rwlock_init_lock { };
|
||||||
|
|
||||||
if (!rwlock)
|
if (!rwlock)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Genode::Lock::Guard g(rwlock_init_lock);
|
Lock::Guard g(rwlock_init_lock);
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
*rwlock = new (alloc) struct pthread_rwlock();
|
*rwlock = new (alloc) struct pthread_rwlock();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -45,10 +45,12 @@ namespace Libc {
|
||||||
struct Select_cb_list;
|
struct Select_cb_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
static Libc::Suspend *_suspend_ptr;
|
|
||||||
static Libc::Resume *_resume_ptr;
|
static Suspend *_suspend_ptr;
|
||||||
static Libc::Select *_select_ptr;
|
static Resume *_resume_ptr;
|
||||||
|
static Select *_select_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_select(Suspend &suspend, Resume &resume, Select &select)
|
void Libc::init_select(Suspend &suspend, Resume &resume, Select &select)
|
||||||
|
@ -82,14 +84,14 @@ struct Libc::Select_cb
|
||||||
|
|
||||||
struct Libc::Select_cb_list
|
struct Libc::Select_cb_list
|
||||||
{
|
{
|
||||||
Genode::Lock _mutex;
|
Lock _mutex;
|
||||||
Select_cb *_first = nullptr;
|
Select_cb *_first = nullptr;
|
||||||
|
|
||||||
struct Guard : Genode::Lock::Guard
|
struct Guard : Lock::Guard
|
||||||
{
|
{
|
||||||
Select_cb_list *l;
|
Select_cb_list *l;
|
||||||
|
|
||||||
Guard(Select_cb_list &list) : Genode::Lock::Guard(list._mutex), l(&list) { }
|
Guard(Select_cb_list &list) : Lock::Guard(list._mutex), l(&list) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
void unsynchronized_insert(Select_cb *scb)
|
void unsynchronized_insert(Select_cb *scb)
|
||||||
|
@ -130,7 +132,7 @@ struct Libc::Select_cb_list
|
||||||
/** The global list of tasks waiting for select */
|
/** The global list of tasks waiting for select */
|
||||||
static Libc::Select_cb_list &select_cb_list()
|
static Libc::Select_cb_list &select_cb_list()
|
||||||
{
|
{
|
||||||
static Libc::Select_cb_list inst;
|
static Select_cb_list inst;
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +164,7 @@ static int selscan(int nfds,
|
||||||
if (out_writefds) FD_ZERO(out_writefds);
|
if (out_writefds) FD_ZERO(out_writefds);
|
||||||
if (out_exceptfds) FD_ZERO(out_exceptfds);
|
if (out_exceptfds) FD_ZERO(out_exceptfds);
|
||||||
|
|
||||||
for (Libc::Plugin *plugin = Libc::plugin_registry()->first();
|
for (Plugin *plugin = plugin_registry()->first();
|
||||||
plugin;
|
plugin;
|
||||||
plugin = plugin->next()) {
|
plugin = plugin->next()) {
|
||||||
if (plugin->supports_select(nfds, in_readfds, in_writefds, in_exceptfds, &tv_0)) {
|
if (plugin->supports_select(nfds, in_readfds, in_writefds, in_exceptfds, &tv_0)) {
|
||||||
|
@ -187,7 +189,7 @@ static int selscan(int nfds,
|
||||||
}
|
}
|
||||||
nready += plugin_nready;
|
nready += plugin_nready;
|
||||||
} else if (plugin_nready < 0) {
|
} else if (plugin_nready < 0) {
|
||||||
Genode::error("plugin->select() returned error value ", plugin_nready);
|
error("plugin->select() returned error value ", plugin_nready);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +207,7 @@ static void select_notify()
|
||||||
/* check for each waiting select() function if one of its fds is ready now
|
/* check for each waiting select() function if one of its fds is ready now
|
||||||
* and if so, wake all up */
|
* and if so, wake all up */
|
||||||
|
|
||||||
select_cb_list().for_each([&] (Libc::Select_cb &scb) {
|
select_cb_list().for_each([&] (Select_cb &scb) {
|
||||||
scb.nready = selscan(scb.nfds,
|
scb.nready = selscan(scb.nfds,
|
||||||
&scb.readfds, &scb.writefds, &scb.exceptfds,
|
&scb.readfds, &scb.writefds, &scb.exceptfds,
|
||||||
&tmp_readfds, &tmp_writefds, &tmp_exceptfds);
|
&tmp_readfds, &tmp_writefds, &tmp_exceptfds);
|
||||||
|
@ -219,7 +221,7 @@ static void select_notify()
|
||||||
});
|
});
|
||||||
|
|
||||||
if (resume_all) {
|
if (resume_all) {
|
||||||
struct Missing_call_of_init_select : Genode::Exception { };
|
struct Missing_call_of_init_select : Exception { };
|
||||||
if (!_resume_ptr)
|
if (!_resume_ptr)
|
||||||
throw Missing_call_of_init_select();
|
throw Missing_call_of_init_select();
|
||||||
|
|
||||||
|
@ -228,7 +230,7 @@ static void select_notify()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void print(Genode::Output &output, timeval *tv)
|
static inline void print(Output &output, timeval *tv)
|
||||||
{
|
{
|
||||||
if (!tv) {
|
if (!tv) {
|
||||||
print(output, "nullptr");
|
print(output, "nullptr");
|
||||||
|
@ -248,7 +250,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
{
|
{
|
||||||
fd_set in_readfds, in_writefds, in_exceptfds;
|
fd_set in_readfds, in_writefds, in_exceptfds;
|
||||||
|
|
||||||
Genode::Constructible<Libc::Select_cb> select_cb;
|
Constructible<Select_cb> select_cb;
|
||||||
|
|
||||||
/* initialize the select notification function pointer */
|
/* initialize the select notification function pointer */
|
||||||
if (!libc_select_notify)
|
if (!libc_select_notify)
|
||||||
|
@ -263,7 +265,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
* We use the guard directly to atomically check if any descripor is
|
* We use the guard directly to atomically check if any descripor is
|
||||||
* ready, but insert into select-callback list otherwise.
|
* ready, but insert into select-callback list otherwise.
|
||||||
*/
|
*/
|
||||||
Libc::Select_cb_list::Guard guard(select_cb_list());
|
Select_cb_list::Guard guard(select_cb_list());
|
||||||
|
|
||||||
int const nready = selscan(nfds,
|
int const nready = selscan(nfds,
|
||||||
&in_readfds, &in_writefds, &in_exceptfds,
|
&in_readfds, &in_writefds, &in_exceptfds,
|
||||||
|
@ -296,11 +298,12 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
Timeout(timeval *tv) : _tv(tv) { }
|
Timeout(timeval *tv) : _tv(tv) { }
|
||||||
} timeout { tv };
|
} timeout { tv };
|
||||||
|
|
||||||
struct Check : Libc::Suspend_functor {
|
struct Check : Suspend_functor
|
||||||
struct Timeout *timeout;
|
{
|
||||||
Libc::Select_cb *select_cb;
|
struct Timeout *timeout;
|
||||||
|
Select_cb *select_cb;
|
||||||
|
|
||||||
Check(Timeout *timeout, Libc::Select_cb * select_cb)
|
Check(Timeout *timeout, Select_cb * select_cb)
|
||||||
: timeout(timeout), select_cb(select_cb) { }
|
: timeout(timeout), select_cb(select_cb) { }
|
||||||
|
|
||||||
bool suspend() override {
|
bool suspend() override {
|
||||||
|
@ -308,7 +311,7 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||||
} check ( &timeout, &*select_cb );
|
} check ( &timeout, &*select_cb );
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Missing_call_of_init_select : Genode::Exception { };
|
struct Missing_call_of_init_select : Exception { };
|
||||||
if (!_suspend_ptr)
|
if (!_suspend_ptr)
|
||||||
throw Missing_call_of_init_select();
|
throw Missing_call_of_init_select();
|
||||||
}
|
}
|
||||||
|
@ -392,7 +395,7 @@ int Libc::Select_handler_base::select(int nfds, fd_set &readfds,
|
||||||
* We use the guard directly to atomically check is any descripor is
|
* We use the guard directly to atomically check is any descripor is
|
||||||
* ready, and insert into select-callback list otherwise.
|
* ready, and insert into select-callback list otherwise.
|
||||||
*/
|
*/
|
||||||
Libc::Select_cb_list::Guard guard(select_cb_list());
|
Select_cb_list::Guard guard(select_cb_list());
|
||||||
|
|
||||||
int const nready = selscan(nfds,
|
int const nready = selscan(nfds,
|
||||||
&in_readfds, &in_writefds, &in_exceptfds,
|
&in_readfds, &in_writefds, &in_exceptfds,
|
||||||
|
@ -440,5 +443,6 @@ Libc::Select_handler_base::Select_handler_base()
|
||||||
_select_cb((Select_handler_cb*)malloc(sizeof(*_select_cb)))
|
_select_cb((Select_handler_cb*)malloc(sizeof(*_select_cb)))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
Libc::Select_handler_base::~Select_handler_base()
|
Libc::Select_handler_base::~Select_handler_base()
|
||||||
{ }
|
{ }
|
||||||
|
|
|
@ -20,7 +20,10 @@
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <libc/allocator.h>
|
#include <libc/allocator.h>
|
||||||
|
|
||||||
using namespace Genode;
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
|
@ -24,6 +24,11 @@ extern "C" {
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
|
|
||||||
|
/* libc-internal includes */
|
||||||
|
#include <internal/types.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
int sigprocmask(int how, const sigset_t *set, sigset_t *old_set)
|
int sigprocmask(int how, const sigset_t *set, sigset_t *old_set)
|
||||||
|
@ -78,7 +83,7 @@ extern "C" pid_t _waitpid(pid_t pid, int *istat, int options) {
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
pid_t wait6(idtype_t, id_t, int*, int, struct __wrusage*, siginfo_t*)
|
pid_t wait6(idtype_t, id_t, int*, int, struct __wrusage*, siginfo_t*)
|
||||||
{
|
{
|
||||||
Genode::warning(__func__, " not implemented");
|
warning(__func__, " not implemented");
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
#include <internal/suspend.h>
|
#include <internal/suspend.h>
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
static Libc::Suspend *_suspend_ptr;
|
|
||||||
|
static Suspend *_suspend_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_sleep(Suspend &suspend)
|
void Libc::init_sleep(Suspend &suspend)
|
||||||
|
@ -33,7 +35,7 @@ static void millisleep(Genode::uint64_t timeout_ms)
|
||||||
{
|
{
|
||||||
Genode::uint64_t remaining_ms = timeout_ms;
|
Genode::uint64_t remaining_ms = timeout_ms;
|
||||||
|
|
||||||
struct Missing_call_of_init_sleep : Genode::Exception { };
|
struct Missing_call_of_init_sleep : Exception { };
|
||||||
if (!_suspend_ptr)
|
if (!_suspend_ptr)
|
||||||
throw Missing_call_of_init_sleep();
|
throw Missing_call_of_init_sleep();
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ static void millisleep(Genode::uint64_t timeout_ms)
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
int nanosleep(const struct timespec *req, struct timespec *rem)
|
int nanosleep(const struct timespec *req, struct timespec *rem)
|
||||||
{
|
{
|
||||||
Genode::uint64_t sleep_ms = (uint64_t)req->tv_sec*1000;
|
Genode::uint64_t sleep_ms = (Genode::uint64_t)req->tv_sec*1000;
|
||||||
if (req->tv_nsec)
|
if (req->tv_nsec)
|
||||||
sleep_ms += req->tv_nsec / 1000000;
|
sleep_ms += req->tv_nsec / 1000000;
|
||||||
millisleep(sleep_ms);
|
millisleep(sleep_ms);
|
||||||
|
@ -74,7 +76,7 @@ int clock_nanosleep(clockid_t clock_id, int flags,
|
||||||
if (flags & TIMER_ABSTIME) {
|
if (flags & TIMER_ABSTIME) {
|
||||||
struct timespec now_ts { 0 };
|
struct timespec now_ts { 0 };
|
||||||
if (clock_gettime(clock_id, &now_ts) != 0) {
|
if (clock_gettime(clock_id, &now_ts) != 0) {
|
||||||
Genode::error(__func__, ": RTC device not configured");
|
error(__func__, ": RTC device not configured");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ int __sys_clock_nanosleep(clockid_t clock_id, int flags,
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
unsigned int sleep(unsigned int seconds)
|
unsigned int sleep(unsigned int seconds)
|
||||||
{
|
{
|
||||||
Genode::uint64_t sleep_ms = 1000 * (Genode::uint64_t)seconds;
|
Genode::uint64_t const sleep_ms = 1000 * (Genode::uint64_t)seconds;
|
||||||
millisleep(sleep_ms);
|
millisleep(sleep_ms);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
extern char const *config_socket();
|
extern char const *config_socket();
|
||||||
bool read_ready(Libc::File_descriptor *);
|
bool read_ready(File_descriptor *);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,9 +62,7 @@ void Libc::init_socket_fs(Suspend &suspend)
|
||||||
** Utilities **
|
** Utilities **
|
||||||
***************/
|
***************/
|
||||||
|
|
||||||
namespace Socket_fs {
|
namespace Libc { namespace Socket_fs {
|
||||||
|
|
||||||
using Libc::Errno;
|
|
||||||
|
|
||||||
struct Absolute_path : Vfs::Absolute_path
|
struct Absolute_path : Vfs::Absolute_path
|
||||||
{
|
{
|
||||||
|
@ -83,7 +81,6 @@ namespace Socket_fs {
|
||||||
typedef String<NI_MAXSERV> Port_string;
|
typedef String<NI_MAXSERV> Port_string;
|
||||||
struct Sockaddr_string;
|
struct Sockaddr_string;
|
||||||
|
|
||||||
struct Exception { };
|
|
||||||
struct New_socket_failed : Exception { };
|
struct New_socket_failed : Exception { };
|
||||||
struct Address_conversion_failed : Exception { };
|
struct Address_conversion_failed : Exception { };
|
||||||
|
|
||||||
|
@ -96,13 +93,13 @@ namespace Socket_fs {
|
||||||
Plugin & plugin();
|
Plugin & plugin();
|
||||||
|
|
||||||
enum { MAX_CONTROL_PATH_LEN = 16 };
|
enum { MAX_CONTROL_PATH_LEN = 16 };
|
||||||
}
|
} }
|
||||||
|
|
||||||
|
|
||||||
using namespace Socket_fs;
|
using namespace Libc::Socket_fs;
|
||||||
|
|
||||||
|
|
||||||
struct Socket_fs::Context : Libc::Plugin_context
|
struct Libc::Socket_fs::Context : Plugin_context
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -129,7 +126,7 @@ struct Socket_fs::Context : Libc::Plugin_context
|
||||||
struct Inaccessible { }; /* exception */
|
struct Inaccessible { }; /* exception */
|
||||||
|
|
||||||
Absolute_path const path {
|
Absolute_path const path {
|
||||||
_read_socket_path().base(), Libc::config_socket() };
|
_read_socket_path().base(), config_socket() };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -139,9 +136,9 @@ struct Socket_fs::Context : Libc::Plugin_context
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
char const *name;
|
char const *name;
|
||||||
int num;
|
int num;
|
||||||
Libc::File_descriptor *file;
|
File_descriptor *file;
|
||||||
} _fd[Fd::MAX] = {
|
} _fd[Fd::MAX] = {
|
||||||
{ "data", -1, nullptr },
|
{ "data", -1, nullptr },
|
||||||
{ "connect", -1, nullptr }, { "bind", -1, nullptr },
|
{ "connect", -1, nullptr }, { "bind", -1, nullptr },
|
||||||
|
@ -169,11 +166,11 @@ struct Socket_fs::Context : Libc::Plugin_context
|
||||||
Absolute_path file(_fd[type].name, path.base());
|
Absolute_path file(_fd[type].name, path.base());
|
||||||
int const fd = open(file.base(), flags|_fd_flags);
|
int const fd = open(file.base(), flags|_fd_flags);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
Genode::error(__func__, ": ", _fd[type].name, " file not accessible at ", file);
|
error(__func__, ": ", _fd[type].name, " file not accessible at ", file);
|
||||||
throw Inaccessible();
|
throw Inaccessible();
|
||||||
}
|
}
|
||||||
_fd[type].num = fd;
|
_fd[type].num = fd;
|
||||||
_fd[type].file = Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
_fd[type].file = file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _fd[type].num;
|
return _fd[type].num;
|
||||||
|
@ -252,10 +249,12 @@ struct Socket_fs::Context : Libc::Plugin_context
|
||||||
sizeof(connect_status));
|
sizeof(connect_status));
|
||||||
|
|
||||||
if (connect_status_len <= 0) {
|
if (connect_status_len <= 0) {
|
||||||
Genode::error("socket_fs: reading from the connect file failed");
|
error("socket_fs: reading from the connect file failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ::strcmp;
|
||||||
|
|
||||||
if (strcmp(connect_status, "connected") == 0)
|
if (strcmp(connect_status, "connected") == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -265,13 +264,13 @@ struct Socket_fs::Context : Libc::Plugin_context
|
||||||
if (strcmp(connect_status, "not connected") == 0)
|
if (strcmp(connect_status, "not connected") == 0)
|
||||||
return Errno(ENOTCONN);
|
return Errno(ENOTCONN);
|
||||||
|
|
||||||
Genode::error("socket_fs: unhandled connection state");
|
error("socket_fs: unhandled connection state");
|
||||||
return Errno(ECONNREFUSED);
|
return Errno(ECONNREFUSED);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Socket_fs::Sockaddr_functor : Libc::Suspend_functor
|
struct Libc::Socket_fs::Sockaddr_functor : Suspend_functor
|
||||||
{
|
{
|
||||||
Socket_fs::Context &context;
|
Socket_fs::Context &context;
|
||||||
bool const nonblocking;
|
bool const nonblocking;
|
||||||
|
@ -283,7 +282,7 @@ struct Socket_fs::Sockaddr_functor : Libc::Suspend_functor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Socket_fs::Remote_functor : Socket_fs::Sockaddr_functor
|
struct Libc::Socket_fs::Remote_functor : Sockaddr_functor
|
||||||
{
|
{
|
||||||
Remote_functor(Socket_fs::Context &context, bool nonblocking)
|
Remote_functor(Socket_fs::Context &context, bool nonblocking)
|
||||||
: Sockaddr_functor(context, nonblocking) { }
|
: Sockaddr_functor(context, nonblocking) { }
|
||||||
|
@ -293,9 +292,9 @@ struct Socket_fs::Remote_functor : Socket_fs::Sockaddr_functor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Socket_fs::Local_functor : Socket_fs::Sockaddr_functor
|
struct Libc::Socket_fs::Local_functor : Sockaddr_functor
|
||||||
{
|
{
|
||||||
Local_functor(Socket_fs::Context &context, bool nonblocking)
|
Local_functor(Context &context, bool nonblocking)
|
||||||
: Sockaddr_functor(context, nonblocking) { }
|
: Sockaddr_functor(context, nonblocking) { }
|
||||||
|
|
||||||
bool suspend() override { return !nonblocking && !context.local_read_ready(); }
|
bool suspend() override { return !nonblocking && !context.local_read_ready(); }
|
||||||
|
@ -303,22 +302,22 @@ struct Socket_fs::Local_functor : Socket_fs::Sockaddr_functor
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Socket_fs::Plugin : Libc::Plugin
|
struct Libc::Socket_fs::Plugin : Libc::Plugin
|
||||||
{
|
{
|
||||||
bool supports_poll() override { return true; }
|
bool supports_poll() override { return true; }
|
||||||
bool supports_select(int, fd_set *, fd_set *, fd_set *, timeval *) override;
|
bool supports_select(int, fd_set *, fd_set *, fd_set *, timeval *) override;
|
||||||
|
|
||||||
ssize_t read(Libc::File_descriptor *, void *, ::size_t) override;
|
ssize_t read(File_descriptor *, void *, ::size_t) override;
|
||||||
ssize_t write(Libc::File_descriptor *, const void *, ::size_t) override;
|
ssize_t write(File_descriptor *, const void *, ::size_t) override;
|
||||||
int fcntl(Libc::File_descriptor *, int, long) override;
|
int fcntl(File_descriptor *, int, long) override;
|
||||||
int close(Libc::File_descriptor *) override;
|
int close(File_descriptor *) override;
|
||||||
bool poll(Libc::File_descriptor &fd, struct pollfd &pfd) override;
|
bool poll(File_descriptor &fd, struct pollfd &pfd) override;
|
||||||
int select(int, fd_set *, fd_set *, fd_set *, timeval *) override;
|
int select(int, fd_set *, fd_set *, fd_set *, timeval *) override;
|
||||||
int ioctl(Libc::File_descriptor *, int, char *) override;
|
int ioctl(File_descriptor *, int, char *) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <int CAPACITY> class Socket_fs::String
|
template <int CAPACITY> class Libc::Socket_fs::String
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -349,7 +348,7 @@ template <int CAPACITY> class Socket_fs::String
|
||||||
* Both NI_MAXHOST and NI_MAXSERV include the terminating 0, which allows
|
* Both NI_MAXHOST and NI_MAXSERV include the terminating 0, which allows
|
||||||
* use to put ':' between host and port on concatenation.
|
* use to put ':' between host and port on concatenation.
|
||||||
*/
|
*/
|
||||||
struct Socket_fs::Sockaddr_string : String<NI_MAXHOST + NI_MAXSERV>
|
struct Libc::Socket_fs::Sockaddr_string : String<NI_MAXHOST + NI_MAXSERV>
|
||||||
{
|
{
|
||||||
Sockaddr_string() { }
|
Sockaddr_string() { }
|
||||||
|
|
||||||
|
@ -389,6 +388,9 @@ struct Socket_fs::Sockaddr_string : String<NI_MAXHOST + NI_MAXSERV>
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
static Port_string port_string(sockaddr_in const &addr)
|
static Port_string port_string(sockaddr_in const &addr)
|
||||||
{
|
{
|
||||||
Port_string port;
|
Port_string port;
|
||||||
|
@ -422,7 +424,7 @@ static sockaddr_in sockaddr_in_struct(Host_string const &host, Port_string const
|
||||||
addrinfo hints;
|
addrinfo hints;
|
||||||
addrinfo *info = nullptr;
|
addrinfo *info = nullptr;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
::memset(&hints, 0, sizeof(hints));
|
||||||
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
|
hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV;
|
||||||
|
|
||||||
if (getaddrinfo(host.base(), port.base(), &hints, &info))
|
if (getaddrinfo(host.base(), port.base(), &hints, &info))
|
||||||
|
@ -468,12 +470,12 @@ static int read_sockaddr_in(Socket_fs::Sockaddr_functor &func,
|
||||||
try {
|
try {
|
||||||
/* convert the address but do not exceed the caller's buffer */
|
/* convert the address but do not exceed the caller's buffer */
|
||||||
sockaddr_in saddr = sockaddr_in_struct(addr_string.host(), addr_string.port());
|
sockaddr_in saddr = sockaddr_in_struct(addr_string.host(), addr_string.port());
|
||||||
memcpy(addr, &saddr, *addrlen);
|
::memcpy(addr, &saddr, *addrlen);
|
||||||
*addrlen = sizeof(saddr);
|
*addrlen = sizeof(saddr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} catch (Address_conversion_failed) {
|
} catch (Address_conversion_failed) {
|
||||||
Genode::warning("IP address conversion failed");
|
warning("IP address conversion failed");
|
||||||
return Errno(ENOBUFS);
|
return Errno(ENOBUFS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,7 +487,7 @@ static int read_sockaddr_in(Socket_fs::Sockaddr_functor &func,
|
||||||
|
|
||||||
extern "C" int socket_fs_getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
extern "C" int socket_fs_getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -506,7 +508,7 @@ extern "C" int socket_fs_getpeername(int libc_fd, sockaddr *addr, socklen_t *add
|
||||||
|
|
||||||
extern "C" int socket_fs_getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
extern "C" int socket_fs_getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -523,7 +525,7 @@ extern "C" int socket_fs_getsockname(int libc_fd, sockaddr *addr, socklen_t *add
|
||||||
|
|
||||||
extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *listen_context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *listen_context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -545,12 +547,12 @@ extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
return Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Absolute_path path = listen_context->path;
|
Socket_fs::Absolute_path path = listen_context->path;
|
||||||
path.append("/accept_socket");
|
path.append("/accept_socket");
|
||||||
|
|
||||||
int handle_fd = ::open(path.base(), O_RDONLY);
|
int handle_fd = ::open(path.base(), O_RDONLY);
|
||||||
if (handle_fd < 0) {
|
if (handle_fd < 0) {
|
||||||
Genode::error("failed to open accept socket at ", path);
|
error("failed to open accept socket at ", path);
|
||||||
return Errno(EACCES);
|
return Errno(EACCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,8 +563,8 @@ extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
Socket_fs::Context(listen_context->proto(), handle_fd);
|
Socket_fs::Context(listen_context->proto(), handle_fd);
|
||||||
} catch (New_socket_failed) { return Errno(EACCES); }
|
} catch (New_socket_failed) { return Errno(EACCES); }
|
||||||
|
|
||||||
Libc::File_descriptor *accept_fd =
|
File_descriptor *accept_fd =
|
||||||
Libc::file_descriptor_allocator()->alloc(&plugin(), accept_context);
|
file_descriptor_allocator()->alloc(&plugin(), accept_context);
|
||||||
|
|
||||||
/* inherit the O_NONBLOCK flag if set */
|
/* inherit the O_NONBLOCK flag if set */
|
||||||
accept_context->fd_flags(listen_context->fd_flags());
|
accept_context->fd_flags(listen_context->fd_flags());
|
||||||
|
@ -579,7 +581,7 @@ extern "C" int socket_fs_accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
|
|
||||||
extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -588,7 +590,7 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl
|
||||||
if (!addr) return Errno(EFAULT);
|
if (!addr) return Errno(EFAULT);
|
||||||
|
|
||||||
if (addr->sa_family != AF_INET) {
|
if (addr->sa_family != AF_INET) {
|
||||||
Genode::error(__func__, ": family not supported");
|
error(__func__, ": family not supported");
|
||||||
return Errno(EAFNOSUPPORT);
|
return Errno(EAFNOSUPPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +603,7 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl
|
||||||
catch (Address_conversion_failed) { return Errno(EINVAL); }
|
catch (Address_conversion_failed) { return Errno(EINVAL); }
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int const len = strlen(addr_string.base());
|
int const len = ::strlen(addr_string.base());
|
||||||
int const n = write(context->bind_fd(), addr_string.base(), len);
|
int const n = write(context->bind_fd(), addr_string.base(), len);
|
||||||
if (n != len) return Errno(EACCES);
|
if (n != len) return Errno(EACCES);
|
||||||
|
|
||||||
|
@ -615,7 +617,7 @@ extern "C" int socket_fs_bind(int libc_fd, sockaddr const *addr, socklen_t addrl
|
||||||
|
|
||||||
extern "C" int socket_fs_connect(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
extern "C" int socket_fs_connect(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -643,7 +645,7 @@ extern "C" int socket_fs_connect(int libc_fd, sockaddr const *addr, socklen_t ad
|
||||||
|
|
||||||
context->state(Context::CONNECTING);
|
context->state(Context::CONNECTING);
|
||||||
|
|
||||||
int const len = strlen(addr_string.base());
|
int const len = ::strlen(addr_string.base());
|
||||||
int const n = write(context->connect_fd(), addr_string.base(), len);
|
int const n = write(context->connect_fd(), addr_string.base(), len);
|
||||||
|
|
||||||
if (n != len) return Errno(ECONNREFUSED);
|
if (n != len) return Errno(ECONNREFUSED);
|
||||||
|
@ -711,14 +713,14 @@ extern "C" int socket_fs_connect(int libc_fd, sockaddr const *addr, socklen_t ad
|
||||||
|
|
||||||
extern "C" int socket_fs_listen(int libc_fd, int backlog)
|
extern "C" int socket_fs_listen(int libc_fd, int backlog)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
if (!context) return Errno(ENOTSOCK);
|
if (!context) return Errno(ENOTSOCK);
|
||||||
|
|
||||||
char buf[MAX_CONTROL_PATH_LEN];
|
char buf[MAX_CONTROL_PATH_LEN];
|
||||||
int const len = snprintf(buf, sizeof(buf), "%d", backlog);
|
int const len = ::snprintf(buf, sizeof(buf), "%d", backlog);
|
||||||
int const n = write(context->listen_fd(), buf, len);
|
int const n = write(context->listen_fd(), buf, len);
|
||||||
if (n != len) return Errno(EOPNOTSUPP);
|
if (n != len) return Errno(EOPNOTSUPP);
|
||||||
|
|
||||||
|
@ -731,7 +733,7 @@ extern "C" int socket_fs_listen(int libc_fd, int backlog)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t do_recvfrom(Libc::File_descriptor *fd,
|
static ssize_t do_recvfrom(File_descriptor *fd,
|
||||||
void *buf, ::size_t len, int flags,
|
void *buf, ::size_t len, int flags,
|
||||||
struct sockaddr *src_addr, socklen_t *src_addrlen)
|
struct sockaddr *src_addr, socklen_t *src_addrlen)
|
||||||
{
|
{
|
||||||
|
@ -762,7 +764,7 @@ static ssize_t do_recvfrom(Libc::File_descriptor *fd,
|
||||||
extern "C" ssize_t socket_fs_recvfrom(int libc_fd, void *buf, ::size_t len, int flags,
|
extern "C" ssize_t socket_fs_recvfrom(int libc_fd, void *buf, ::size_t len, int flags,
|
||||||
sockaddr *src_addr, socklen_t *src_addrlen)
|
sockaddr *src_addr, socklen_t *src_addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
return do_recvfrom(fd, buf, len, flags, src_addr, src_addrlen);
|
return do_recvfrom(fd, buf, len, flags, src_addr, src_addrlen);
|
||||||
|
@ -778,12 +780,12 @@ extern "C" ssize_t socket_fs_recv(int libc_fd, void *buf, ::size_t len, int flag
|
||||||
|
|
||||||
extern "C" ssize_t socket_fs_recvmsg(int libc_fd, msghdr *msg, int flags)
|
extern "C" ssize_t socket_fs_recvmsg(int libc_fd, msghdr *msg, int flags)
|
||||||
{
|
{
|
||||||
Genode::warning("########## TODO ########## ", __func__);
|
warning("########## TODO ########## ", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t do_sendto(Libc::File_descriptor *fd,
|
static ssize_t do_sendto(File_descriptor *fd,
|
||||||
void const *buf, ::size_t len, int flags,
|
void const *buf, ::size_t len, int flags,
|
||||||
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
||||||
{
|
{
|
||||||
|
@ -801,7 +803,7 @@ static ssize_t do_sendto(Libc::File_descriptor *fd,
|
||||||
Sockaddr_string addr_string(host_string(*(sockaddr_in const *)dest_addr),
|
Sockaddr_string addr_string(host_string(*(sockaddr_in const *)dest_addr),
|
||||||
port_string(*(sockaddr_in const *)dest_addr));
|
port_string(*(sockaddr_in const *)dest_addr));
|
||||||
|
|
||||||
int const len = strlen(addr_string.base());
|
int const len = ::strlen(addr_string.base());
|
||||||
int const n = write(context->remote_fd(), addr_string.base(), len);
|
int const n = write(context->remote_fd(), addr_string.base(), len);
|
||||||
if (n != len) return Errno(EIO);
|
if (n != len) return Errno(EIO);
|
||||||
}
|
}
|
||||||
|
@ -826,7 +828,7 @@ static ssize_t do_sendto(Libc::File_descriptor *fd,
|
||||||
extern "C" ssize_t socket_fs_sendto(int libc_fd, void const *buf, ::size_t len, int flags,
|
extern "C" ssize_t socket_fs_sendto(int libc_fd, void const *buf, ::size_t len, int flags,
|
||||||
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
return do_sendto(fd, buf, len, flags, dest_addr, dest_addrlen);
|
return do_sendto(fd, buf, len, flags, dest_addr, dest_addrlen);
|
||||||
|
@ -843,7 +845,7 @@ extern "C" ssize_t socket_fs_send(int libc_fd, void const *buf, ::size_t len, in
|
||||||
extern "C" int socket_fs_getsockopt(int libc_fd, int level, int optname,
|
extern "C" int socket_fs_getsockopt(int libc_fd, int level, int optname,
|
||||||
void *optval, socklen_t *optlen)
|
void *optval, socklen_t *optlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -894,7 +896,7 @@ extern "C" int socket_fs_getsockopt(int libc_fd, int level, int optname,
|
||||||
extern "C" int socket_fs_setsockopt(int libc_fd, int level, int optname,
|
extern "C" int socket_fs_setsockopt(int libc_fd, int level, int optname,
|
||||||
void const *optval, socklen_t optlen)
|
void const *optval, socklen_t optlen)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -930,7 +932,7 @@ extern "C" int socket_fs_setsockopt(int libc_fd, int level, int optname,
|
||||||
|
|
||||||
extern "C" int socket_fs_shutdown(int libc_fd, int how)
|
extern "C" int socket_fs_shutdown(int libc_fd, int how)
|
||||||
{
|
{
|
||||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||||
if (!fd) return Errno(EBADF);
|
if (!fd) return Errno(EBADF);
|
||||||
|
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
|
@ -946,18 +948,18 @@ extern "C" int socket_fs_shutdown(int libc_fd, int how)
|
||||||
|
|
||||||
extern "C" int socket_fs_socket(int domain, int type, int protocol)
|
extern "C" int socket_fs_socket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
Absolute_path path(Libc::config_socket());
|
Socket_fs::Absolute_path path(config_socket());
|
||||||
|
|
||||||
if (path == "") {
|
if (path == "") {
|
||||||
Genode::error(__func__, ": socket fs not mounted");
|
error(__func__, ": socket fs not mounted");
|
||||||
return Errno(EACCES);
|
return Errno(EACCES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((type&7) != SOCK_STREAM || (protocol != 0 && protocol != IPPROTO_TCP))
|
if (((type&7) != SOCK_STREAM || (protocol != 0 && protocol != IPPROTO_TCP))
|
||||||
&& ((type&7) != SOCK_DGRAM || (protocol != 0 && protocol != IPPROTO_UDP))) {
|
&& ((type&7) != SOCK_DGRAM || (protocol != 0 && protocol != IPPROTO_UDP))) {
|
||||||
Genode::error(__func__,
|
error(__func__,
|
||||||
": socket with type=", (Genode::Hex)type,
|
": socket with type=", (Hex)type,
|
||||||
" protocol=", (Genode::Hex)protocol, " not supported");
|
" protocol=", (Hex)protocol, " not supported");
|
||||||
return Errno(EAFNOSUPPORT);
|
return Errno(EAFNOSUPPORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,7 +976,7 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol)
|
||||||
path.append("/new_socket");
|
path.append("/new_socket");
|
||||||
int handle_fd = ::open(path.base(), O_RDONLY);
|
int handle_fd = ::open(path.base(), O_RDONLY);
|
||||||
if (handle_fd < 0) {
|
if (handle_fd < 0) {
|
||||||
Genode::error("failed to open new socket at ", path);
|
error("failed to open new socket at ", path);
|
||||||
return Errno(EACCES);
|
return Errno(EACCES);
|
||||||
}
|
}
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
|
@ -982,14 +984,13 @@ extern "C" int socket_fs_socket(int domain, int type, int protocol)
|
||||||
Socket_fs::Context(proto, handle_fd);
|
Socket_fs::Context(proto, handle_fd);
|
||||||
} catch (New_socket_failed) { return Errno(EACCES); }
|
} catch (New_socket_failed) { return Errno(EACCES); }
|
||||||
|
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd = file_descriptor_allocator()->alloc(&plugin(), context);
|
||||||
Libc::file_descriptor_allocator()->alloc(&plugin(), context);
|
|
||||||
|
|
||||||
return fd->libc_fd;
|
return fd->libc_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int read_ifaddr_file(sockaddr_in &sockaddr, Absolute_path const &path)
|
static int read_ifaddr_file(sockaddr_in &sockaddr, Socket_fs::Absolute_path const &path)
|
||||||
{
|
{
|
||||||
Host_string address;
|
Host_string address;
|
||||||
Port_string service;
|
Port_string service;
|
||||||
|
@ -1012,8 +1013,8 @@ static int read_ifaddr_file(sockaddr_in &sockaddr, Absolute_path const &path)
|
||||||
|
|
||||||
extern "C" int getifaddrs(struct ifaddrs **ifap)
|
extern "C" int getifaddrs(struct ifaddrs **ifap)
|
||||||
{
|
{
|
||||||
static Genode::Lock lock;
|
static Lock lock;
|
||||||
Genode::Lock::Guard guard(lock);
|
Lock::Guard guard(lock);
|
||||||
|
|
||||||
// TODO: dual-stack / multi-homing
|
// TODO: dual-stack / multi-homing
|
||||||
|
|
||||||
|
@ -1032,7 +1033,9 @@ extern "C" int getifaddrs(struct ifaddrs **ifap)
|
||||||
|
|
||||||
*ifap = &ifaddr;
|
*ifap = &ifaddr;
|
||||||
|
|
||||||
Absolute_path const root(Libc::config_socket());
|
using Socket_fs::Absolute_path;
|
||||||
|
|
||||||
|
Absolute_path const root(config_socket());
|
||||||
|
|
||||||
if (read_ifaddr_file(address, Absolute_path("address", root.base())))
|
if (read_ifaddr_file(address, Absolute_path("address", root.base())))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1049,7 +1052,7 @@ extern "C" void freeifaddrs(struct ifaddrs *) { }
|
||||||
** File-plugin operations **
|
** File-plugin operations **
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
int Socket_fs::Plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
int Socket_fs::Plugin::fcntl(File_descriptor *fd, int cmd, long arg)
|
||||||
{
|
{
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
if (!context) return Errno(EBADF);
|
if (!context) return Errno(EBADF);
|
||||||
|
@ -1061,12 +1064,12 @@ int Socket_fs::Plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||||
context->fd_flags(arg);
|
context->fd_flags(arg);
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
Genode::error(__func__, " command ", cmd, " not supported on sockets");
|
error(__func__, " command ", cmd, " not supported on sockets");
|
||||||
return Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Socket_fs::Plugin::read(Libc::File_descriptor *fd, void *buf, ::size_t count)
|
ssize_t Socket_fs::Plugin::read(File_descriptor *fd, void *buf, ::size_t count)
|
||||||
{
|
{
|
||||||
ssize_t const ret = do_recvfrom(fd, buf, count, 0, nullptr, nullptr);
|
ssize_t const ret = do_recvfrom(fd, buf, count, 0, nullptr, nullptr);
|
||||||
if (ret != -1) return ret;
|
if (ret != -1) return ret;
|
||||||
|
@ -1078,7 +1081,7 @@ ssize_t Socket_fs::Plugin::read(Libc::File_descriptor *fd, void *buf, ::size_t c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t Socket_fs::Plugin::write(Libc::File_descriptor *fd, const void *buf, ::size_t count)
|
ssize_t Socket_fs::Plugin::write(File_descriptor *fd, const void *buf, ::size_t count)
|
||||||
{
|
{
|
||||||
|
|
||||||
ssize_t const ret = do_sendto(fd, buf, count, 0, nullptr, 0);
|
ssize_t const ret = do_sendto(fd, buf, count, 0, nullptr, 0);
|
||||||
|
@ -1091,8 +1094,7 @@ ssize_t Socket_fs::Plugin::write(Libc::File_descriptor *fd, const void *buf, ::s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Socket_fs::Plugin::poll(Libc::File_descriptor &fdo,
|
bool Socket_fs::Plugin::poll(File_descriptor &fdo, struct pollfd &pfd)
|
||||||
struct pollfd &pfd)
|
|
||||||
{
|
{
|
||||||
if (fdo.plugin != this) return false;
|
if (fdo.plugin != this) return false;
|
||||||
Socket_fs::Context *context { nullptr };
|
Socket_fs::Context *context { nullptr };
|
||||||
|
@ -1135,8 +1137,7 @@ bool Socket_fs::Plugin::supports_select(int nfds,
|
||||||
for (int fd = 0; fd < nfds; ++fd) {
|
for (int fd = 0; fd < nfds; ++fd) {
|
||||||
|
|
||||||
if (FD_ISSET(fd, readfds) || FD_ISSET(fd, writefds) || FD_ISSET(fd, exceptfds)) {
|
if (FD_ISSET(fd, readfds) || FD_ISSET(fd, writefds) || FD_ISSET(fd, exceptfds)) {
|
||||||
Libc::File_descriptor *fdo =
|
File_descriptor *fdo = file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
|
||||||
|
|
||||||
if (fdo && (fdo->plugin == this))
|
if (fdo && (fdo->plugin == this))
|
||||||
return true;
|
return true;
|
||||||
|
@ -1164,8 +1165,7 @@ int Socket_fs::Plugin::select(int nfds,
|
||||||
|
|
||||||
for (int fd = 0; fd < nfds; ++fd) {
|
for (int fd = 0; fd < nfds; ++fd) {
|
||||||
|
|
||||||
Libc::File_descriptor *fdo =
|
File_descriptor *fdo = file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
|
||||||
|
|
||||||
/* handle only fds that belong to this plugin */
|
/* handle only fds that belong to this plugin */
|
||||||
if (!fdo || (fdo->plugin != this))
|
if (!fdo || (fdo->plugin != this))
|
||||||
|
@ -1200,14 +1200,14 @@ int Socket_fs::Plugin::select(int nfds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Socket_fs::Plugin::close(Libc::File_descriptor *fd)
|
int Socket_fs::Plugin::close(File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
Socket_fs::Context *context = dynamic_cast<Socket_fs::Context *>(fd->context);
|
||||||
if (!context) return Errno(EBADF);
|
if (!context) return Errno(EBADF);
|
||||||
|
|
||||||
Libc::Allocator alloc { };
|
Libc::Allocator alloc { };
|
||||||
Genode::destroy(alloc, context);
|
destroy(alloc, context);
|
||||||
Libc::file_descriptor_allocator()->free(fd);
|
file_descriptor_allocator()->free(fd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the socket is freed when the initial handle
|
* the socket is freed when the initial handle
|
||||||
|
@ -1218,7 +1218,7 @@ int Socket_fs::Plugin::close(Libc::File_descriptor *fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Socket_fs::Plugin::ioctl(Libc::File_descriptor *, int request, char*)
|
int Socket_fs::Plugin::ioctl(File_descriptor *, int request, char*)
|
||||||
{
|
{
|
||||||
if (request == FIONREAD) {
|
if (request == FIONREAD) {
|
||||||
/*
|
/*
|
||||||
|
@ -1227,20 +1227,20 @@ int Socket_fs::Plugin::ioctl(Libc::File_descriptor *, int request, char*)
|
||||||
*/
|
*/
|
||||||
static bool print_fionread_error_message = true;
|
static bool print_fionread_error_message = true;
|
||||||
if (print_fionread_error_message) {
|
if (print_fionread_error_message) {
|
||||||
Genode::error(__func__, " request FIONREAD not supported on sockets"
|
error(__func__, " request FIONREAD not supported on sockets"
|
||||||
" (this message will not be shown again)");
|
" (this message will not be shown again)");
|
||||||
print_fionread_error_message = false;
|
print_fionread_error_message = false;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::error(__func__, " request ", request, " not supported on sockets");
|
error(__func__, " request ", request, " not supported on sockets");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Plugin & Socket_fs::plugin()
|
Libc::Socket_fs::Plugin &Libc::Socket_fs::plugin()
|
||||||
{
|
{
|
||||||
static Plugin inst;
|
static Socket_fs::Plugin inst;
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace Libc { extern char const *config_socket(); }
|
||||||
|
|
||||||
extern "C" int getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
extern "C" int getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_getpeername(libc_fd, addr, addrlen);
|
return socket_fs_getpeername(libc_fd, addr, addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen);
|
FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen);
|
||||||
|
@ -62,7 +62,7 @@ int _getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen);
|
||||||
|
|
||||||
extern "C" int getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
extern "C" int getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_getsockname(libc_fd, addr, addrlen);
|
return socket_fs_getsockname(libc_fd, addr, addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen);
|
FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen);
|
||||||
|
@ -79,7 +79,7 @@ int _getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen);
|
||||||
|
|
||||||
__SYS_(int, accept, (int libc_fd, sockaddr *addr, socklen_t *addrlen),
|
__SYS_(int, accept, (int libc_fd, sockaddr *addr, socklen_t *addrlen),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_accept(libc_fd, addr, addrlen);
|
return socket_fs_accept(libc_fd, addr, addrlen);
|
||||||
|
|
||||||
File_descriptor *ret_fd;
|
File_descriptor *ret_fd;
|
||||||
|
@ -96,7 +96,7 @@ __SYS_(int, accept4, (int libc_fd, struct sockaddr *addr, socklen_t *addrlen, in
|
||||||
|
|
||||||
extern "C" int bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
extern "C" int bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_bind(libc_fd, addr, addrlen);
|
return socket_fs_bind(libc_fd, addr, addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen);
|
FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen);
|
||||||
|
@ -109,7 +109,7 @@ int _bind(int libc_fd, sockaddr const *addr, socklen_t addrlen);
|
||||||
|
|
||||||
__SYS_(int, connect, (int libc_fd, sockaddr const *addr, socklen_t addrlen),
|
__SYS_(int, connect, (int libc_fd, sockaddr const *addr, socklen_t addrlen),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_connect(libc_fd, addr, addrlen);
|
return socket_fs_connect(libc_fd, addr, addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen);
|
FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen);
|
||||||
|
@ -118,7 +118,7 @@ __SYS_(int, connect, (int libc_fd, sockaddr const *addr, socklen_t addrlen),
|
||||||
|
|
||||||
extern "C" int listen(int libc_fd, int backlog)
|
extern "C" int listen(int libc_fd, int backlog)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_listen(libc_fd, backlog);
|
return socket_fs_listen(libc_fd, backlog);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(listen, libc_fd, backlog);
|
FD_FUNC_WRAPPER(listen, libc_fd, backlog);
|
||||||
|
@ -128,7 +128,7 @@ extern "C" int listen(int libc_fd, int backlog)
|
||||||
__SYS_(ssize_t, recvfrom, (int libc_fd, void *buf, ::size_t len, int flags,
|
__SYS_(ssize_t, recvfrom, (int libc_fd, void *buf, ::size_t len, int flags,
|
||||||
sockaddr *src_addr, socklen_t *src_addrlen),
|
sockaddr *src_addr, socklen_t *src_addrlen),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_recvfrom(libc_fd, buf, len, flags, src_addr, src_addrlen);
|
return socket_fs_recvfrom(libc_fd, buf, len, flags, src_addr, src_addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, src_addrlen);
|
FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, src_addrlen);
|
||||||
|
@ -137,7 +137,7 @@ __SYS_(ssize_t, recvfrom, (int libc_fd, void *buf, ::size_t len, int flags,
|
||||||
|
|
||||||
__SYS_(ssize_t, recv, (int libc_fd, void *buf, ::size_t len, int flags),
|
__SYS_(ssize_t, recv, (int libc_fd, void *buf, ::size_t len, int flags),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_recv(libc_fd, buf, len, flags);
|
return socket_fs_recv(libc_fd, buf, len, flags);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags);
|
FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags);
|
||||||
|
@ -146,7 +146,7 @@ __SYS_(ssize_t, recv, (int libc_fd, void *buf, ::size_t len, int flags),
|
||||||
|
|
||||||
__SYS_(ssize_t, recvmsg, (int libc_fd, msghdr *msg, int flags),
|
__SYS_(ssize_t, recvmsg, (int libc_fd, msghdr *msg, int flags),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_recvmsg(libc_fd, msg, flags);
|
return socket_fs_recvmsg(libc_fd, msg, flags);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags);
|
FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags);
|
||||||
|
@ -156,7 +156,7 @@ __SYS_(ssize_t, recvmsg, (int libc_fd, msghdr *msg, int flags),
|
||||||
__SYS_(ssize_t, sendto, (int libc_fd, void const *buf, ::size_t len, int flags,
|
__SYS_(ssize_t, sendto, (int libc_fd, void const *buf, ::size_t len, int flags,
|
||||||
sockaddr const *dest_addr, socklen_t dest_addrlen),
|
sockaddr const *dest_addr, socklen_t dest_addrlen),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_sendto(libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
return socket_fs_sendto(libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
||||||
|
@ -165,7 +165,7 @@ __SYS_(ssize_t, sendto, (int libc_fd, void const *buf, ::size_t len, int flags,
|
||||||
|
|
||||||
extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
|
extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_send(libc_fd, buf, len, flags);
|
return socket_fs_send(libc_fd, buf, len, flags);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags);
|
FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags);
|
||||||
|
@ -175,7 +175,7 @@ extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
|
||||||
extern "C" int getsockopt(int libc_fd, int level, int optname,
|
extern "C" int getsockopt(int libc_fd, int level, int optname,
|
||||||
void *optval, socklen_t *optlen)
|
void *optval, socklen_t *optlen)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_getsockopt(libc_fd, level, optname, optval, optlen);
|
return socket_fs_getsockopt(libc_fd, level, optname, optval, optlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen);
|
FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen);
|
||||||
|
@ -190,7 +190,7 @@ int _getsockopt(int libc_fd, int level, int optname,
|
||||||
extern "C" int setsockopt(int libc_fd, int level, int optname,
|
extern "C" int setsockopt(int libc_fd, int level, int optname,
|
||||||
void const *optval, socklen_t optlen)
|
void const *optval, socklen_t optlen)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_setsockopt(libc_fd, level, optname, optval, optlen);
|
return socket_fs_setsockopt(libc_fd, level, optname, optval, optlen);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen);
|
FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen);
|
||||||
|
@ -204,7 +204,7 @@ int _setsockopt(int libc_fd, int level, int optname,
|
||||||
|
|
||||||
extern "C" int shutdown(int libc_fd, int how)
|
extern "C" int shutdown(int libc_fd, int how)
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_shutdown(libc_fd, how);
|
return socket_fs_shutdown(libc_fd, how);
|
||||||
|
|
||||||
FD_FUNC_WRAPPER(shutdown, libc_fd, how);
|
FD_FUNC_WRAPPER(shutdown, libc_fd, how);
|
||||||
|
@ -212,7 +212,7 @@ extern "C" int shutdown(int libc_fd, int how)
|
||||||
|
|
||||||
__SYS_(int, socket, (int domain, int type, int protocol),
|
__SYS_(int, socket, (int domain, int type, int protocol),
|
||||||
{
|
{
|
||||||
if (*Libc::config_socket())
|
if (*config_socket())
|
||||||
return socket_fs_socket(domain, type, protocol);
|
return socket_fs_socket(domain, type, protocol);
|
||||||
|
|
||||||
Plugin *plugin;
|
Plugin *plugin;
|
||||||
|
@ -221,13 +221,13 @@ __SYS_(int, socket, (int domain, int type, int protocol),
|
||||||
plugin = plugin_registry()->get_plugin_for_socket(domain, type, protocol);
|
plugin = plugin_registry()->get_plugin_for_socket(domain, type, protocol);
|
||||||
|
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
Genode::error("no plugin found for socket()");
|
error("no plugin found for socket()");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_fdo = plugin->socket(domain, type, protocol);
|
new_fdo = plugin->socket(domain, type, protocol);
|
||||||
if (!new_fdo) {
|
if (!new_fdo) {
|
||||||
Genode::error("plugin()->socket() failed");
|
error("plugin()->socket() failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <internal/errno.h>
|
#include <internal/errno.h>
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
enum { PAGESIZE = 4096 };
|
enum { PAGESIZE = 4096 };
|
||||||
|
|
||||||
|
@ -55,8 +56,8 @@ extern "C" long sysconf(int name)
|
||||||
case _SC_PHYS_PAGES:
|
case _SC_PHYS_PAGES:
|
||||||
return _global_env->pd().ram_quota().value / PAGESIZE;
|
return _global_env->pd().ram_quota().value / PAGESIZE;
|
||||||
default:
|
default:
|
||||||
Genode::warning(__func__, "(", name, ") not implemented");
|
warning(__func__, "(", name, ") not implemented");
|
||||||
return Libc::Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +68,9 @@ extern "C" int __sysctl(const int *name, u_int namelen,
|
||||||
{
|
{
|
||||||
/* read only */
|
/* read only */
|
||||||
if (!oldp) /* check for write attempt */
|
if (!oldp) /* check for write attempt */
|
||||||
return Libc::Errno(newp ? EPERM : EINVAL);
|
return Errno(newp ? EPERM : EINVAL);
|
||||||
|
|
||||||
if (namelen != 2) return Libc::Errno(ENOENT);
|
if (namelen != 2) return Errno(ENOENT);
|
||||||
|
|
||||||
char *buf = (char*)oldp;
|
char *buf = (char*)oldp;
|
||||||
int index_a = name[0];
|
int index_a = name[0];
|
||||||
|
@ -93,7 +94,7 @@ extern "C" int __sysctl(const int *name, u_int namelen,
|
||||||
*(Genode::int64_t*)oldp = _global_env->pd().ram_quota().value;
|
*(Genode::int64_t*)oldp = _global_env->pd().ram_quota().value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return Libc::Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -163,6 +164,6 @@ extern "C" int __sysctl(const int *name, u_int namelen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::warning("missing sysctl for [", index_a, "][", index_b, "]");
|
warning("missing sysctl for [", index_a, "][", index_b, "]");
|
||||||
return Libc::Errno(ENOENT);
|
return Errno(ENOENT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,11 +61,11 @@ struct Libc::Rtc : Vfs::Watch_response_handler
|
||||||
_rtc_path(rtc_path)
|
_rtc_path(rtc_path)
|
||||||
{
|
{
|
||||||
if (!_rtc_path_valid) {
|
if (!_rtc_path_valid) {
|
||||||
Genode::warning("rtc not configured, returning ", _rtc_value);
|
warning("rtc not configured, returning ", _rtc_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_watch_handle = Libc::watch(_rtc_path.string());
|
_watch_handle = watch(_rtc_path.string());
|
||||||
if (_watch_handle) {
|
if (_watch_handle) {
|
||||||
_watch_handle->handler(this);
|
_watch_handle->handler(this);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ struct Libc::Rtc : Vfs::Watch_response_handler
|
||||||
|
|
||||||
int fd = open(_rtc_path.string(), O_RDONLY);
|
int fd = open(_rtc_path.string(), O_RDONLY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
Genode::warning(_rtc_path, " not readable, returning ", _rtc_value);
|
warning(_rtc_path, " not readable, returning ", _rtc_value);
|
||||||
return _rtc_value;
|
return _rtc_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ struct Libc::Rtc : Vfs::Watch_response_handler
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
buf[n - 1] = '\0';
|
buf[n - 1] = '\0';
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
Genode::memset(&tm, 0, sizeof(tm));
|
memset(&tm, 0, sizeof(tm));
|
||||||
|
|
||||||
if (strptime(buf, "%Y-%m-%d %R", &tm)) {
|
if (strptime(buf, "%Y-%m-%d %R", &tm)) {
|
||||||
_rtc_value = mktime(&tm);
|
_rtc_value = mktime(&tm);
|
||||||
|
@ -115,7 +115,7 @@ struct Libc::Rtc : Vfs::Watch_response_handler
|
||||||
if (!_current_time_ptr)
|
if (!_current_time_ptr)
|
||||||
throw Missing_call_of_init_time();
|
throw Missing_call_of_init_time();
|
||||||
|
|
||||||
Genode::uint64_t const ts_value =
|
uint64_t const ts_value =
|
||||||
_current_time_ptr->current_time().trunc_to_plain_ms().value;
|
_current_time_ptr->current_time().trunc_to_plain_ms().value;
|
||||||
_rtc_value += (time_t)ts_value / 1000;
|
_rtc_value += (time_t)ts_value / 1000;
|
||||||
|
|
||||||
|
@ -124,14 +124,19 @@ struct Libc::Rtc : Vfs::Watch_response_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
extern "C" __attribute__((weak))
|
extern "C" __attribute__((weak))
|
||||||
int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||||
{
|
{
|
||||||
if (!ts) return Libc::Errno(EFAULT);
|
typedef Libc::uint64_t uint64_t;
|
||||||
|
|
||||||
|
if (!ts) return Errno(EFAULT);
|
||||||
|
|
||||||
auto current_time = [&] ()
|
auto current_time = [&] ()
|
||||||
{
|
{
|
||||||
struct Missing_call_of_init_time : Genode::Exception { };
|
struct Missing_call_of_init_time : Exception { };
|
||||||
if (!_current_time_ptr)
|
if (!_current_time_ptr)
|
||||||
throw Missing_call_of_init_time();
|
throw Missing_call_of_init_time();
|
||||||
|
|
||||||
|
@ -151,12 +156,12 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||||
/*
|
/*
|
||||||
* XXX move instance to Libc::Kernel
|
* XXX move instance to Libc::Kernel
|
||||||
*/
|
*/
|
||||||
static Libc::Rtc rtc(_rtc_path);
|
static Rtc rtc(_rtc_path);
|
||||||
|
|
||||||
time_t const rtc_value = rtc.read();
|
time_t const rtc_value = rtc.read();
|
||||||
if (!rtc_value) return Libc::Errno(EINVAL);
|
if (!rtc_value) return Errno(EINVAL);
|
||||||
|
|
||||||
Genode::uint64_t const time = current_time().trunc_to_plain_ms().value;
|
uint64_t const time = current_time().trunc_to_plain_ms().value;
|
||||||
|
|
||||||
ts->tv_sec = rtc_value + time/1000;
|
ts->tv_sec = rtc_value + time/1000;
|
||||||
ts->tv_nsec = (time % 1000) * (1000*1000);
|
ts->tv_nsec = (time % 1000) * (1000*1000);
|
||||||
|
@ -167,7 +172,7 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||||
case CLOCK_MONOTONIC:
|
case CLOCK_MONOTONIC:
|
||||||
case CLOCK_UPTIME:
|
case CLOCK_UPTIME:
|
||||||
{
|
{
|
||||||
Genode::uint64_t us = current_time().trunc_to_plain_us().value;
|
uint64_t us = current_time().trunc_to_plain_us().value;
|
||||||
|
|
||||||
ts->tv_sec = us / (1000*1000);
|
ts->tv_sec = us / (1000*1000);
|
||||||
ts->tv_nsec = (us % (1000*1000)) * 1000;
|
ts->tv_nsec = (us % (1000*1000)) * 1000;
|
||||||
|
@ -175,7 +180,7 @@ int clock_gettime(clockid_t clk_id, struct timespec *ts)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Libc::Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -209,6 +214,6 @@ int __sys_gettimeofday(struct timeval *tv, struct timezone *);
|
||||||
extern "C"
|
extern "C"
|
||||||
clock_t clock()
|
clock_t clock()
|
||||||
{
|
{
|
||||||
Genode::error(__func__, " not implemented, use 'clock_gettime' instead");
|
error(__func__, " not implemented, use 'clock_gettime' instead");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,8 +118,8 @@ char const *libc_resolv_path;
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
|
|
||||||
Genode::Xml_node config() __attribute__((weak));
|
Xml_node config() __attribute__((weak));
|
||||||
Genode::Xml_node config()
|
Xml_node config()
|
||||||
{
|
{
|
||||||
if (!_config_node) {
|
if (!_config_node) {
|
||||||
error("libc config not initialized - aborting");
|
error("libc config not initialized - aborting");
|
||||||
|
@ -139,8 +139,8 @@ namespace Libc {
|
||||||
|
|
||||||
Config_attr(char const *attr_name, char const *default_value)
|
Config_attr(char const *attr_name, char const *default_value)
|
||||||
:
|
:
|
||||||
_value(Libc::config().attribute_value(attr_name,
|
_value(config().attribute_value(attr_name,
|
||||||
Value(default_value)))
|
Value(default_value)))
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
char const *string() const { return _value.string(); }
|
char const *string() const { return _value.string(); }
|
||||||
|
@ -168,9 +168,9 @@ namespace Libc {
|
||||||
return ns_file.string();
|
return ns_file.string();
|
||||||
}
|
}
|
||||||
|
|
||||||
void libc_config_init(Genode::Xml_node node)
|
void libc_config_init(Xml_node node)
|
||||||
{
|
{
|
||||||
static Genode::Xml_node config = node;
|
static Xml_node config = node;
|
||||||
_config_node = &config;
|
_config_node = &config;
|
||||||
|
|
||||||
libc_resolv_path = config_nameserver_file();
|
libc_resolv_path = config_nameserver_file();
|
||||||
|
@ -187,7 +187,7 @@ namespace Libc {
|
||||||
VFS_THREAD_SAFE(handle->fs().notify_read_ready(handle));
|
VFS_THREAD_SAFE(handle->fs().notify_read_ready(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_ready(Libc::File_descriptor *fd)
|
bool read_ready(File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
if (!handle) return false;
|
if (!handle) return false;
|
||||||
|
@ -238,8 +238,8 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags,
|
||||||
|
|
||||||
/* the directory was successfully opened */
|
/* the directory was successfully opened */
|
||||||
|
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd =
|
||||||
Libc::file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd);
|
file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd);
|
||||||
|
|
||||||
/* FIXME error cleanup code leaks resources! */
|
/* FIXME error cleanup code leaks resources! */
|
||||||
|
|
||||||
|
@ -319,8 +319,8 @@ Libc::File_descriptor *Libc::Vfs_plugin::open(char const *path, int flags,
|
||||||
|
|
||||||
/* the file was successfully opened */
|
/* the file was successfully opened */
|
||||||
|
|
||||||
Libc::File_descriptor *fd =
|
File_descriptor *fd =
|
||||||
Libc::file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd);
|
file_descriptor_allocator()->alloc(this, vfs_context(handle), libc_fd);
|
||||||
|
|
||||||
/* FIXME error cleanup code leaks resources! */
|
/* FIXME error cleanup code leaks resources! */
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ int Libc::Vfs_plugin::_vfs_sync(Vfs::Vfs_handle &vfs_handle)
|
||||||
Result result = Result::SYNC_QUEUED;
|
Result result = Result::SYNC_QUEUED;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -377,7 +377,7 @@ int Libc::Vfs_plugin::_vfs_sync(Vfs::Vfs_handle &vfs_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -407,30 +407,30 @@ int Libc::Vfs_plugin::_vfs_sync(Vfs::Vfs_handle &vfs_handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result == Result::SYNC_OK ? 0 : Libc::Errno(EIO);
|
return result == Result::SYNC_OK ? 0 : Errno(EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::close(Libc::File_descriptor *fd)
|
int Libc::Vfs_plugin::close(File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
/* XXX: mark the handle as requiring sync or not */
|
/* XXX: mark the handle as requiring sync or not */
|
||||||
_vfs_sync(*handle);
|
_vfs_sync(*handle);
|
||||||
VFS_THREAD_SAFE(handle->close());
|
VFS_THREAD_SAFE(handle->close());
|
||||||
Libc::file_descriptor_allocator()->free(fd);
|
file_descriptor_allocator()->free(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::dup2(Libc::File_descriptor *fd,
|
int Libc::Vfs_plugin::dup2(File_descriptor *fd,
|
||||||
Libc::File_descriptor *new_fd)
|
File_descriptor *new_fd)
|
||||||
{
|
{
|
||||||
new_fd->context = fd->context;
|
new_fd->context = fd->context;
|
||||||
return new_fd->libc_fd;
|
return new_fd->libc_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::fstat(Libc::File_descriptor *fd, struct stat *buf)
|
int Libc::Vfs_plugin::fstat(File_descriptor *fd, struct stat *buf)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
_vfs_sync(*handle);
|
_vfs_sync(*handle);
|
||||||
|
@ -438,10 +438,10 @@ int Libc::Vfs_plugin::fstat(Libc::File_descriptor *fd, struct stat *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::fstatfs(Libc::File_descriptor *fd, struct statfs *buf)
|
int Libc::Vfs_plugin::fstatfs(File_descriptor *fd, struct statfs *buf)
|
||||||
{
|
{
|
||||||
if (!fd || !buf)
|
if (!fd || !buf)
|
||||||
return Libc::Errno(EFAULT);
|
return Errno(EFAULT);
|
||||||
|
|
||||||
Genode::memset(buf, 0, sizeof(*buf));
|
Genode::memset(buf, 0, sizeof(*buf));
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ int Libc::Vfs_plugin::stat(char const *path, struct stat *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
ssize_t Libc::Vfs_plugin::write(File_descriptor *fd, const void *buf,
|
||||||
::size_t count)
|
::size_t count)
|
||||||
{
|
{
|
||||||
typedef Vfs::File_io_service::Write_result Result;
|
typedef Vfs::File_io_service::Write_result Result;
|
||||||
|
@ -521,7 +521,7 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -574,10 +574,10 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
ssize_t Libc::Vfs_plugin::read(File_descriptor *fd, void *buf,
|
||||||
::size_t count)
|
::size_t count)
|
||||||
{
|
{
|
||||||
Libc::dispatch_pending_io_signals();
|
dispatch_pending_io_signals();
|
||||||
|
|
||||||
typedef Vfs::File_io_service::Read_result Result;
|
typedef Vfs::File_io_service::Read_result Result;
|
||||||
|
|
||||||
|
@ -586,11 +586,11 @@ ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
||||||
if (fd->flags & O_DIRECTORY)
|
if (fd->flags & O_DIRECTORY)
|
||||||
return Errno(EISDIR);
|
return Errno(EISDIR);
|
||||||
|
|
||||||
if (fd->flags & O_NONBLOCK && !Libc::read_ready(fd))
|
if (fd->flags & O_NONBLOCK && !read_ready(fd))
|
||||||
return Errno(EAGAIN);
|
return Errno(EAGAIN);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -616,7 +616,7 @@ ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
||||||
Result out_result;
|
Result out_result;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -668,11 +668,11 @@ ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ssize_t Libc::Vfs_plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
|
ssize_t Libc::Vfs_plugin::getdirentries(File_descriptor *fd, char *buf,
|
||||||
::size_t nbytes, ::off_t *basep)
|
::size_t nbytes, ::off_t *basep)
|
||||||
{
|
{
|
||||||
if (nbytes < sizeof(struct dirent)) {
|
if (nbytes < sizeof(struct dirent)) {
|
||||||
Genode::error("getdirentries: buffer too small");
|
error("getdirentries: buffer too small");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,7 +685,7 @@ ssize_t Libc::Vfs_plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||||
Dirent dirent_out;
|
Dirent dirent_out;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ ssize_t Libc::Vfs_plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||||
Vfs::file_size out_count;
|
Vfs::file_size out_count;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -786,7 +786,7 @@ ssize_t Libc::Vfs_plugin::getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::ioctl(Libc::File_descriptor *fd, int request, char *argp)
|
int Libc::Vfs_plugin::ioctl(File_descriptor *fd, int request, char *argp)
|
||||||
{
|
{
|
||||||
using ::off_t;
|
using ::off_t;
|
||||||
|
|
||||||
|
@ -881,7 +881,7 @@ int Libc::Vfs_plugin::ioctl(Libc::File_descriptor *fd, int request, char *argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Genode::warning("unsupported ioctl (request=", Genode::Hex(request), ")");
|
warning("unsupported ioctl (request=", Hex(request), ")");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,7 +940,7 @@ int Libc::Vfs_plugin::ioctl(Libc::File_descriptor *fd, int request, char *argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
::off_t Libc::Vfs_plugin::lseek(Libc::File_descriptor *fd, ::off_t offset, int whence)
|
::off_t Libc::Vfs_plugin::lseek(File_descriptor *fd, ::off_t offset, int whence)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
|
|
||||||
|
@ -960,7 +960,7 @@ int Libc::Vfs_plugin::ioctl(Libc::File_descriptor *fd, int request, char *argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
int Libc::Vfs_plugin::ftruncate(File_descriptor *fd, ::off_t length)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
_vfs_sync(*handle);
|
_vfs_sync(*handle);
|
||||||
|
@ -977,7 +977,7 @@ int Libc::Vfs_plugin::ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
int Libc::Vfs_plugin::fcntl(File_descriptor *fd, int cmd, long arg)
|
||||||
{
|
{
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case F_DUPFD_CLOEXEC:
|
case F_DUPFD_CLOEXEC:
|
||||||
|
@ -986,8 +986,8 @@ int Libc::Vfs_plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||||
/*
|
/*
|
||||||
* Allocate free file descriptor locally.
|
* Allocate free file descriptor locally.
|
||||||
*/
|
*/
|
||||||
Libc::File_descriptor *new_fd =
|
File_descriptor *new_fd =
|
||||||
Libc::file_descriptor_allocator()->alloc(this, 0);
|
file_descriptor_allocator()->alloc(this, 0);
|
||||||
if (!new_fd) return Errno(EMFILE);
|
if (!new_fd) return Errno(EMFILE);
|
||||||
|
|
||||||
new_fd->path(fd->fd_path);
|
new_fd->path(fd->fd_path);
|
||||||
|
@ -997,7 +997,7 @@ int Libc::Vfs_plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||||
* duplicate.
|
* duplicate.
|
||||||
*/
|
*/
|
||||||
if (dup2(fd, new_fd) == -1) {
|
if (dup2(fd, new_fd) == -1) {
|
||||||
Genode::error("Plugin::fcntl: dup2 unexpectedly failed");
|
error("Plugin::fcntl: dup2 unexpectedly failed");
|
||||||
return Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,12 +1013,12 @@ int Libc::Vfs_plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::error("fcntl(): command ", cmd, " not supported - vfs");
|
error("fcntl(): command ", cmd, " not supported - vfs");
|
||||||
return Errno(EINVAL);
|
return Errno(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Libc::Vfs_plugin::fsync(Libc::File_descriptor *fd)
|
int Libc::Vfs_plugin::fsync(File_descriptor *fd)
|
||||||
{
|
{
|
||||||
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
Vfs::Vfs_handle *handle = vfs_handle(fd);
|
||||||
return _vfs_sync(*handle);
|
return _vfs_sync(*handle);
|
||||||
|
@ -1058,7 +1058,7 @@ int Libc::Vfs_plugin::symlink(const char *oldpath, const char *newpath)
|
||||||
|
|
||||||
handle->handler(&_response_handler);
|
handle->handler(&_response_handler);
|
||||||
|
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -1128,7 +1128,7 @@ ssize_t Libc::Vfs_plugin::readlink(const char *path, char *buf, ::size_t buf_siz
|
||||||
symlink_handle->handler(&_response_handler);
|
symlink_handle->handler(&_response_handler);
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -1158,7 +1158,7 @@ ssize_t Libc::Vfs_plugin::readlink(const char *path, char *buf, ::size_t buf_siz
|
||||||
Vfs::file_size out_len = 0;
|
Vfs::file_size out_len = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
struct Check : Libc::Suspend_functor
|
struct Check : Suspend_functor
|
||||||
{
|
{
|
||||||
bool retry { false };
|
bool retry { false };
|
||||||
|
|
||||||
|
@ -1265,16 +1265,16 @@ int Libc::Vfs_plugin::rename(char const *from_path, char const *to_path)
|
||||||
|
|
||||||
|
|
||||||
void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags,
|
void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags,
|
||||||
Libc::File_descriptor *fd, ::off_t offset)
|
File_descriptor *fd, ::off_t offset)
|
||||||
{
|
{
|
||||||
if (prot != PROT_READ && !(prot == (PROT_READ | PROT_WRITE) && flags == MAP_PRIVATE)) {
|
if (prot != PROT_READ && !(prot == (PROT_READ | PROT_WRITE) && flags == MAP_PRIVATE)) {
|
||||||
Genode::error("mmap for prot=", Genode::Hex(prot), " not supported");
|
error("mmap for prot=", Hex(prot), " not supported");
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr_in != 0) {
|
if (addr_in != 0) {
|
||||||
Genode::error("mmap for predefined address not supported");
|
error("mmap for predefined address not supported");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
}
|
}
|
||||||
|
@ -1284,7 +1284,7 @@ void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags
|
||||||
* 'Vfs::Directory_service::dataspace'.
|
* 'Vfs::Directory_service::dataspace'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *addr = Libc::mem_alloc()->alloc(length, PAGE_SHIFT);
|
void *addr = mem_alloc()->alloc(length, PAGE_SHIFT);
|
||||||
if (addr == (void *)-1) {
|
if (addr == (void *)-1) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
|
@ -1298,7 +1298,7 @@ void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags
|
||||||
while (read_remain > 0) {
|
while (read_remain > 0) {
|
||||||
ssize_t length_read = ::pread(fd->libc_fd, read_addr, read_remain, read_offset);
|
ssize_t length_read = ::pread(fd->libc_fd, read_addr, read_remain, read_offset);
|
||||||
if (length_read < 0) { /* error */
|
if (length_read < 0) { /* error */
|
||||||
Genode::error("mmap could not obtain file content");
|
error("mmap could not obtain file content");
|
||||||
::munmap(addr, length);
|
::munmap(addr, length);
|
||||||
errno = EACCES;
|
errno = EACCES;
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
|
@ -1315,7 +1315,7 @@ void *Libc::Vfs_plugin::mmap(void *addr_in, ::size_t length, int prot, int flags
|
||||||
|
|
||||||
int Libc::Vfs_plugin::munmap(void *addr, ::size_t)
|
int Libc::Vfs_plugin::munmap(void *addr, ::size_t)
|
||||||
{
|
{
|
||||||
Libc::mem_alloc()->free(addr);
|
mem_alloc()->free(addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1363,8 +1363,8 @@ bool Libc::Vfs_plugin::supports_select(int nfds,
|
||||||
|
|
||||||
if (FD_ISSET(fd, readfds) || FD_ISSET(fd, writefds) || FD_ISSET(fd, exceptfds)) {
|
if (FD_ISSET(fd, readfds) || FD_ISSET(fd, writefds) || FD_ISSET(fd, exceptfds)) {
|
||||||
|
|
||||||
Libc::File_descriptor *fdo =
|
File_descriptor *fdo =
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
|
|
||||||
if (fdo && (fdo->plugin == this))
|
if (fdo && (fdo->plugin == this))
|
||||||
return true;
|
return true;
|
||||||
|
@ -1391,8 +1391,8 @@ int Libc::Vfs_plugin::select(int nfds,
|
||||||
|
|
||||||
for (int fd = 0; fd < nfds; ++fd) {
|
for (int fd = 0; fd < nfds; ++fd) {
|
||||||
|
|
||||||
Libc::File_descriptor *fdo =
|
File_descriptor *fdo =
|
||||||
Libc::file_descriptor_allocator()->find_by_libc_fd(fd);
|
file_descriptor_allocator()->find_by_libc_fd(fd);
|
||||||
|
|
||||||
/* handle only fds that belong to this plugin */
|
/* handle only fds that belong to this plugin */
|
||||||
if (!fdo || (fdo->plugin != this))
|
if (!fdo || (fdo->plugin != this))
|
||||||
|
@ -1406,7 +1406,7 @@ int Libc::Vfs_plugin::select(int nfds,
|
||||||
FD_SET(fd, readfds);
|
FD_SET(fd, readfds);
|
||||||
++nready;
|
++nready;
|
||||||
} else {
|
} else {
|
||||||
Libc::notify_read_ready(handle);
|
notify_read_ready(handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user