genode/libports/src/lib/python/libc_plugin.cc
2012-01-03 15:35:05 +01:00

110 lines
2.3 KiB
C++

/**
* \brief Libc back-end for Python
* \author Sebastian Sumpf
* \date 2010-02-17
*/
/*
* Copyright (C) 2010-2012 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.
*/
#include <base/env.h>
#include <base/printf.h>
#include <rom_session/connection.h>
#include <dataspace/client.h>
#include <libc-plugin/fd_alloc.h>
namespace {
class Plugin_context : public Libc::Plugin_context
{
private:
Genode::Dataspace_capability _ds_cap;
::size_t _ds_size;
::off_t _offs;
Genode::addr_t _base;
public:
Plugin_context(Genode::Dataspace_capability ds_cap)
: _ds_cap(ds_cap), _offs(0)
{
_ds_size = Genode::Dataspace_client(ds_cap).size();
_base = Genode::env()->rm_session()->attach(ds_cap);
}
ssize_t read(void *buf, ::size_t count)
{
if (_offs >= (::off_t)_ds_size)
return -1;
if (_offs + count > _ds_size)
count = _ds_size - _offs;
Genode::memcpy(buf, (void *)(_base + _offs), count);
_offs += count;
return count;
}
};
static inline Plugin_context *context(Libc::File_descriptor *fd)
{
return static_cast<Plugin_context *>(fd->context);
}
struct Plugin : Libc::Plugin
{
Plugin()
{
PDBG("Python libc plugin");
}
bool supports_open(const char*, int) { return true; }
Libc::File_descriptor *open(const char *pathname, int flags)
{
using namespace Genode;
Dataspace_capability ds_cap;
const char *_pathname = (pathname[0] == '/') ? pathname + 1 : pathname;
try {
/* Open the file dataspace */
Rom_connection rom(_pathname);
rom.on_destruction(Rom_connection::KEEP_OPEN);
ds_cap = rom.dataspace();
}
catch (...) {
PERR("could not open file: %s", pathname);
return 0;
}
Plugin_context *context = new (env()->heap()) Plugin_context(ds_cap);
return Libc::file_descriptor_allocator()->alloc(this, context);
}
ssize_t read(Libc::File_descriptor *fdo, void *buf, ::size_t count)
{
return context(fdo)->read(buf, count);
}
ssize_t _read(Libc::File_descriptor *fdo, void *buf, ::size_t count)
{
return read(fdo, buf, count);
}
};
}
void create_libc_plugin()
{
static Plugin plugin;
}