diff --git a/repos/dde_linux/src/lib/libc_lxip/plugin.cc b/repos/dde_linux/src/lib/libc_lxip/plugin.cc deleted file mode 100644 index 3676f6332d..0000000000 --- a/repos/dde_linux/src/lib/libc_lxip/plugin.cc +++ /dev/null @@ -1,749 +0,0 @@ -/* - * \brief Lxip plugin implementation - * \author Sebastian Sumpf - * \author Christian Helmuth - * \date 2013-09-04 - */ - -/* - * Copyright (C) 2010-2017 Genode Labs GmbH - * - * This file is distributed under the terms of the GNU General Public License - * version 2. - */ - -/* Libc includes */ -#include -#include -#include -#include - -/* Genode includes */ -#include -#include -#include -#include - -/* Libc plugin includes */ -#include -#include - -/* Lxip includes */ -#include - - -/************************** - ** Linux family numbers ** - **************************/ - -enum { - LINUX_AF_INET = 2 -}; - - -/********************** - ** Plugin interface ** - **********************/ - -namespace { - -class Plugin_context : public Libc::Plugin_context -{ - private: - - Lxip::Handle _handle; - - public: - - /** - * Constructor - */ - Plugin_context(Lxip::Handle handle) : _handle(handle) { } - - Lxip::Handle handle() const { return _handle; } - - void non_block(bool nb) { _handle.non_block = nb; } -}; - - -static inline Plugin_context * context(Libc::File_descriptor *fd) -{ - return static_cast(fd->context); -} - - -struct Plugin : Libc::Plugin -{ - - /** - * Interface to LXIP stack - */ - struct Socketcall - { - Genode::Heap heap; - Lxip::Socketcall &socketcall; - - Socketcall(Genode::Env &env, - char const *ip_addr_str, - char const *netmask_str, - char const *gateway_str) - : heap(env.ram(), env.rm()), - socketcall(Lxip::init(env, ip_addr_str, netmask_str, - gateway_str, gateway_str)) - { } - }; - - Genode::Constructible socketconstruct; - - Lxip::Socketcall &socketcall() - { - return socketconstruct->socketcall; - } - - Genode::Heap &heap() - { - return socketconstruct->heap; - } - - /** - * Constructor - */ - Plugin(); - - void init(Genode::Env &env) override; - - bool supports_select(int nfds, - fd_set *readfds, - fd_set *writefds, - fd_set *exceptfds, - struct timeval *timeout); - bool supports_socket(int domain, int type, int protocol); - - Libc::File_descriptor *accept(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, - socklen_t *addrlen); - int bind(Libc::File_descriptor *sockfdo, - const struct sockaddr *addr, - socklen_t addrlen); - int close(Libc::File_descriptor *fdo); - int connect(Libc::File_descriptor *sockfdo, - const struct sockaddr *addr, - socklen_t addrlen); - int fcntl(Libc::File_descriptor *sockfdo, int cmd, long val); - int getpeername(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, - socklen_t *addrlen); - int getsockname(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, - socklen_t *addrlen); - int getsockopt(Libc::File_descriptor *sockfdo, int level, - int optname, void *optval, - socklen_t *optlen); - int ioctl(Libc::File_descriptor *sockfdo, int request, char *argp); - int listen(Libc::File_descriptor *sockfdo, int backlog); - ssize_t read(Libc::File_descriptor *fdo, void *buf, ::size_t count); - int shutdown(Libc::File_descriptor *fdo, int); - int select(int nfds, fd_set *readfds, fd_set *writefds, - fd_set *exceptfds, struct timeval *timeout); - ssize_t send(Libc::File_descriptor *, const void *buf, ::size_t len, int flags); - ssize_t sendto(Libc::File_descriptor *, const void *buf, - ::size_t len, int flags, - const struct sockaddr *dest_addr, - socklen_t addrlen); - ssize_t recv(Libc::File_descriptor *, void *buf, ::size_t len, int flags); - ssize_t recvfrom(Libc::File_descriptor *, void *buf, ::size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen); - int setsockopt(Libc::File_descriptor *sockfdo, int level, - int optname, const void *optval, - socklen_t optlen); - Libc::File_descriptor *socket(int domain, int type, int protocol); - ssize_t write(Libc::File_descriptor *fdo, const void *buf, ::size_t count); - - int linux_family(const struct sockaddr *addr, socklen_t addrlen); - int bsd_family(struct sockaddr *addr); - int retrieve_and_clear_fds(int nfds, struct fd_set *fds, struct fd_set *in); - int translate_msg_flags(int bsd_flags); - int translate_ops_linux(int optname); - - ::ssize_t getdirentries(Libc::File_descriptor *fd, char *buf, ::size_t nbytes, - ::off_t *basep) - { - Genode::error(__FILE__, ":", __LINE__, " ", __func__, "not implemented"); - return 0UL; - } - - void *mmap(void *addr, ::size_t length, int prot, int flags, - Libc::File_descriptor *, ::off_t offset) - { - Genode::error(__FILE__, ":", __LINE__, " ", __func__, "not implemented"); - return nullptr; - } - - int msync(void *addr, ::size_t len, int flags) - { - Genode::error(__FILE__, ":", __LINE__, " ", __func__, "not implemented"); - return 0; - } -}; - - -Plugin::Plugin() -{ - Genode::log("using the lxip libc plugin"); -} - - -void Plugin::init(Genode::Env &env) -{ - - Genode::Attached_rom_dataspace config { env, "config"} ; - - try { - Genode::Xml_node libc_node = config.xml().sub_node("libc"); - - typedef Genode::String<20> Ip_addr; - - Ip_addr const ip_addr = libc_node.attribute_value("ip_addr", Ip_addr()); - Ip_addr const netmask = libc_node.attribute_value("netmask", Ip_addr()); - Ip_addr const gateway = libc_node.attribute_value("gateway", Ip_addr()); - - /* either none or all 3 interface attributes must exist */ - if (ip_addr.valid() || netmask.valid() || gateway.valid()) { - - if (!ip_addr.valid()) { - Genode::error("missing \"ip_addr\" attribute. Ignoring network interface config."); - throw Genode::Xml_node::Nonexistent_attribute(); - } - if (!netmask.valid()) { - Genode::error("missing \"netmask\" attribute. Ignoring network interface config."); - throw Genode::Xml_node::Nonexistent_attribute(); - } - if (!gateway.valid()) { - Genode::error("missing \"gateway\" attribute. Ignoring network interface config."); - throw Genode::Xml_node::Nonexistent_attribute(); - } - } else - throw -1; - - Genode::log("static network interface: ", - "ip_addr=", ip_addr, " " - "netmask=", netmask, " " - "gateway=", gateway); - - socketconstruct.construct(env, ip_addr.string(), - netmask.string(), - gateway.string()); - } - catch (...) { - Genode::log("Using DHCP for interface configuration."); - } - - socketconstruct.construct(env, "", "", ""); -}; - -/* TODO shameful copied from lwip... generalize this */ -bool 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 marked set in one of - * the sets belongs to this plugin. - */ - - Libc::File_descriptor *fdo; - 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)) { - fdo = Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd); - if (fdo && (fdo->plugin == this)) { - return true; - } - } - } - return false; -} - - -bool Plugin::supports_socket(int domain, int type, int) -{ - if (domain == AF_INET && (type == SOCK_STREAM || type == SOCK_DGRAM)) - return true; - - return false; -} - - -Libc::File_descriptor *Plugin::accept(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, socklen_t *addrlen) -{ - Lxip::Handle handle; - - handle = socketcall().accept(context(sockfdo)->handle(), (void *)addr, addrlen); - if (!handle.socket) - return 0; - - if (addr) { - addr->sa_family = bsd_family(addr); - addr->sa_len = *addrlen; - } - - Plugin_context *context = new (heap()) Plugin_context(handle); - Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context); - return fd; -} - - -int Plugin::bind(Libc::File_descriptor *sockfdo, const struct sockaddr *addr, - socklen_t addrlen) -{ - int family; - - if (!(family = linux_family(addr, addrlen))) { - errno = ENOTSUP; - return -1; - } - - errno = -socketcall().bind(context(sockfdo)->handle(), family, (void*)addr); - - return errno > 0 ? -1 : 0; -} - - -int Plugin::close(Libc::File_descriptor *sockfdo) -{ - socketcall().close(context(sockfdo)->handle()); - - if (context(sockfdo)) - Genode::destroy(heap(), context(sockfdo)); - - Libc::file_descriptor_allocator()->free(sockfdo); - - return 0; -} - - -int Plugin::connect(Libc::File_descriptor *sockfdo, - const struct sockaddr *addr, - socklen_t addrlen) -{ - int family; - - if (!(family = linux_family(addr, addrlen))) { - errno = ENOTSUP; - return -1; - } - - errno = -socketcall().connect(context(sockfdo)->handle(), family, (void *)addr); - return errno > 0 ? -1 : 0; -} - - -int Plugin::fcntl(Libc::File_descriptor *sockfdo, int cmd, long val) -{ - - switch (cmd) { - - case F_GETFL: - - return context(sockfdo)->handle().non_block ? O_NONBLOCK : 0; - - case F_SETFL: - - context(sockfdo)->non_block(!!(val & O_NONBLOCK)); - return 0; - - default: - - Genode::error("unsupported fcntl() request: ", cmd); - errno = ENOSYS; - return -1; - } -} - - -int Plugin::getpeername(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, - socklen_t *addrlen) -{ - if (!addr) { - errno = EFAULT; - return -1; - } - - errno = -socketcall().getpeername(context(sockfdo)->handle(), (void *)addr, addrlen); - - addr->sa_family = bsd_family(addr); - addr->sa_len = *addrlen; - - return errno > 0 ? -1 : 0; -} - - -int Plugin::getsockname(Libc::File_descriptor *sockfdo, - struct sockaddr *addr, - socklen_t *addrlen) -{ - if (!addr) { - errno = EFAULT; - return -1; - } - - errno = -socketcall().getsockname(context(sockfdo)->handle(), (void *)addr, addrlen); - - addr->sa_family = bsd_family(addr); - addr->sa_len = *addrlen; - - return errno > 0 ? -1 : 0; -} - - -int Plugin::getsockopt(Libc::File_descriptor *sockfdo, int level, - int optname, void *optval, socklen_t *optlen) -{ - if (level != SOL_SOCKET) { - Genode::error(__func__, ": Unsupported level ", level, ", we only support SOL_SOCKET for now"); - errno = EBADF; - return -1; - } - - optname = translate_ops_linux(optname); - if (optname < 0) { - errno = ENOPROTOOPT; - return -1; - } - - return socketcall().getsockopt(context(sockfdo)->handle(), Lxip::LINUX_SOL_SOCKET, - optname, optval, (int *)optlen); -} - - -int Plugin::ioctl(Libc::File_descriptor *sockfdo, int request, char *argp) -{ - switch (request) { - - case FIONBIO: - - context(sockfdo)->non_block(!!*argp); - return 0; - - case FIONREAD: - - errno = -socketcall().ioctl(context(sockfdo)->handle(), Lxip::LINUX_FIONREAD, - argp); - return errno > 0 ? -1 : 0; - - default: - - Genode::error("unsupported ioctl() request"); - errno = ENOSYS; - return -1; - } -} - - -int Plugin::listen(Libc::File_descriptor *sockfdo, int backlog) -{ - errno = -socketcall().listen(context(sockfdo)->handle(), backlog); - return errno > 0 ? -1 : 0; -} - - -int Plugin::shutdown(Libc::File_descriptor *sockfdo, int how) -{ - errno = -socketcall().shutdown(context(sockfdo)->handle(), how); - return errno > 0 ? -1 : 0; -} - - -/* TODO: Support timeouts */ -/* XXX: Check blocking and non-blocking semantics */ -int Plugin::select(int nfds, - fd_set *readfds, - fd_set *writefds, - fd_set *exceptfds, - struct timeval *timeout) -{ - Libc::File_descriptor *sockfdo; - struct fd_set fds[3]; - int bits = 0; - - if (nfds < 0) { - errno = EINVAL; - return -1; - } - - for (int i = 0; i < 3; i++) - FD_ZERO(&fds[i]); - - bool block = false; - for (int fd = 0; fd <= nfds; fd++) { - - if (fd == nfds && !bits) { - fd = -1; - block = true; - continue; - } - - int set = 0; - set |= FD_ISSET(fd, readfds); - set |= FD_ISSET(fd, writefds); - set |= FD_ISSET(fd, exceptfds); - - if (!set) - continue; - - sockfdo = Libc::file_descriptor_allocator()->find_by_libc_fd(fd); - /* handle only libc_fds that belong to this plugin */ - if (!sockfdo || (sockfdo->plugin != this)) - continue; - - /* call IP stack blocking/non-blocking */ - int mask = socketcall().poll(context(sockfdo)->handle(), block); - - if (mask) - block = false; - - if (readfds && (mask & Lxip::POLLIN) && FD_ISSET(fd, readfds) && ++bits) - FD_SET(fd, &fds[0]); - if (writefds && (mask & Lxip::POLLOUT) && FD_ISSET(fd, writefds) && ++bits) - FD_SET(fd, &fds[1]); - if (exceptfds && (mask & Lxip::POLLEX) && FD_ISSET(fd, exceptfds) && ++bits) - FD_SET(fd, &fds[2]); - } - - if (readfds) *readfds = fds[0]; - if (writefds) *writefds = fds[1]; - if (exceptfds) *exceptfds = fds[2]; - - return bits; -} - - -ssize_t Plugin::read(Libc::File_descriptor *fdo, void *buf, ::size_t count) -{ - return recv(fdo, buf, count, 0); -} - - -ssize_t Plugin::recv(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags) -{ - return recvfrom(sockfdo, buf, len, flags, 0, 0); -} - - -ssize_t Plugin::recvfrom(Libc::File_descriptor *sockfdo, void *buf, ::size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) -{ - int family = 0; - - if (src_addr && addrlen && !(family = linux_family(src_addr, *addrlen))) { - errno = ENOTSUP; - return -1; - } - - int recv = socketcall().recv(context(sockfdo)->handle(), buf, len, translate_msg_flags(flags), - family, (void *)src_addr, addrlen); - - if (recv < 0) { - errno = -recv; - return errno == EAGAIN ? 0 : -1; - } - - if (src_addr) { - src_addr->sa_family = bsd_family(src_addr); - src_addr->sa_len = *addrlen; - } - - return recv; -} - - -ssize_t Plugin::send(Libc::File_descriptor *sockfdo, const void *buf, ::size_t len, int flags) -{ - return sendto(sockfdo, buf, len, flags, 0, 0); -} - - -ssize_t Plugin::sendto(Libc::File_descriptor *sockfdo, const void *buf, - ::size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - int family = 0; - - if (dest_addr && addrlen && !(family = linux_family(dest_addr, addrlen))) { - errno = ENOTSUP; - return -1; - } - - int send = socketcall().send(context(sockfdo)->handle(), buf, len, translate_msg_flags(flags), - family, (void *)dest_addr); - if (send < 0) - errno = -send; - - return send < 0 ? -1 : send; -} - - -int Plugin::setsockopt(Libc::File_descriptor *sockfdo, int level, - int optname, const void *optval, - socklen_t optlen) -{ - if (level != SOL_SOCKET) { - Genode::error(__func__, ": Unsupported level ", level, ", we only support SOL_SOCKET for now"); - errno = EBADF; - return -1; - } - - optname = translate_ops_linux(optname); - if (optname < 0) { - errno = ENOPROTOOPT; - return -1; - } - - return socketcall().setsockopt(context(sockfdo)->handle(), Lxip::LINUX_SOL_SOCKET, - optname, optval, optlen); -} - - -Libc::File_descriptor *Plugin::socket(int domain, int type, int protocol) -{ - using namespace Lxip; - Handle handle = socketcall().socket(type == SOCK_STREAM ? TYPE_STREAM : TYPE_DGRAM); - - if (!handle.socket) { - errno = EBADF; - return 0; - } - - Plugin_context *context = new (heap()) Plugin_context(handle); - Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context); - return fd; -} - - -ssize_t Plugin::write(Libc::File_descriptor *fdo, const void *buf, ::size_t count) -{ - return send(fdo, buf, count, 0); -} - - -int Plugin::linux_family(const struct sockaddr *addr, socklen_t addrlen) -{ - switch (addr->sa_family) - { - case AF_INET: - - return LINUX_AF_INET; - - default: - - Genode::error("unsupported socket BSD protocol ", addr->sa_family); - return 0; - } - - return 0; -} - - -int Plugin::bsd_family(struct sockaddr *addr) -{ - /* - * Note: Since in Linux 'sa_family' is 16 bit while in BSD it is 8 bit (both - * little endian), 'sa_len' will contain the actual family (or lower order - * bits) of Linux - */ - addr->sa_family = addr->sa_len; - - switch (addr->sa_family) - { - case LINUX_AF_INET: return AF_INET; - - default: - - Genode::error("unsupported socket Linux protocol ", addr->sa_family); - return 0; - } -} - - -int Plugin::translate_msg_flags(int bsd_flags) -{ - using namespace Lxip; - int f = 0; - - if (bsd_flags & MSG_OOB) f |= LINUX_MSG_OOB; - if (bsd_flags & MSG_PEEK) f |= LINUX_MSG_PEEK; - if (bsd_flags & MSG_DONTROUTE) f |= LINUX_MSG_DONTROUTE; - if (bsd_flags & MSG_EOR) f |= LINUX_MSG_EOR; - if (bsd_flags & MSG_TRUNC) f |= LINUX_MSG_TRUNC; - if (bsd_flags & MSG_CTRUNC) f |= LINUX_MSG_CTRUNC; - if (bsd_flags & MSG_WAITALL) f |= LINUX_MSG_WAITALL; - if (bsd_flags & MSG_NOTIFICATION) Genode::warning("MSG_NOTIFICATION ignored"); - if (bsd_flags & MSG_DONTWAIT) f |= LINUX_MSG_DONTWAIT; - if (bsd_flags & MSG_EOF) f |= LINUX_MSG_EOF; - if (bsd_flags & MSG_NBIO) Genode::warning("MSG_NBIO ignored"); - if (bsd_flags & MSG_NOSIGNAL) f |= LINUX_MSG_NOSIGNAL; - if (bsd_flags & MSG_COMPAT) f |= LINUX_MSG_COMPAT; - - return f; -} - - -/* index is Linux, value is BSD */ -static int sockopts[] -{ - 0, /* 0 */ - SO_DEBUG, - SO_REUSEADDR, - SO_TYPE, - SO_ERROR, - SO_DONTROUTE, /* 5 */ - SO_BROADCAST, - SO_SNDBUF, - SO_RCVBUF, - SO_KEEPALIVE, - SO_OOBINLINE, /* 10 */ - /* SO_NOCHECK */ 0, - /* SO_PRIORITY */ 0, - SO_LINGER, - /* SO_BSDCOMPAT */ 0, - SO_REUSEPORT, /* 15 */ - /* SO_PASSCRED */ 0, - /* SO_PEERCRED */ 0, - SO_RCVLOWAT, - SO_SNDLOWAT, - SO_RCVTIMEO, /* 20 */ - SO_SNDTIMEO, - 0, - 0, - 0, - 0, /* 25 */ - 0, - 0, - SO_PEERLABEL, - SO_TIMESTAMP, - SO_ACCEPTCONN, /* 30 */ - -1 -}; - - -int Plugin::translate_ops_linux(int optname) -{ - for (int i = 0; sockopts[i] > -1; i++) - if (sockopts[i] == optname) - return i; - - Genode::error("unsupported sockopt ", optname); - return -1; -} - -} /* unnamed namespace */ - - -void __attribute__((constructor)) init_lxip_plugin() -{ - static Plugin lxip_plugin; -}