diff --git a/repos/libports/lib/mk/libc.mk b/repos/libports/lib/mk/libc.mk index 0d5b8aa90c..26ed6881af 100644 --- a/repos/libports/lib/mk/libc.mk +++ b/repos/libports/lib/mk/libc.mk @@ -14,7 +14,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \ gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \ plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \ libc_mem_alloc.cc pread_pwrite.cc readv_writev.cc poll.cc \ - libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc + libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc socket_operations.cc INC_DIR += $(REP_DIR)/src/lib/libc diff --git a/repos/libports/src/lib/libc/file_operations.cc b/repos/libports/src/lib/libc/file_operations.cc index cd3ec94670..8b36671f81 100644 --- a/repos/libports/src/lib/libc/file_operations.cc +++ b/repos/libports/src/lib/libc/file_operations.cc @@ -13,13 +13,11 @@ */ /* Genode includes */ -#include #include #include #include /* Genode-specific libc interfaces */ -#include #include #include @@ -33,6 +31,7 @@ #include /* libc-internal includes */ +#include "libc_file.h" #include "libc_mem_alloc.h" #include "libc_mmap_registry.h" @@ -48,9 +47,6 @@ static bool const verbose = false; #define PDBGV(...) if (verbose) PDBG(__VA_ARGS__) -enum { INVALID_FD = -1 }; - - Libc::Mmap_registry *Libc::mmap_registry() { static Libc::Mmap_registry registry; @@ -62,54 +58,6 @@ Libc::Mmap_registry *Libc::mmap_registry() ** Utilities ** ***************/ -/** - * Find plugin responsible for the specified libc file descriptor - * - * \param func_name function name of the caller for printing an error message - */ -inline File_descriptor *libc_fd_to_fd(int libc_fd, const char *func_name) -{ - File_descriptor *fd = file_descriptor_allocator()->find_by_libc_fd(libc_fd); - if (!fd) - PERR("no plugin found for %s(%d)", func_name, libc_fd); - return fd; -} - - -/** - * Generate body of wrapper function taking a file descriptor as first argument - */ -#define FD_FUNC_WRAPPER_GENERIC(result_stm, result_err_val, func_name, libc_fd, ...) \ -{ \ - File_descriptor *fd = libc_fd_to_fd(libc_fd, #func_name); \ - if (!fd || !fd->plugin) { \ - errno = EBADF; \ - result_stm result_err_val; \ - } else \ - result_stm fd->plugin->func_name(fd, ##__VA_ARGS__ ); \ -} - -#define FD_FUNC_WRAPPER(func_name, libc_fd, ...) \ - FD_FUNC_WRAPPER_GENERIC(return, INVALID_FD, func_name, libc_fd, ##__VA_ARGS__ ) - -/** - * Generate body of wrapper function taking a path name as first argument - */ -#define FNAME_FUNC_WRAPPER_GENERIC(result_stm, func_name, path, ...) \ -{ \ - Plugin *plugin = plugin_registry()->get_plugin_for_##func_name(path, ##__VA_ARGS__); \ - if (!plugin) { \ - PERR("no plugin found for %s(\"%s\")", #func_name, path); \ - errno = ENOSYS; \ - result_stm -1; \ - } else \ - result_stm plugin->func_name(path, ##__VA_ARGS__); \ -} - -#define FNAME_FUNC_WRAPPER(func_name, path, ...) \ - FNAME_FUNC_WRAPPER_GENERIC(return, func_name, path, ##__VA_ARGS__ ) - - /** * Current working directory */ @@ -266,32 +214,6 @@ static void resolve_symlinks_except_last_element(char const *path, Absolute_path ** Libc functions ** ********************/ -extern "C" int _accept(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) -{ - return accept(libc_fd, addr, addrlen); -} - - -extern "C" int accept(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) -{ - File_descriptor *ret_fd; - FD_FUNC_WRAPPER_GENERIC(ret_fd =, 0, accept, libc_fd, addr, addrlen); - return ret_fd ? ret_fd->libc_fd : INVALID_FD; -} - - -extern "C" int _bind(int libc_fd, const struct sockaddr *addr, - socklen_t addrlen) -{ - return bind(libc_fd, addr, addrlen); -} - - -extern "C" int bind(int libc_fd, const struct sockaddr *addr, - socklen_t addrlen) { - FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen); } - - extern "C" int chdir(const char *path) { struct stat stat_buf; @@ -312,18 +234,6 @@ extern "C" int _close(int libc_fd) { extern "C" int close(int libc_fd) { return _close(libc_fd); } -extern "C" int connect(int libc_fd, const struct sockaddr *addr, - socklen_t addrlen) { - FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen); } - - -extern "C" int _connect(int libc_fd, const struct sockaddr *addr, - socklen_t addrlen) -{ - return connect(libc_fd, addr, addrlen); -} - - extern "C" int _dup(int libc_fd) { File_descriptor *ret_fd; @@ -418,21 +328,6 @@ extern "C" int _fcntl(int libc_fd, int cmd, long arg) { return fcntl(libc_fd, cmd, arg); } -extern "C" void freeaddrinfo(struct addrinfo *res) -{ - Plugin *plugin; - - plugin = plugin_registry()->get_plugin_for_freeaddrinfo(res); - - if (!plugin) { - PERR("no plugin found for freeaddrinfo()"); - return; - } - - plugin->freeaddrinfo(res); -} - - extern "C" int _fstat(int libc_fd, struct stat *buf) { FD_FUNC_WRAPPER(fstat, libc_fd, buf); } @@ -455,48 +350,11 @@ extern "C" int ftruncate(int libc_fd, ::off_t length) { FD_FUNC_WRAPPER(ftruncate, libc_fd, length); } -extern "C" int getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res) -{ - Plugin *plugin; - - plugin = plugin_registry()->get_plugin_for_getaddrinfo(node, service, hints, res); - - if (!plugin) { - PERR("no plugin found for getaddrinfo()"); - return -1; - } - - return plugin->getaddrinfo(node, service, hints, res); -} - - extern "C" ssize_t _getdirentries(int libc_fd, char *buf, ::size_t nbytes, ::off_t *basep) { FD_FUNC_WRAPPER(getdirentries, libc_fd, buf, nbytes, basep); } -extern "C" int _getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { - FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen); } - - -extern "C" int getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) -{ - return _getpeername(libc_fd, addr, addrlen); -} - - -extern "C" int _getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { - FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen); } - - -extern "C" int getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) -{ - return _getsockname(libc_fd, addr, addrlen); -} - - extern "C" int ioctl(int libc_fd, int request, char *argp) { FD_FUNC_WRAPPER(ioctl, libc_fd, request, argp); } @@ -505,16 +363,6 @@ extern "C" int _ioctl(int libc_fd, int request, char *argp) { FD_FUNC_WRAPPER(ioctl, libc_fd, request, argp); } -extern "C" int _listen(int libc_fd, int backlog) -{ - return listen(libc_fd, backlog); -} - - -extern "C" int listen(int libc_fd, int backlog) { - FD_FUNC_WRAPPER(listen, libc_fd, backlog); } - - extern "C" ::off_t lseek(int libc_fd, ::off_t offset, int whence) { FD_FUNC_WRAPPER(lseek, libc_fd, offset, whence); } @@ -698,26 +546,6 @@ extern "C" ssize_t readlink(const char *path, char *buf, size_t bufsiz) } -extern "C" ssize_t recv(int libc_fd, void *buf, ::size_t len, int flags) { - FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags); } - - -extern "C" ssize_t _recvfrom(int libc_fd, void *buf, ::size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) { - FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, addrlen); } - - -extern "C" ssize_t recvfrom(int libc_fd, void *buf, ::size_t len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) -{ - return _recvfrom(libc_fd, buf, len, flags, src_addr, addrlen); -} - - -extern "C" ssize_t recvmsg(int libc_fd, struct msghdr *msg, int flags) { - FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags); } - - extern "C" int rename(const char *oldpath, const char *newpath) { try { @@ -743,77 +571,6 @@ extern "C" int rmdir(const char *path) } -extern "C" ssize_t send(int libc_fd, const void *buf, ::size_t len, int flags) { - FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags); } - - -extern "C" ssize_t _sendto(int libc_fd, const void *buf, ::size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) { - FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, addrlen); } - - -extern "C" ssize_t sendto(int libc_fd, const void *buf, ::size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - return _sendto(libc_fd, buf, len, flags, dest_addr, addrlen); -} - - -extern "C" int _getsockopt(int libc_fd, int level, int optname, - void *optval, socklen_t *optlen) -{ - return getsockopt(libc_fd, level, optname, optval, optlen); -} - - -extern "C" int getsockopt(int libc_fd, int level, int optname, - void *optval, socklen_t *optlen) { - FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen); } - - -extern "C" int _setsockopt(int libc_fd, int level, int optname, - const void *optval, socklen_t optlen) { - FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen); } - - -extern "C" int setsockopt(int libc_fd, int level, int optname, - const void *optval, socklen_t optlen) -{ - return _setsockopt(libc_fd, level, optname, optval, optlen); -} - - -extern "C" int shutdown(int libc_fd, int how) { - FD_FUNC_WRAPPER(shutdown, libc_fd, how); } - -extern "C" int socket(int domain, int type, int protocol) -{ - Plugin *plugin; - File_descriptor *new_fdo; - - plugin = plugin_registry()->get_plugin_for_socket(domain, type, protocol); - - if (!plugin) { - PERR("no plugin found for socket()"); - return -1; - } - - new_fdo = plugin->socket(domain, type, protocol); - if (!new_fdo) { - PERR("plugin()->socket() failed"); - return -1; - } - - return new_fdo->libc_fd; -} - - -extern "C" int _socket(int domain, int type, int protocol) -{ - return socket(domain, type, protocol); -} - - extern "C" int stat(const char *path, struct stat *buf) { PDBGV("path = %s", path); diff --git a/repos/libports/src/lib/libc/libc_file.h b/repos/libports/src/lib/libc/libc_file.h new file mode 100644 index 0000000000..d903b35e41 --- /dev/null +++ b/repos/libports/src/lib/libc/libc_file.h @@ -0,0 +1,76 @@ +/* + * \brief File-operation utilities + * \author Christian Helmuth + * \date 2015-06-30 + */ + +/* + * Copyright (C) 2015 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. + */ + +#ifndef _LIBC_FILE_H_ +#define _LIBC_FILE_H_ + +/* Genode includes */ +#include + +/* Genode-specific libc interfaces */ +#include +#include + + +enum { INVALID_FD = -1 }; + +/** + * Find plugin responsible for the specified libc file descriptor + * + * \param func_name function name of the caller for printing an error message + */ +static inline Libc::File_descriptor *libc_fd_to_fd(int libc_fd, const char *func_name) +{ + Libc::File_descriptor *fd = + Libc::file_descriptor_allocator()->find_by_libc_fd(libc_fd); + if (!fd) + PERR("no plugin found for %s(%d)", func_name, libc_fd); + return fd; +} + + +/** + * Generate body of wrapper function taking a file descriptor as first argument + */ +#define FD_FUNC_WRAPPER_GENERIC(result_stm, result_err_val, func_name, libc_fd, ...) \ +{ \ + File_descriptor *fd = libc_fd_to_fd(libc_fd, #func_name); \ + if (!fd || !fd->plugin) { \ + errno = EBADF; \ + result_stm result_err_val; \ + } else \ + result_stm fd->plugin->func_name(fd, ##__VA_ARGS__ ); \ +} + +#define FD_FUNC_WRAPPER(func_name, libc_fd, ...) \ + FD_FUNC_WRAPPER_GENERIC(return, INVALID_FD, func_name, libc_fd, ##__VA_ARGS__ ) + +/** + * Generate body of wrapper function taking a path name as first argument + */ +#define FNAME_FUNC_WRAPPER_GENERIC(result_stm, func_name, path, ...) \ +{ \ + Plugin *plugin = plugin_registry()->get_plugin_for_##func_name(path, ##__VA_ARGS__); \ + if (!plugin) { \ + PERR("no plugin found for %s(\"%s\")", #func_name, path); \ + errno = ENOSYS; \ + result_stm -1; \ + } else \ + result_stm plugin->func_name(path, ##__VA_ARGS__); \ +} + +#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/socket_operations.cc b/repos/libports/src/lib/libc/socket_operations.cc new file mode 100644 index 0000000000..a29d3b4ca3 --- /dev/null +++ b/repos/libports/src/lib/libc/socket_operations.cc @@ -0,0 +1,230 @@ +/* + * \brief libc socket operations + * \author Christian Helmuth + * \author Christian Prochaska + * \author Norman Feske + * \date 2015-06-23 + */ + +/* + * Copyright (C) 2015 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 +#include +#include + +/* libc includes */ +#include +#include +#include + +/* libc-internal includes */ +#include "libc_file.h" + +using namespace Libc; + + +#ifdef GENODE_RELEASE +#undef PERR +#define PERR(...) +#endif /* GENODE_RELEASE */ + +static bool const verbose = false; +#define PDBGV(...) if (verbose) PDBG(__VA_ARGS__) + + +extern "C" int _accept(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + return accept(libc_fd, addr, addrlen); +} + + +extern "C" int accept(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + File_descriptor *ret_fd; + FD_FUNC_WRAPPER_GENERIC(ret_fd =, 0, accept, libc_fd, addr, addrlen); + return ret_fd ? ret_fd->libc_fd : INVALID_FD; +} + + +extern "C" int _bind(int libc_fd, const struct sockaddr *addr, + socklen_t addrlen) +{ + return bind(libc_fd, addr, addrlen); +} + + +extern "C" int bind(int libc_fd, const struct sockaddr *addr, + socklen_t addrlen) { + FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen); } + + +extern "C" int connect(int libc_fd, const struct sockaddr *addr, + socklen_t addrlen) { + FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen); } + + +extern "C" int _connect(int libc_fd, const struct sockaddr *addr, + socklen_t addrlen) +{ + return connect(libc_fd, addr, addrlen); +} + + +extern "C" void freeaddrinfo(struct addrinfo *res) +{ + Plugin *plugin; + + plugin = plugin_registry()->get_plugin_for_freeaddrinfo(res); + + if (!plugin) { + PERR("no plugin found for freeaddrinfo()"); + return; + } + + plugin->freeaddrinfo(res); +} + + +extern "C" int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, + struct addrinfo **res) +{ + Plugin *plugin; + + plugin = plugin_registry()->get_plugin_for_getaddrinfo(node, service, hints, res); + + if (!plugin) { + PERR("no plugin found for getaddrinfo()"); + return -1; + } + + return plugin->getaddrinfo(node, service, hints, res); +} + + +extern "C" int _getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { + FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen); } + + +extern "C" int getpeername(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + return _getpeername(libc_fd, addr, addrlen); +} + + +extern "C" int _getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) { + FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen); } + + +extern "C" int getsockname(int libc_fd, struct sockaddr *addr, socklen_t *addrlen) +{ + return _getsockname(libc_fd, addr, addrlen); +} + + +extern "C" int _listen(int libc_fd, int backlog) +{ + return listen(libc_fd, backlog); +} + + +extern "C" int listen(int libc_fd, int backlog) { + FD_FUNC_WRAPPER(listen, libc_fd, backlog); } + + +extern "C" ssize_t recv(int libc_fd, void *buf, ::size_t len, int flags) { + FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags); } + + +extern "C" ssize_t _recvfrom(int libc_fd, void *buf, ::size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) { + FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, addrlen); } + + +extern "C" ssize_t recvfrom(int libc_fd, void *buf, ::size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + return _recvfrom(libc_fd, buf, len, flags, src_addr, addrlen); +} + + +extern "C" ssize_t recvmsg(int libc_fd, struct msghdr *msg, int flags) { + FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags); } + + +extern "C" ssize_t send(int libc_fd, const void *buf, ::size_t len, int flags) { + FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags); } + + +extern "C" ssize_t _sendto(int libc_fd, const void *buf, ::size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) { + FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, addrlen); } + + +extern "C" ssize_t sendto(int libc_fd, const void *buf, ::size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + return _sendto(libc_fd, buf, len, flags, dest_addr, addrlen); +} + + +extern "C" int _getsockopt(int libc_fd, int level, int optname, + void *optval, socklen_t *optlen) +{ + return getsockopt(libc_fd, level, optname, optval, optlen); +} + + +extern "C" int getsockopt(int libc_fd, int level, int optname, + void *optval, socklen_t *optlen) { + FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen); } + + +extern "C" int _setsockopt(int libc_fd, int level, int optname, + const void *optval, socklen_t optlen) { + FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen); } + + +extern "C" int setsockopt(int libc_fd, int level, int optname, + const void *optval, socklen_t optlen) +{ + return _setsockopt(libc_fd, level, optname, optval, optlen); +} + + +extern "C" int shutdown(int libc_fd, int how) { + FD_FUNC_WRAPPER(shutdown, libc_fd, how); } + + +extern "C" int socket(int domain, int type, int protocol) +{ + Plugin *plugin; + File_descriptor *new_fdo; + + plugin = plugin_registry()->get_plugin_for_socket(domain, type, protocol); + + if (!plugin) { + PERR("no plugin found for socket()"); + return -1; + } + + new_fdo = plugin->socket(domain, type, protocol); + if (!new_fdo) { + PERR("plugin()->socket() failed"); + return -1; + } + + return new_fdo->libc_fd; +} + + +extern "C" int _socket(int domain, int type, int protocol) +{ + return socket(domain, type, protocol); +}