From f9389109bf286760a484fbe022f7e6a78c6ba426 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Wed, 1 Feb 2017 11:28:15 +0100 Subject: [PATCH] Support select in libc VFS plugin by read_ready() --- repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc | 10 ++- repos/libports/run/libc_select.run | 24 ++++-- .../libports/src/lib/libc/file_operations.cc | 16 ++-- repos/libports/src/lib/libc/libc_file.h | 4 +- repos/libports/src/lib/libc/vfs_plugin.cc | 81 +++++++++++++++++-- repos/libports/src/lib/libc/vfs_plugin.h | 20 +++-- .../libports/src/lib/vfs/jitterentropy/vfs.cc | 3 +- .../lib/vfs/jitterentropy/vfs_jitterentropy.h | 2 + repos/os/include/vfs/dir_file_system.h | 12 ++- repos/os/include/vfs/file_io_service.h | 5 ++ repos/os/src/lib/vfs/block_file_system.h | 2 + repos/os/src/lib/vfs/fs_file_system.h | 2 + repos/os/src/lib/vfs/inline_file_system.h | 2 + repos/os/src/lib/vfs/log_file_system.h | 2 + repos/os/src/lib/vfs/null_file_system.h | 2 + repos/os/src/lib/vfs/ram_file_system.h | 2 + repos/os/src/lib/vfs/rom_file_system.h | 2 + repos/os/src/lib/vfs/rtc_file_system.h | 2 + repos/os/src/lib/vfs/symlink_file_system.h | 2 + repos/os/src/lib/vfs/tar_file_system.h | 2 + repos/os/src/lib/vfs/terminal_file_system.h | 5 ++ repos/os/src/lib/vfs/zero_file_system.h | 2 + 22 files changed, 174 insertions(+), 30 deletions(-) diff --git a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc index 87b26100d8..7f8de3ccd9 100644 --- a/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc +++ b/repos/dde_rump/src/lib/vfs/rump/vfs_rump.cc @@ -470,6 +470,8 @@ class Vfs::Rump_file_system : public File_system return READ_OK; } + bool read_ready(Vfs_handle *) override { return true; } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) override { Rump_vfs_handle *handle = @@ -525,7 +527,8 @@ class Rump_factory : public Vfs::File_system_factory Vfs::File_system *create(Genode::Env &env, Genode::Allocator &alloc, - Genode::Xml_node config) override + Genode::Xml_node config, + Vfs::Io_response_handler &) override { return new (alloc) Vfs::Rump_file_system(config); } @@ -538,10 +541,11 @@ extern "C" Vfs::File_system_factory *vfs_file_system_factory(void) { Vfs::File_system *create(Genode::Env &env, Genode::Allocator &alloc, - Genode::Xml_node node) override + Genode::Xml_node node, + Vfs::Io_response_handler &io_handler) override { static Rump_factory factory(env, alloc); - return factory.create(env, alloc, node); + return factory.create(env, alloc, node, io_handler); } }; diff --git a/repos/libports/run/libc_select.run b/repos/libports/run/libc_select.run index dba1e231dd..e888b78ef7 100644 --- a/repos/libports/run/libc_select.run +++ b/repos/libports/run/libc_select.run @@ -1,6 +1,6 @@ set build_components { - core init drivers/timer - test/libc_select + core init drivers/timer server/terminal_crosslink + test/libc_select test/libc_counter } build $build_components @@ -29,19 +29,33 @@ set config { + + + + + + + + + + + + + + - + @@ -53,8 +67,8 @@ set config { install_config $config set boot_modules { - core init timer - test-libc_select + core init timer terminal_crosslink + test-libc_counter-source test-libc_select ld.lib.so libc.lib.so libm.lib.so stdcxx.lib.so pthread.lib.so libc_pipe.lib.so } diff --git a/repos/libports/src/lib/libc/file_operations.cc b/repos/libports/src/lib/libc/file_operations.cc index f6e5126a50..68112bf5b2 100644 --- a/repos/libports/src/lib/libc/file_operations.cc +++ b/repos/libports/src/lib/libc/file_operations.cc @@ -2,11 +2,13 @@ * \brief libc file operations * \author Christian Prochaska * \author Norman Feske + * \author Emery Hemingway + * \author Christian Helmuth * \date 2010-01-21 */ /* - * Copyright (C) 2010-2013 Genode Labs GmbH + * Copyright (C) 2010-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -216,8 +218,10 @@ extern "C" int chdir(const char *path) } -extern "C" int _close(int libc_fd) { - FD_FUNC_WRAPPER(close, libc_fd); } +extern "C" int _close(int libc_fd) +{ + FD_FUNC_WRAPPER(close, libc_fd); +} extern "C" int close(int libc_fd) { return _close(libc_fd); } @@ -538,8 +542,10 @@ extern "C" int pipe(int pipefd[2]) } -extern "C" ssize_t _read(int libc_fd, void *buf, ::size_t count) { - FD_FUNC_WRAPPER(read, libc_fd, buf, count); } +extern "C" ssize_t _read(int libc_fd, void *buf, ::size_t count) +{ + FD_FUNC_WRAPPER(read, libc_fd, buf, count); +} extern "C" ssize_t read(int libc_fd, void *buf, ::size_t count) diff --git a/repos/libports/src/lib/libc/libc_file.h b/repos/libports/src/lib/libc/libc_file.h index 6bb76506f1..d57cce98e4 100644 --- a/repos/libports/src/lib/libc/libc_file.h +++ b/repos/libports/src/lib/libc/libc_file.h @@ -1,11 +1,12 @@ /* * \brief File-operation utilities * \author Christian Helmuth + * \author Emery Hemingway * \date 2015-06-30 */ /* - * Copyright (C) 2015 Genode Labs GmbH + * Copyright (C) 2015-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -72,5 +73,4 @@ static inline Libc::File_descriptor *libc_fd_to_fd(int libc_fd, const char *func #define FNAME_FUNC_WRAPPER(func_name, path, ...) \ FNAME_FUNC_WRAPPER_GENERIC(return, func_name, path, ##__VA_ARGS__ ) - #endif /* _LIBC_FILE_H_ */ diff --git a/repos/libports/src/lib/libc/vfs_plugin.cc b/repos/libports/src/lib/libc/vfs_plugin.cc index f8b8c0e325..3e3ab7ec41 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.cc +++ b/repos/libports/src/lib/libc/vfs_plugin.cc @@ -1,11 +1,13 @@ /* - * \brief Libc plugin for using a process-local virtual file system - * \author Norman Feske - * \date 2014-04-09 + * \brief Libc plugin for using a process-local virtual file system + * \author Norman Feske + * \author Christian Helmuth + * \author Emery Hemingway + * \date 2014-04-09 */ /* - * Copyright (C) 2014-2016 Genode Labs GmbH + * Copyright (C) 2014-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -36,7 +38,7 @@ #include /* libc-internal includes */ -#include +#include "libc_mem_alloc.h" #include "libc_errno.h" #include "task.h" @@ -725,3 +727,72 @@ int Libc::Vfs_plugin::munmap(void *addr, ::size_t) Libc::mem_alloc()->free(addr); return 0; } + + +bool Libc::Vfs_plugin::supports_select(int nfds, + fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + /* return true if any file descriptor (which is set) belongs to the VFS */ + for (int fd = 0; fd < nfds; ++fd) { + + if (FD_ISSET(fd, readfds) || FD_ISSET(fd, writefds) || FD_ISSET(fd, exceptfds)) { + + Libc::File_descriptor *fdo = + Libc::file_descriptor_allocator()->find_by_libc_fd(fd); + + if (fdo && (fdo->plugin == this)) + return true; + } + } + return false; +} + + +int Libc::Vfs_plugin::select(int nfds, + fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) +{ + int nready = 0; + + fd_set const in_readfds = *readfds; + fd_set const in_writefds = *writefds; + /* XXX exceptfds not supported */ + + /* clear fd sets */ + FD_ZERO(readfds); + FD_ZERO(writefds); + FD_ZERO(exceptfds); + + for (int fd = 0; fd < nfds; ++fd) { + + Libc::File_descriptor *fdo = + Libc::file_descriptor_allocator()->find_by_libc_fd(fd); + + /* handle only fds that belong to this plugin */ + if (!fdo || (fdo->plugin != this)) + continue; + + Vfs::Vfs_handle *handle = vfs_handle(fdo); + if (!handle) continue; + + if (FD_ISSET(fd, &in_readfds)) { + if (handle->fs().read_ready(handle)) { + FD_SET(fd, readfds); + ++nready; + } else { +// handle->fs().notify_read_ready(handle); + } + } + + if (FD_ISSET(fd, &in_writefds)) { + if (true /* XXX always writeable */) { + FD_SET(fd, writefds); + ++nready; + } + } + + /* XXX exceptfds not supported */ + } + return nready; +} diff --git a/repos/libports/src/lib/libc/vfs_plugin.h b/repos/libports/src/lib/libc/vfs_plugin.h index 6ece55d962..389ef5c657 100644 --- a/repos/libports/src/lib/libc/vfs_plugin.h +++ b/repos/libports/src/lib/libc/vfs_plugin.h @@ -1,11 +1,13 @@ /* - * \brief Libc plugin for using a process-local virtual file system - * \author Norman Feske - * \date 2014-04-09 + * \brief Libc plugin for using a process-local virtual file system + * \author Norman Feske + * \author Emery Hemingway + * \author Christian Helmuth + * \date 2014-04-09 */ /* - * Copyright (C) 2014-2016 Genode Labs GmbH + * Copyright (C) 2014-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -71,9 +73,6 @@ class Libc::Vfs_plugin : public Libc::Plugin public: - /** - * Constructor - */ Vfs_plugin(Libc::Env &env, Genode::Allocator &alloc) : _alloc(alloc), _root_dir(env.vfs()) @@ -96,7 +95,7 @@ class Libc::Vfs_plugin : public Libc::Plugin }); } - ~Vfs_plugin() { } + ~Vfs_plugin() final { } bool supports_access(const char *, int) override { return true; } bool supports_mkdir(const char *, mode_t) override { return true; } @@ -109,6 +108,10 @@ class Libc::Vfs_plugin : public Libc::Plugin bool supports_unlink(const char *) override { return true; } bool supports_mmap() override { return true; } + bool supports_select(int nfds, + fd_set *readfds, fd_set *writefds, fd_set *exceptfds, + struct timeval *timeout) override; + Libc::File_descriptor *open(const char *, int, int libc_fd); Libc::File_descriptor *open(const char *path, int flags) override @@ -138,6 +141,7 @@ class Libc::Vfs_plugin : public Libc::Plugin ssize_t write(Libc::File_descriptor *, const void *, ::size_t ) override; void *mmap(void *, ::size_t, int, int, Libc::File_descriptor *, ::off_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; }; #endif diff --git a/repos/libports/src/lib/vfs/jitterentropy/vfs.cc b/repos/libports/src/lib/vfs/jitterentropy/vfs.cc index 4abf4bbf5a..d2695736f1 100644 --- a/repos/libports/src/lib/vfs/jitterentropy/vfs.cc +++ b/repos/libports/src/lib/vfs/jitterentropy/vfs.cc @@ -21,7 +21,8 @@ struct Jitterentropy_factory : Vfs::File_system_factory { Vfs::File_system *create(Genode::Env&, Genode::Allocator &alloc, - Genode::Xml_node node) override + Genode::Xml_node node, + Vfs::Io_response_handler &) override { return new (alloc) Jitterentropy_file_system(node); } diff --git a/repos/libports/src/lib/vfs/jitterentropy/vfs_jitterentropy.h b/repos/libports/src/lib/vfs/jitterentropy/vfs_jitterentropy.h index 4f285a11b4..1e77a2deb6 100644 --- a/repos/libports/src/lib/vfs/jitterentropy/vfs_jitterentropy.h +++ b/repos/libports/src/lib/vfs/jitterentropy/vfs_jitterentropy.h @@ -98,6 +98,8 @@ class Jitterentropy_file_system : public Vfs::Single_file_system return READ_OK; } + + bool read_ready(Vfs::Vfs_handle *) override { return true; } }; #endif /* _JITTERENTROPY_FILE_SYSTEM_H_ */ diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index 39c73c0d21..2c96ce6655 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -1,11 +1,13 @@ /* * \brief Directory file system * \author Norman Feske + * \author Emery Hemingway + * \author Christian Helmuth * \date 2012-04-23 */ /* - * Copyright (C) 2011-2016 Genode Labs GmbH + * Copyright (C) 2011-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -601,6 +603,14 @@ class Vfs::Dir_file_system : public File_system { return FTRUNCATE_ERR_NO_PERM; } + + bool read_ready(Vfs_handle *handle) override + { + if (&handle->fs() == this) + return true; + + return handle->fs().read_ready(handle); + } }; #endif /* _INCLUDE__VFS__DIR_FILE_SYSTEM_H_ */ diff --git a/repos/os/include/vfs/file_io_service.h b/repos/os/include/vfs/file_io_service.h index 29b98399ae..5ed8fc4958 100644 --- a/repos/os/include/vfs/file_io_service.h +++ b/repos/os/include/vfs/file_io_service.h @@ -76,6 +76,11 @@ struct Vfs::File_io_service file_size &out_count) { return read(vfs_handle, dst, count, out_count); } + /** + * Return true if the handle has readable data + */ + virtual bool read_ready(Vfs_handle *) = 0; + /*************** ** Ftruncate ** diff --git a/repos/os/src/lib/vfs/block_file_system.h b/repos/os/src/lib/vfs/block_file_system.h index 8d1de84837..7b6c2b483c 100644 --- a/repos/os/src/lib/vfs/block_file_system.h +++ b/repos/os/src/lib/vfs/block_file_system.h @@ -312,6 +312,8 @@ class Vfs::Block_file_system : public Single_file_system return READ_OK; } + bool read_ready(Vfs_handle *) override { return true; } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size) override { return FTRUNCATE_OK; diff --git a/repos/os/src/lib/vfs/fs_file_system.h b/repos/os/src/lib/vfs/fs_file_system.h index 4a5c13c2f7..9f2b32df1d 100644 --- a/repos/os/src/lib/vfs/fs_file_system.h +++ b/repos/os/src/lib/vfs/fs_file_system.h @@ -629,6 +629,8 @@ class Vfs::Fs_file_system : public File_system return READ_OK; } + bool read_ready(Vfs_handle *) override { return true; } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) override { Fs_vfs_handle const *handle = static_cast(vfs_handle); diff --git a/repos/os/src/lib/vfs/inline_file_system.h b/repos/os/src/lib/vfs/inline_file_system.h index 419785c52a..a6b9b83e87 100644 --- a/repos/os/src/lib/vfs/inline_file_system.h +++ b/repos/os/src/lib/vfs/inline_file_system.h @@ -96,6 +96,8 @@ class Vfs::Inline_file_system : public Single_file_system out_count = num_bytes; return READ_OK; } + + bool read_ready(Vfs_handle *) override { return true; } }; #endif /* _INCLUDE__VFS__INLINE_FILE_SYSTEM_H_ */ diff --git a/repos/os/src/lib/vfs/log_file_system.h b/repos/os/src/lib/vfs/log_file_system.h index 6c807ca81a..d68d3d9a32 100644 --- a/repos/os/src/lib/vfs/log_file_system.h +++ b/repos/os/src/lib/vfs/log_file_system.h @@ -90,6 +90,8 @@ class Vfs::Log_file_system : public Single_file_system out_count = 0; return READ_OK; } + + bool read_ready(Vfs_handle *) override { return false; } }; #endif /* _INCLUDE__VFS__LOG_FILE_SYSTEM_H_ */ diff --git a/repos/os/src/lib/vfs/null_file_system.h b/repos/os/src/lib/vfs/null_file_system.h index c279dddba5..3aaf024bf0 100644 --- a/repos/os/src/lib/vfs/null_file_system.h +++ b/repos/os/src/lib/vfs/null_file_system.h @@ -53,6 +53,8 @@ struct Vfs::Null_file_system : Single_file_system return READ_OK; } + bool read_ready(Vfs_handle *) override { return false; } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size) override { return FTRUNCATE_OK; diff --git a/repos/os/src/lib/vfs/ram_file_system.h b/repos/os/src/lib/vfs/ram_file_system.h index f0024a0d1e..e219651763 100644 --- a/repos/os/src/lib/vfs/ram_file_system.h +++ b/repos/os/src/lib/vfs/ram_file_system.h @@ -764,6 +764,8 @@ class Vfs::Ram_file_system : public Vfs::File_system return READ_OK; } + bool read_ready(Vfs_handle *) override { return true; } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size len) override { if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY) diff --git a/repos/os/src/lib/vfs/rom_file_system.h b/repos/os/src/lib/vfs/rom_file_system.h index 2450e2c9b0..d39d2f198d 100644 --- a/repos/os/src/lib/vfs/rom_file_system.h +++ b/repos/os/src/lib/vfs/rom_file_system.h @@ -142,6 +142,8 @@ class Vfs::Rom_file_system : public Single_file_system out_count = num_bytes; return READ_OK; } + + bool read_ready(Vfs_handle *) override { return true; } }; #endif /* _INCLUDE__VFS__ROM_FILE_SYSTEM_H_ */ diff --git a/repos/os/src/lib/vfs/rtc_file_system.h b/repos/os/src/lib/vfs/rtc_file_system.h index fccea531b0..21f2fd6aaa 100644 --- a/repos/os/src/lib/vfs/rtc_file_system.h +++ b/repos/os/src/lib/vfs/rtc_file_system.h @@ -98,6 +98,8 @@ class Vfs::Rtc_file_system : public Single_file_system return READ_OK; } + + bool read_ready(Vfs_handle *) override { return true; } }; #endif /* _INCLUDE__VFS__RTC_FILE_SYSTEM_H_ */ diff --git a/repos/os/src/lib/vfs/symlink_file_system.h b/repos/os/src/lib/vfs/symlink_file_system.h index 1752f2585b..5cf5ed3f8c 100644 --- a/repos/os/src/lib/vfs/symlink_file_system.h +++ b/repos/os/src/lib/vfs/symlink_file_system.h @@ -82,6 +82,8 @@ class Vfs::Symlink_file_system : public Single_file_system Read_result read(Vfs_handle *, char *, file_size, file_size &) override { return READ_ERR_INVALID; } + bool read_ready(Vfs_handle *) override { return false; } + Ftruncate_result ftruncate(Vfs_handle *, file_size) override { return FTRUNCATE_ERR_NO_PERM; } }; diff --git a/repos/os/src/lib/vfs/tar_file_system.h b/repos/os/src/lib/vfs/tar_file_system.h index 95c4b19dda..337546d384 100644 --- a/repos/os/src/lib/vfs/tar_file_system.h +++ b/repos/os/src/lib/vfs/tar_file_system.h @@ -611,6 +611,8 @@ class Vfs::Tar_file_system : public File_system { return FTRUNCATE_ERR_NO_PERM; } + + bool read_ready(Vfs_handle *) override { return true; } }; #endif /* _INCLUDE__VFS__TAR_FILE_SYSTEM_H_ */ diff --git a/repos/os/src/lib/vfs/terminal_file_system.h b/repos/os/src/lib/vfs/terminal_file_system.h index 80b4135de6..2eee440708 100644 --- a/repos/os/src/lib/vfs/terminal_file_system.h +++ b/repos/os/src/lib/vfs/terminal_file_system.h @@ -101,6 +101,11 @@ class Vfs::Terminal_file_system : public Single_file_system return _read(vfs_handle, dst, count, out_count); } + bool read_ready(Vfs_handle *) override + { + return _terminal.avail(); + } + Ftruncate_result ftruncate(Vfs_handle *vfs_handle, file_size) override { return FTRUNCATE_OK; diff --git a/repos/os/src/lib/vfs/zero_file_system.h b/repos/os/src/lib/vfs/zero_file_system.h index 0ce9cb4485..0d5495acdd 100644 --- a/repos/os/src/lib/vfs/zero_file_system.h +++ b/repos/os/src/lib/vfs/zero_file_system.h @@ -53,6 +53,8 @@ struct Vfs::Zero_file_system : Single_file_system return READ_OK; } + + bool read_ready(Vfs_handle *) override { return true; } }; #endif /* _INCLUDE__VFS__ZERO_FILE_SYSTEM_H_ */