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);
+}