mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-05 18:50:04 +00:00
libc: pipe plugin
A libc plugin which implements pipes using a ring buffer. Fixes #1947
This commit is contained in:
parent
f81867f208
commit
ea726a1f48
@ -235,7 +235,7 @@ set boot_modules {
|
||||
freetype.lib.so
|
||||
gallium.lib.so
|
||||
icu.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -87,7 +87,7 @@ install_config $config
|
||||
set boot_modules {
|
||||
core init timer
|
||||
nic_drv
|
||||
ld.lib.so libc.lib.so lwip.lib.so libc_lock_pipe.lib.so
|
||||
ld.lib.so libc.lib.so lwip.lib.so libc_pipe.lib.so
|
||||
tcp_terminal
|
||||
test-terminal_echo
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
TARGET = tcp_terminal
|
||||
SRC_CC = main.cc
|
||||
LIBS = libc libc_lwip_nic_dhcp libc_lock_pipe
|
||||
LIBS = libc libc_lwip_nic_dhcp libc_pipe
|
||||
|
@ -1,6 +1,6 @@
|
||||
SRC_CC = plugin.cc
|
||||
LIBS += libc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_lock_pipe
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_pipe
|
||||
|
||||
SHARED_LIB = yes
|
@ -35,4 +35,4 @@ INC_DIR += $(REP_DIR)/include/qt5/qtbase/QtCore/private \
|
||||
$(QT5_CONTRIB_DIR)/qtbase/include/QtCore/$(QT_VERSION)/QtCore \
|
||||
$(QT5_CONTRIB_DIR)/qtbase/include/QtCore/$(QT_VERSION)/QtCore/private
|
||||
|
||||
LIBS += qt5_host_tools launchpad zlib icu libc libm alarm libc_lock_pipe pthread
|
||||
LIBS += qt5_host_tools launchpad zlib icu libc libm alarm libc_pipe pthread
|
||||
|
41
repos/libports/run/libc_pipe.run
Normal file
41
repos/libports/run/libc_pipe.run
Normal file
@ -0,0 +1,41 @@
|
||||
build "core init test/libc_pipe"
|
||||
|
||||
create_boot_directory
|
||||
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="CAP"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="test-libc_pipe">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<config>
|
||||
<libc stdout="/dev/log" stderr="/dev/log">
|
||||
<vfs> <dir name="dev"> <log/> </dir> </vfs>
|
||||
</libc>
|
||||
</config>
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
|
||||
build_boot_image {
|
||||
core init test-libc_pipe
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so pthread.lib.so
|
||||
}
|
||||
|
||||
append qemu_args " -nographic -m 64 "
|
||||
|
||||
run_genode_until "child .* exited with exit value 0.*\n" 10
|
||||
|
@ -90,7 +90,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -80,7 +80,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -67,7 +67,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -66,7 +66,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -66,7 +66,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -78,7 +78,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libcrypto.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
|
@ -70,7 +70,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libcrypto.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
|
@ -70,7 +70,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libcrypto.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
|
@ -66,7 +66,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -129,7 +129,7 @@ append boot_modules {
|
||||
icu.lib.so
|
||||
ld.lib.so
|
||||
libc.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
libm.lib.so
|
||||
libpng.lib.so
|
||||
jpeg.lib.so
|
||||
|
@ -1,22 +1,25 @@
|
||||
/*
|
||||
* \brief Pipe plugin implementation
|
||||
* \author Christian Prochaska
|
||||
* \date 2010-03-17
|
||||
* \date 2014-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2014-2016 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.
|
||||
*/
|
||||
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/ring_buffer.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -30,22 +33,27 @@
|
||||
extern void (*libc_select_notify)();
|
||||
|
||||
|
||||
namespace {
|
||||
namespace Libc_pipe {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
enum Type { READ_END, WRITE_END };
|
||||
enum { PIPE_BUF_SIZE = 4096 };
|
||||
|
||||
typedef Ring_buffer<unsigned char, PIPE_BUF_SIZE+1> Pipe_buffer;
|
||||
|
||||
class Plugin_context : public Libc::Plugin_context
|
||||
{
|
||||
private:
|
||||
|
||||
Type _type;
|
||||
char *_buffer;
|
||||
|
||||
Pipe_buffer *_buffer;
|
||||
|
||||
Libc::File_descriptor *_partner;
|
||||
Genode::Lock *_lock;
|
||||
Genode::Cancelable_lock::State *_lock_state;
|
||||
Genode::Semaphore *_write_avail_sem;
|
||||
|
||||
bool _nonblock = false;
|
||||
|
||||
public:
|
||||
|
||||
@ -61,21 +69,14 @@ namespace {
|
||||
|
||||
~Plugin_context();
|
||||
|
||||
Type type() const { return _type; }
|
||||
char *buffer() const { return _buffer; }
|
||||
Libc::File_descriptor *partner() const { return _partner; }
|
||||
Genode::Lock *lock() const { return _lock; }
|
||||
Genode::Cancelable_lock::State *lock_state() { return _lock_state; }
|
||||
Type type() const { return _type; }
|
||||
Pipe_buffer *buffer() const { return _buffer; }
|
||||
Libc::File_descriptor *partner() const { return _partner; }
|
||||
Genode::Semaphore *write_avail_sem() const { return _write_avail_sem; }
|
||||
bool nonblock() const { return _nonblock; }
|
||||
|
||||
void set_partner(Libc::File_descriptor *partner)
|
||||
{
|
||||
_partner = partner;
|
||||
}
|
||||
|
||||
void set_lock_state(Genode::Cancelable_lock::State lock_state)
|
||||
{
|
||||
*_lock_state = lock_state;
|
||||
}
|
||||
void set_partner(Libc::File_descriptor *partner) { _partner = partner; }
|
||||
void set_nonblock(bool nonblock) { _nonblock = nonblock; }
|
||||
};
|
||||
|
||||
|
||||
@ -88,20 +89,22 @@ namespace {
|
||||
*/
|
||||
Plugin();
|
||||
|
||||
bool supports_pipe();
|
||||
bool supports_pipe() override;
|
||||
bool supports_select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
fd_set *exceptfds,
|
||||
struct timeval *timeout);
|
||||
struct timeval *timeout) override;
|
||||
|
||||
int close(Libc::File_descriptor *pipefdo);
|
||||
int fcntl(Libc::File_descriptor *pipefdo, int cmd, long arg);
|
||||
int pipe(Libc::File_descriptor *pipefdo[2]);
|
||||
ssize_t read(Libc::File_descriptor *pipefdo, void *buf, ::size_t count);
|
||||
int close(Libc::File_descriptor *pipefdo) override;
|
||||
int fcntl(Libc::File_descriptor *pipefdo, int cmd, long arg) override;
|
||||
int pipe(Libc::File_descriptor *pipefdo[2]) override;
|
||||
ssize_t read(Libc::File_descriptor *pipefdo, void *buf,
|
||||
::size_t count) override;
|
||||
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout);
|
||||
ssize_t write(Libc::File_descriptor *pipefdo, const void *buf, ::size_t count);
|
||||
fd_set *exceptfds, struct timeval *timeout) override;
|
||||
ssize_t write(Libc::File_descriptor *pipefdo, const void *buf,
|
||||
::size_t count) override;
|
||||
};
|
||||
|
||||
|
||||
@ -138,30 +141,15 @@ namespace {
|
||||
|
||||
/* allocate shared resources */
|
||||
|
||||
_buffer = (char*)malloc(PIPE_BUF_SIZE);
|
||||
if (!_buffer) {
|
||||
PERR("pipe buffer allocation failed");
|
||||
}
|
||||
Genode::memset(_buffer, 0, PIPE_BUF_SIZE);
|
||||
_buffer = new (Genode::env()->heap()) Pipe_buffer;
|
||||
_write_avail_sem = new (Genode::env()->heap()) Genode::Semaphore(PIPE_BUF_SIZE);
|
||||
|
||||
_lock_state = new (Genode::env()->heap())
|
||||
Genode::Cancelable_lock::State(Genode::Lock::LOCKED);
|
||||
|
||||
if (!_lock_state) {
|
||||
PERR("pipe lock_state allocation failed");
|
||||
}
|
||||
|
||||
_lock = new (Genode::env()->heap()) Genode::Lock(*_lock_state);
|
||||
if (!_lock) {
|
||||
PERR("pipe lock allocation failed");
|
||||
}
|
||||
} else {
|
||||
|
||||
/* get shared resource pointers from partner */
|
||||
|
||||
_buffer = context(_partner)->buffer();
|
||||
_lock_state = context(_partner)->lock_state();
|
||||
_lock = context(_partner)->lock();
|
||||
_write_avail_sem = context(_partner)->write_avail_sem();
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,13 +157,15 @@ namespace {
|
||||
Plugin_context::~Plugin_context()
|
||||
{
|
||||
if (_partner) {
|
||||
|
||||
/* remove the fd this context belongs to from the partner's context */
|
||||
context(_partner)->set_partner(0);
|
||||
|
||||
} else {
|
||||
|
||||
/* partner fd is already destroyed -> free shared resources */
|
||||
free(_buffer);
|
||||
destroy(Genode::env()->heap(), _lock);
|
||||
destroy(Genode::env()->heap(), _lock_state);
|
||||
destroy(Genode::env()->heap(), _buffer);
|
||||
destroy(Genode::env()->heap(), _write_avail_sem);
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,13 +197,16 @@ namespace {
|
||||
* the sets belongs to this plugin
|
||||
*/
|
||||
for (int libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
||||
if (FD_ISSET(libc_fd, readfds) || FD_ISSET(libc_fd, writefds)
|
||||
|| FD_ISSET(libc_fd, exceptfds)) {
|
||||
|
||||
if (FD_ISSET(libc_fd, readfds) ||
|
||||
FD_ISSET(libc_fd, writefds) ||
|
||||
FD_ISSET(libc_fd, exceptfds)) {
|
||||
|
||||
Libc::File_descriptor *fdo =
|
||||
Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||
if (fdo && (fdo->plugin == this)) {
|
||||
|
||||
if (fdo && (fdo->plugin == this))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -232,26 +225,49 @@ namespace {
|
||||
int Plugin::fcntl(Libc::File_descriptor *pipefdo, int cmd, long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case F_GETFL:
|
||||
if (is_write_end(pipefdo))
|
||||
return O_WRONLY;
|
||||
else
|
||||
return O_RDONLY;
|
||||
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;
|
||||
|
||||
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:
|
||||
PERR("fcntl(): command %d arg %ld not supported - pipe",
|
||||
cmd, arg);
|
||||
return -1;
|
||||
|
||||
case F_GETFL:
|
||||
|
||||
if (is_write_end(pipefdo))
|
||||
return O_WRONLY;
|
||||
else
|
||||
return O_RDONLY;
|
||||
|
||||
case F_SETFL:
|
||||
{
|
||||
constexpr long supported_flags = O_NONBLOCK;
|
||||
|
||||
context(pipefdo)->set_nonblock(arg & O_NONBLOCK);
|
||||
|
||||
if ((arg & ~supported_flags) == 0)
|
||||
break;
|
||||
|
||||
/* unsupported flags present */
|
||||
|
||||
PERR("%s: command F_SETFL arg %ld not fully supported",
|
||||
__PRETTY_FUNCTION__, arg);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
PERR("%s: command %d arg %ld not supported", __PRETTY_FUNCTION__, cmd, arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -271,21 +287,40 @@ namespace {
|
||||
{
|
||||
if (!is_read_end(fdo)) {
|
||||
PERR("Cannot read from write end of pipe.");
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
context(fdo)->set_lock_state(Genode::Lock::LOCKED);
|
||||
context(fdo)->lock()->lock();
|
||||
if (!context(fdo)->partner())
|
||||
return 0;
|
||||
|
||||
if ((count > 0) && buf)
|
||||
Genode::memcpy(buf, context(fdo)->buffer(),
|
||||
Genode::min(count, (::size_t)PIPE_BUF_SIZE));
|
||||
if (context(fdo)->nonblock() && context(fdo)->buffer()->empty()) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* blocking mode, read at least one byte */
|
||||
|
||||
ssize_t num_bytes_read = 0;
|
||||
|
||||
do {
|
||||
|
||||
((unsigned char*)buf)[num_bytes_read] =
|
||||
context(fdo)->buffer()->get();
|
||||
|
||||
num_bytes_read++;
|
||||
|
||||
context(fdo)->write_avail_sem()->up();
|
||||
|
||||
} while ((num_bytes_read < (ssize_t)count) &&
|
||||
!context(fdo)->buffer()->empty());
|
||||
|
||||
return num_bytes_read;
|
||||
}
|
||||
|
||||
|
||||
/* no support for execptfds right now */
|
||||
|
||||
int Plugin::select(int nfds,
|
||||
fd_set *readfds,
|
||||
fd_set *writefds,
|
||||
@ -303,6 +338,7 @@ namespace {
|
||||
FD_ZERO(exceptfds);
|
||||
|
||||
for (int libc_fd = 0; libc_fd < nfds; libc_fd++) {
|
||||
|
||||
fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd);
|
||||
|
||||
/* handle only libc_fds that belong to this plugin */
|
||||
@ -310,14 +346,15 @@ namespace {
|
||||
continue;
|
||||
|
||||
if (FD_ISSET(libc_fd, &in_readfds) &&
|
||||
(is_read_end(fdo)) &&
|
||||
(*context(fdo)->lock_state() == Genode::Lock::UNLOCKED)) {
|
||||
is_read_end(fdo) &&
|
||||
!context(fdo)->buffer()->empty()) {
|
||||
FD_SET(libc_fd, readfds);
|
||||
nready++;
|
||||
}
|
||||
|
||||
/* currently the write end is always ready for writing */
|
||||
if (FD_ISSET(libc_fd, &in_writefds)) {
|
||||
if (FD_ISSET(libc_fd, &in_writefds) &&
|
||||
is_write_end(fdo) &&
|
||||
(context(fdo)->buffer()->avail_capacity() > 0)) {
|
||||
FD_SET(libc_fd, writefds);
|
||||
nready++;
|
||||
}
|
||||
@ -331,33 +368,43 @@ namespace {
|
||||
{
|
||||
if (!is_write_end(fdo)) {
|
||||
PERR("Cannot write into read end of pipe.");
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently each 'write()' overwrites the previous
|
||||
* content of the pipe buffer.
|
||||
*/
|
||||
if ((count > 0) && buf)
|
||||
Genode::memcpy(context(fdo)->buffer(), buf,
|
||||
Genode::min(count, (::size_t)PIPE_BUF_SIZE));
|
||||
if (context(fdo)->nonblock() &&
|
||||
(context(fdo)->buffer()->avail_capacity() == 0)) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
context(fdo)->set_lock_state(Genode::Lock::UNLOCKED);
|
||||
context(fdo)->lock()->unlock();
|
||||
::size_t num_bytes_written = 0;
|
||||
while (num_bytes_written < count) {
|
||||
|
||||
if (context(fdo)->buffer()->avail_capacity() == 0) {
|
||||
|
||||
if (context(fdo)->nonblock())
|
||||
return num_bytes_written;
|
||||
|
||||
if (libc_select_notify)
|
||||
libc_select_notify();
|
||||
}
|
||||
|
||||
context(fdo)->write_avail_sem()->down();
|
||||
|
||||
context(fdo)->buffer()->add(((unsigned char*)buf)[num_bytes_written]);
|
||||
num_bytes_written++;
|
||||
}
|
||||
|
||||
if (libc_select_notify)
|
||||
libc_select_notify();
|
||||
|
||||
return 0;
|
||||
return num_bytes_written;
|
||||
}
|
||||
|
||||
|
||||
} /* unnamed namespace */
|
||||
|
||||
|
||||
void __attribute__((constructor)) init_libc_lock_pipe()
|
||||
{
|
||||
PDBG("init_libc_lock_pipe()\n");
|
||||
static Plugin plugin;
|
||||
}
|
||||
|
||||
|
||||
void __attribute__((constructor)) init_libc_pipe()
|
||||
{
|
||||
static Libc_pipe::Plugin plugin;
|
||||
}
|
89
repos/libports/src/test/libc_pipe/main.cc
Normal file
89
repos/libports/src/test/libc_pipe/main.cc
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* \brief libc_pipe test
|
||||
* \author Christian Prochaska
|
||||
* \date 2016-04-24
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
|
||||
/* libc includes */
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
enum { BUF_SIZE = 16*1024 };
|
||||
static char buf[BUF_SIZE];
|
||||
|
||||
static int pipefd[2];
|
||||
|
||||
static volatile bool reader_finished = false;
|
||||
|
||||
void *read_pipe(void *arg)
|
||||
{
|
||||
static char read_buf[BUF_SIZE];
|
||||
|
||||
ssize_t num_bytes_read = 0;
|
||||
|
||||
while (num_bytes_read < BUF_SIZE) {
|
||||
|
||||
ssize_t res = read(pipefd[0],
|
||||
&read_buf[num_bytes_read],
|
||||
BUF_SIZE - num_bytes_read);
|
||||
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Error reading from pipe\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
num_bytes_read += res;
|
||||
}
|
||||
|
||||
if ((read_buf[0] != buf[0]) ||
|
||||
(read_buf[BUF_SIZE - 1] != buf[BUF_SIZE - 1])) {
|
||||
fprintf(stderr, "Error: data mismatch\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
reader_finished = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/* test values */
|
||||
buf[0] = 1;
|
||||
buf[BUF_SIZE - 1] = 255;
|
||||
|
||||
int res = pipe(pipefd);
|
||||
if (res != 0) {
|
||||
fprintf(stderr, "Error creating pipe\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, 0, read_pipe, 0);
|
||||
|
||||
ssize_t bytes_written = write(pipefd[1], buf, BUF_SIZE);
|
||||
|
||||
if (bytes_written != BUF_SIZE) {
|
||||
fprintf(stderr, "Error writing to pipe");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* pthread_join() is not implemented at this time */
|
||||
while (!reader_finished) { }
|
||||
|
||||
printf("--- test finished ---\n");
|
||||
|
||||
return 0;
|
||||
}
|
3
repos/libports/src/test/libc_pipe/target.mk
Normal file
3
repos/libports/src/test/libc_pipe/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
TARGET = test-libc_pipe
|
||||
LIBS = libc libc_pipe pthread
|
||||
SRC_CC = main.cc
|
@ -228,7 +228,7 @@ 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_log.lib.so' (for printing the LOG
|
||||
output of GDB monitor to core's LOG service), 'libc_terminal.lib.so' (to
|
||||
connect with GDB), and 'libc_lock_pipe.lib.so' (used for synchronizing threads
|
||||
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
|
||||
stack) is needed as well.
|
||||
|
||||
|
@ -107,7 +107,7 @@ append boot_modules {
|
||||
libc.lib.so libm.lib.so lwip.lib.so
|
||||
zlib.lib.so libpng.lib.so jpeg.lib.so libssl.lib.so libcrypto.lib.so
|
||||
freetype.lib.so
|
||||
libc_lock_pipe.lib.so
|
||||
libc_pipe.lib.so
|
||||
stdcxx.lib.so
|
||||
nitpicker_plugin.tar
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor
|
||||
nitpicker pointer scout
|
||||
|
@ -88,7 +88,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor test-gdb_monitor
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor test-gdb_monitor
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer
|
||||
ld.lib.so libc.lib.so libc_log.lib.so libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
ld.lib.so libc.lib.so libc_log.lib.so libc_pipe.lib.so libc_terminal.lib.so
|
||||
uart_drv
|
||||
gdb_monitor test-gdb_monitor_target_config
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ install_config $config
|
||||
set boot_modules {
|
||||
core init timer ld.lib.so noux terminal terminal_crosslink
|
||||
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so expat.lib.so
|
||||
libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
libc_pipe.lib.so libc_terminal.lib.so
|
||||
gdb_monitor test-gdb_monitor
|
||||
gdb.tar test-gdb_monitor.tar test-gdb_monitor-src.tar
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ exec cp ${genode_dir}/repos/os/src/app/cli_monitor/gdb_command_config bin
|
||||
set boot_modules {
|
||||
core init timer ld.lib.so noux terminal_mux terminal_crosslink
|
||||
libc.lib.so libm.lib.so libc_noux.lib.so ncurses.lib.so expat.lib.so
|
||||
libc_lock_pipe.lib.so libc_log.lib.so libc_terminal.lib.so
|
||||
libc_pipe.lib.so libc_log.lib.so libc_terminal.lib.so
|
||||
cli_monitor gdb_monitor terminal_log gdb.tar
|
||||
gdb_command_config
|
||||
gdb_target.tar
|
||||
|
@ -159,7 +159,7 @@ install_config $config
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core init timer tcp_terminal nic_bridge
|
||||
ld.lib.so noux_net libc.lib.so libm.lib.so libc_lock_pipe.lib.so
|
||||
ld.lib.so noux_net libc.lib.so libm.lib.so libc_pipe.lib.so
|
||||
libc_resolv.lib.so libc_noux.lib.so lwip.lib.so noux_netcat.tar
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ lappend_if [have_spec linux] boot_modules fb_sdl
|
||||
lappend_if [have_spec x86] boot_modules rtc_drv
|
||||
|
||||
append boot_modules {
|
||||
ld.lib.so libc.lib.so libm.lib.so pthread.lib.so libc_lock_pipe.lib.so
|
||||
ld.lib.so libc.lib.so libm.lib.so pthread.lib.so libc_pipe.lib.so
|
||||
libc_terminal.lib.so libiconv.lib.so stdcxx.lib.so
|
||||
qemu-usb.lib.so
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ append boot_modules {
|
||||
core init timer
|
||||
part_blk ahci_drv fs_rom
|
||||
ld.lib.so libc.lib.so libm.lib.so pthread.lib.so
|
||||
libc_lock_pipe.lib.so libc_terminal.lib.so
|
||||
libc_pipe.lib.so libc_terminal.lib.so
|
||||
libiconv.lib.so stdcxx.lib.so
|
||||
rump.lib.so rump_fs.lib.so rump_fs
|
||||
virtualbox qemu-usb.lib.so
|
||||
|
@ -10,7 +10,7 @@ INC_DIR += $(GDB_CONTRIB_DIR)/include \
|
||||
$(PRG_DIR)/gdbserver \
|
||||
$(PRG_DIR)
|
||||
|
||||
LIBS = libc libc_terminal libc_lock_pipe \
|
||||
LIBS = libc libc_terminal libc_pipe \
|
||||
gdbserver_platform gdbserver_libc_support
|
||||
|
||||
SRC_C = event-loop.c \
|
||||
|
@ -1,6 +1,6 @@
|
||||
TARGET = openvpn
|
||||
|
||||
LIBS += libc libc_lock_pipe libc_lwip_nic_dhcp \
|
||||
LIBS += libc libc_pipe libc_lwip_nic_dhcp \
|
||||
libcrypto libssl config_args server
|
||||
|
||||
OPENVPN_PORT_DIR := $(call select_from_ports,openvpn)
|
||||
|
@ -23,7 +23,7 @@ LIBS += virtualbox-bios virtualbox-recompiler virtualbox-runtime \
|
||||
virtualbox-storage virtualbox-zlib virtualbox-liblzf \
|
||||
virtualbox-hwaccl virtualbox-xml virtualbox-main
|
||||
|
||||
LIBS += pthread libc_terminal libc_lock_pipe libiconv
|
||||
LIBS += pthread libc_terminal libc_pipe libiconv
|
||||
|
||||
LIBS += qemu-usb
|
||||
|
||||
|
@ -8,6 +8,7 @@ tar_rom
|
||||
noux
|
||||
noux_net_netcat
|
||||
libc_ffat
|
||||
libc_pipe
|
||||
libc_vfs
|
||||
libc_vfs_ram
|
||||
libc_vfs_fs
|
||||
|
Loading…
x
Reference in New Issue
Block a user