mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +00:00
parent
46f89d143b
commit
dc8a2ec523
@ -482,13 +482,7 @@ Libraries:
|
||||
:'libports/lib/mk/libc':
|
||||
C runtime ported from FreeBSD.
|
||||
|
||||
:'libports/lib/mk/libc_lwip_nic_dhcp':
|
||||
Translates the BSD socket API to a NIC session using the lwIP stack.
|
||||
|
||||
:'dde_linux/lib/mk/libc_lxip':
|
||||
Translates the BSD socket API to a NIC session using the Linux TCP/IP stack.
|
||||
|
||||
:'libports/lib/mk/libc_ffat':
|
||||
:'libports/lib/mk/libc_fatfs':
|
||||
Accesses files on a block device that contains a FAT32 file system.
|
||||
|
||||
:'libports/lib/mk/libc_fuse_exfat':
|
||||
@ -497,10 +491,6 @@ Libraries:
|
||||
:'libports/lib/mk/libc_fuse_ext2':
|
||||
Accesses files on a block device that contains an ext2 file system.
|
||||
|
||||
:'libports/lib/mk/libc_terminal':
|
||||
Connects the standard input and output from/to Genode's terminal session
|
||||
interface.
|
||||
|
||||
:'libports/lib/mk/stdcxx':
|
||||
Standard C++ library
|
||||
|
||||
|
@ -144,7 +144,7 @@ install_config $config
|
||||
set boot_modules {
|
||||
core init timer ld.lib.so noux terminal_mux terminal_log
|
||||
test-signal cli_monitor test-resource_yield posix.lib.so
|
||||
libc.lib.so vfs.lib.so libm.lib.so libc_noux.lib.so libc_terminal.lib.so ncurses.lib.so
|
||||
libc.lib.so vfs.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so
|
||||
vim.tar pc_uart_drv
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = terminal_mux
|
||||
SRC_CC = main.cc ncurses.cc
|
||||
LIBS = libc libc_terminal ncurses
|
||||
LIBS = libc ncurses
|
||||
INC_DIR += $(PRG_DIR)
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
@ -1,8 +0,0 @@
|
||||
SRC_CC = plugin.cc
|
||||
LIBS += libc
|
||||
|
||||
vpath plugin.cc $(REP_DIR)/src/lib/libc_terminal
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,6 +0,0 @@
|
||||
The 'libc_terminal' plugin allows the use of Genode's terminal-session
|
||||
interface via file operations of the C library. The plugin responds to opening
|
||||
requests for the file "/dev/terminal". Read and write operations referring to
|
||||
the resulting file descriptor are redirected to a terminal service as defined
|
||||
via Genode's service routing policy. The plugin supports 'read', 'write',
|
||||
'stat', and 'select'.
|
@ -1,368 +0,0 @@
|
||||
/*
|
||||
* \brief Libc plugin that uses Genode's Terminal session
|
||||
* \author Norman Feske
|
||||
* \date 2011-09-09
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* libc plugin interface */
|
||||
#include <libc-plugin/plugin.h>
|
||||
#include <libc-plugin/fd_alloc.h>
|
||||
#include <libc/allocator.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <terminal_session/connection.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <base/log.h>
|
||||
#include <base/env.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
extern void (*libc_select_notify)();
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
typedef Genode::Thread_deprecated<8192> Read_sigh_thread;
|
||||
|
||||
|
||||
/**
|
||||
* Thread for receiving notifications about data available for reading
|
||||
* from terminal session
|
||||
*/
|
||||
class Read_sigh : Read_sigh_thread
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Lock _startup_lock;
|
||||
|
||||
Genode::Signal_context _sig_ctx;
|
||||
Genode::Signal_receiver _sig_rec;
|
||||
Genode::Signal_context_capability _sig_cap;
|
||||
|
||||
void entry()
|
||||
{
|
||||
_sig_cap = _sig_rec.manage(&_sig_ctx);
|
||||
|
||||
_startup_lock.unlock();
|
||||
|
||||
for (;;) {
|
||||
_sig_rec.wait_for_signal();
|
||||
|
||||
if (libc_select_notify)
|
||||
libc_select_notify();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Read_sigh()
|
||||
:
|
||||
Read_sigh_thread("read_sigh"),
|
||||
_startup_lock(Genode::Lock::LOCKED)
|
||||
{
|
||||
start();
|
||||
|
||||
/* wait until '_sig_cap' is initialized */
|
||||
_startup_lock.lock();
|
||||
}
|
||||
|
||||
Genode::Signal_context_capability cap() { return _sig_cap; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return singleton instance of 'Read_sigh'
|
||||
*/
|
||||
static Genode::Signal_context_capability read_sigh()
|
||||
{
|
||||
static Read_sigh inst;
|
||||
return inst.cap();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An open file descriptor for this plugin corresponds to a terminal
|
||||
* connection
|
||||
*
|
||||
* The terminal connection is created along with the context. The
|
||||
* notifications about data available for reading are delivered to
|
||||
* the 'Read_sigh' thread, which cares about unblocking 'select()'.
|
||||
*/
|
||||
class Plugin_context : public Libc::Plugin_context, public Terminal::Connection
|
||||
{
|
||||
private:
|
||||
|
||||
int _status_flags;
|
||||
|
||||
public:
|
||||
|
||||
Plugin_context(Genode::Env &env)
|
||||
:
|
||||
Terminal::Connection(env),
|
||||
_status_flags(0)
|
||||
{
|
||||
read_avail_sigh(read_sigh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/get file status status flags
|
||||
*/
|
||||
void status_flags(int flags) { _status_flags = flags; }
|
||||
int status_flags() { return _status_flags; }
|
||||
};
|
||||
|
||||
|
||||
static inline Plugin_context *context(Libc::File_descriptor *fd)
|
||||
{
|
||||
return static_cast<Plugin_context *>(fd->context);
|
||||
}
|
||||
|
||||
|
||||
class Plugin : public Libc::Plugin
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env *_env_ptr = nullptr;
|
||||
|
||||
Libc::Allocator _alloc { };
|
||||
|
||||
/**
|
||||
* File name this plugin feels responsible for
|
||||
*/
|
||||
static char const *_dev_name() { return "/dev/terminal"; }
|
||||
|
||||
/*
|
||||
* Prioritize plugin over libc_vfs
|
||||
*/
|
||||
enum { PLUGIN_PRIORITY = 1 };
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Plugin() : Libc::Plugin(PLUGIN_PRIORITY) { }
|
||||
|
||||
void init(Genode::Env &env) override { _env_ptr = &env; }
|
||||
|
||||
bool supports_stat(const char *path)
|
||||
{
|
||||
return (Genode::strcmp(path, "/dev") == 0) ||
|
||||
(Genode::strcmp(path, _dev_name()) == 0);
|
||||
}
|
||||
|
||||
bool supports_open(const char *path, int flags)
|
||||
{
|
||||
return (Genode::strcmp(path, _dev_name()) == 0);
|
||||
}
|
||||
|
||||
Libc::File_descriptor *open(const char *pathname, int flags)
|
||||
{
|
||||
if (!_env_ptr)
|
||||
Genode::error("libc_terminal: missing call of Plugin::init");
|
||||
|
||||
Plugin_context *context = new (_alloc) Plugin_context(*_env_ptr);
|
||||
|
||||
context->status_flags(flags);
|
||||
return Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
}
|
||||
|
||||
int close(Libc::File_descriptor *fd)
|
||||
{
|
||||
Genode::destroy(_alloc, context(fd));
|
||||
Libc::file_descriptor_allocator()->free(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stat(const char *path, struct stat *buf)
|
||||
{
|
||||
/*
|
||||
* We pretent to be a character device
|
||||
*
|
||||
* This is important, i.e., to convince the gdbserver code to
|
||||
* cooperate with us.
|
||||
*/
|
||||
if (buf) {
|
||||
Genode::memset(buf, 0, sizeof(struct stat));
|
||||
if (Genode::strcmp(path, "/dev") == 0)
|
||||
buf->st_mode = S_IFDIR;
|
||||
else if (Genode::strcmp(path, _dev_name()) == 0)
|
||||
buf->st_mode = S_IFCHR;
|
||||
else {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fstat(Libc::File_descriptor *fd, struct stat *buf)
|
||||
{
|
||||
if (buf) {
|
||||
Genode::memset(buf, 0, sizeof(struct stat));
|
||||
buf->st_mode = S_IFCHR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool supports_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout)
|
||||
{
|
||||
fd_set in_readfds;
|
||||
fd_set in_writefds;
|
||||
FD_ZERO(&in_readfds);
|
||||
FD_ZERO(&in_writefds);
|
||||
|
||||
if (readfds) {
|
||||
in_readfds = *readfds;
|
||||
FD_ZERO(readfds);
|
||||
}
|
||||
|
||||
if (writefds) {
|
||||
in_writefds = *writefds;
|
||||
FD_ZERO(writefds);
|
||||
}
|
||||
|
||||
if (exceptfds)
|
||||
FD_ZERO(exceptfds);
|
||||
|
||||
int nready = 0;
|
||||
for (int libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
||||
Libc::File_descriptor *fdo =
|
||||
Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||
|
||||
/* handle only libc_fds that belong to this plugin */
|
||||
if (!fdo || (fdo->plugin != this))
|
||||
continue;
|
||||
|
||||
if (FD_ISSET(libc_fd, &in_readfds) && context(fdo)->avail()) {
|
||||
if (readfds)
|
||||
FD_SET(libc_fd, readfds);
|
||||
nready++;
|
||||
}
|
||||
|
||||
if (FD_ISSET(libc_fd, &in_writefds)) {
|
||||
if (writefds)
|
||||
FD_SET(libc_fd, writefds);
|
||||
nready++;
|
||||
}
|
||||
}
|
||||
return nready;
|
||||
}
|
||||
|
||||
ssize_t write(Libc::File_descriptor *fd, const void *buf, ::size_t count)
|
||||
{
|
||||
Genode::size_t chunk_size = context(fd)->io_buffer_size();
|
||||
|
||||
Genode::size_t written_bytes = 0;
|
||||
while (written_bytes < count) {
|
||||
|
||||
Genode::size_t n = Genode::min(count - written_bytes, chunk_size);
|
||||
context(fd)->write((char *)buf + written_bytes, n);
|
||||
written_bytes += n;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count)
|
||||
{
|
||||
for (;;) {
|
||||
Genode::size_t num_bytes = context(fd)->read(buf, count);
|
||||
|
||||
if (num_bytes)
|
||||
return num_bytes;
|
||||
|
||||
/* read returned 0, block until data becomes available */
|
||||
fd_set rfds;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd->libc_fd, &rfds);
|
||||
::select(fd->libc_fd + 1, &rfds, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case F_GETFL: return context(fd)->status_flags();
|
||||
case F_SETFD:
|
||||
{
|
||||
const long supported_flags = FD_CLOEXEC;
|
||||
/* if unsupported flags are used, fall through with error */
|
||||
if (!(arg & ~supported_flags)) {
|
||||
/* close fd if exec is called - no exec support -> ignore */
|
||||
if (arg & FD_CLOEXEC)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
default:
|
||||
Genode::warning("fcntl(): command ", cmd, " args ", arg, " "
|
||||
"not supported - terminal");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl(Libc::File_descriptor *fd, int request, char *argp)
|
||||
{
|
||||
struct termios *t = (struct termios*)argp;
|
||||
switch (request) {
|
||||
case TIOCGETA:
|
||||
Genode::memset(t,0,sizeof(struct termios));
|
||||
t->c_lflag = ECHO;
|
||||
return 0;
|
||||
case TIOCSETAW:
|
||||
return 0;
|
||||
case TIOCSETAF:
|
||||
return 0;
|
||||
case TIOCGWINSZ:
|
||||
{
|
||||
::winsize *winsize = (::winsize *)argp;
|
||||
Terminal::Session::Size terminal_size = context(fd)->size();
|
||||
winsize->ws_row = terminal_size.lines();
|
||||
winsize->ws_col = terminal_size.columns();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int dup2(Libc::File_descriptor *fd, Libc::File_descriptor *new_fd)
|
||||
{
|
||||
new_fd->context = fd->context;
|
||||
return new_fd->libc_fd;
|
||||
}
|
||||
};
|
||||
|
||||
} /* unnamed namespace */
|
||||
|
||||
|
||||
void __attribute__((constructor)) init_libc_terminal(void)
|
||||
{
|
||||
static Plugin plugin;
|
||||
}
|
@ -226,9 +226,8 @@ scenario, please refer to the 'tcp_terminal.run' script proved at 'gems/run/'.
|
||||
GDB monitor is built upon the libc and a few custom libc plugins, each coming
|
||||
in the form of a separate shared library. Please make sure to integrate those
|
||||
shared libraries along with the dynamic linker (ld.lib.so) in your boot image.
|
||||
They are 'libc.lib.so' (the libc), 'libc_terminal.lib.so' (to
|
||||
connect with GDB), and 'libc_pipe.lib.so' (used for synchronizing threads
|
||||
via 'select' and 'pipe'). For using the TCP terminal, 'lwip.lib.so' (TCP/IP
|
||||
They are 'libc.lib.so' (the libc), and 'libc_pipe.lib.so' (used for synchronizing
|
||||
threads via 'select' and 'pipe'). For using the TCP terminal, 'lwip.lib.so' (TCP/IP
|
||||
stack) is needed as well.
|
||||
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
<rom label="virtualbox5-nova"/>
|
||||
<rom label="libc.lib.so"/>
|
||||
<rom label="libc_pipe.lib.so"/>
|
||||
<rom label="libc_terminal.lib.so"/>
|
||||
<rom label="libm.lib.so"/>
|
||||
<rom label="libiconv.lib.so"/>
|
||||
<rom label="qemu-usb.lib.so"/>
|
||||
|
@ -35,8 +35,6 @@ $(MIRROR_FROM_PORT_DIR):
|
||||
|
||||
MIRROR_FROM_LIBPORTS := lib/mk/libc_pipe.mk \
|
||||
src/lib/libc_pipe \
|
||||
lib/mk/libc_terminal.mk \
|
||||
src/lib/libc_terminal \
|
||||
lib/mk/libc-mem.mk \
|
||||
lib/mk/libc-common.inc \
|
||||
src/lib/libc/libc_mem_alloc.cc \
|
||||
|
@ -36,8 +36,6 @@ $(MIRROR_FROM_PORT_DIR):
|
||||
|
||||
MIRROR_FROM_LIBPORTS := lib/mk/libc_pipe.mk \
|
||||
src/lib/libc_pipe \
|
||||
lib/mk/libc_terminal.mk \
|
||||
src/lib/libc_terminal \
|
||||
lib/mk/libc-mem.mk \
|
||||
lib/mk/libc-common.inc \
|
||||
src/lib/libc/libc_mem_alloc.cc \
|
||||
|
@ -257,7 +257,7 @@ set boot_modules {
|
||||
usb_hid.iso
|
||||
vm_genode_usb_hid.vbox
|
||||
ld.lib.so libc.lib.so vfs.lib.so libm.lib.so libc_pipe.lib.so
|
||||
libc_terminal.lib.so libiconv.lib.so stdcxx.lib.so
|
||||
libiconv.lib.so stdcxx.lib.so
|
||||
qemu-usb.lib.so
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ lappend_if [expr $use_gui] boot_modules report_rom
|
||||
|
||||
append boot_modules {
|
||||
ld.lib.so libc.lib.so vfs.lib.so libm.lib.so libc_pipe.lib.so
|
||||
libc_terminal.lib.so libiconv.lib.so stdcxx.lib.so
|
||||
libiconv.lib.so stdcxx.lib.so
|
||||
qemu-usb.lib.so
|
||||
}
|
||||
|
||||
|
@ -371,7 +371,7 @@ install_config $config
|
||||
append boot_modules {
|
||||
part_block ahci_drv fs_rom
|
||||
libc.lib.so vfs.lib.so libm.lib.so
|
||||
libc_pipe.lib.so libc_terminal.lib.so
|
||||
libc_pipe.lib.so
|
||||
libiconv.lib.so stdcxx.lib.so
|
||||
qemu-usb.lib.so
|
||||
}
|
||||
|
@ -379,7 +379,6 @@ append boot_modules { ld.lib.so }
|
||||
append boot_modules { libc.lib.so }
|
||||
append boot_modules { libm.lib.so }
|
||||
append boot_modules { libc_pipe.lib.so }
|
||||
append boot_modules { libc_terminal.lib.so }
|
||||
append boot_modules { libiconv.lib.so }
|
||||
append boot_modules { stdcxx.lib.so }
|
||||
append boot_modules { qemu-usb.lib.so }
|
||||
|
@ -20,7 +20,7 @@ LIBS += virtualbox5-bios virtualbox5-recompiler virtualbox5-runtime \
|
||||
virtualbox5-xml virtualbox5-main virtualbox5-apiwrap \
|
||||
virtualbox5-dis
|
||||
|
||||
LIBS += libc_terminal libc_pipe libiconv
|
||||
LIBS += libc_pipe libiconv
|
||||
|
||||
LIBS += qemu-usb
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user