2015-06-29 17:02:08 +02:00
|
|
|
/*
|
|
|
|
* \brief libc socket operations
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \author Christian Prochaska
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2015-06-23
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-12 10:59:37 +01:00
|
|
|
* Copyright (C) 2015-2017 Genode Labs GmbH
|
2015-06-29 17:02:08 +02:00
|
|
|
*
|
|
|
|
* 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 <os/path.h>
|
|
|
|
#include <util/token.h>
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
/* libc-internal includes */
|
|
|
|
#include "libc_file.h"
|
2017-02-12 10:59:37 +01:00
|
|
|
#include "socket_fs_plugin.h"
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
using namespace Libc;
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
namespace Libc { extern char const *config_socket(); }
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
|
|
|
|
/***********************
|
|
|
|
** Address functions **
|
|
|
|
***********************/
|
|
|
|
|
|
|
|
extern "C" int _getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_getpeername(libc_fd, addr, addrlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(getpeername, libc_fd, addr, addrlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int getpeername(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
return _getpeername(libc_fd, addr, addrlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int _getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_getsockname(libc_fd, addr, addrlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(getsockname, libc_fd, addr, addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int getsockname(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _getsockname(libc_fd, addr, addrlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**************************
|
|
|
|
** Socket transport API **
|
|
|
|
**************************/
|
|
|
|
|
|
|
|
extern "C" int _accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_accept(libc_fd, addr, addrlen);
|
|
|
|
|
2015-06-29 17:02:08 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int accept(int libc_fd, sockaddr *addr, socklen_t *addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _accept(libc_fd, addr, addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int _bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_bind(libc_fd, addr, addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
FD_FUNC_WRAPPER(bind, libc_fd, addr, addrlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
|
|
|
|
extern "C" int bind(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
return _bind(libc_fd, addr, addrlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int _connect(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_connect(libc_fd, addr, addrlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(connect, libc_fd, addr, addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int connect(int libc_fd, sockaddr const *addr, socklen_t addrlen)
|
|
|
|
{
|
|
|
|
return _connect(libc_fd, addr, addrlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int _listen(int libc_fd, int backlog)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_listen(libc_fd, backlog);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(listen, libc_fd, backlog);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int listen(int libc_fd, int backlog)
|
|
|
|
{
|
|
|
|
return _listen(libc_fd, backlog);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t _recvfrom(int libc_fd, void *buf, ::size_t len, int flags,
|
|
|
|
sockaddr *src_addr, socklen_t *src_addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_recvfrom(libc_fd, buf, len, flags, src_addr, src_addrlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(recvfrom, libc_fd, buf, len, flags, src_addr, src_addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t recvfrom(int libc_fd, void *buf, ::size_t len, int flags,
|
|
|
|
sockaddr *src_addr, socklen_t *src_addrlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _recvfrom(libc_fd, buf, len, flags, src_addr, src_addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t recv(int libc_fd, void *buf, ::size_t len, int flags)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_recv(libc_fd, buf, len, flags);
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
FD_FUNC_WRAPPER(recv, libc_fd, buf, len, flags);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t _recvmsg(int libc_fd, msghdr *msg, int flags)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_recvmsg(libc_fd, msg, flags);
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
FD_FUNC_WRAPPER(recvmsg, libc_fd, msg, flags);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t recvmsg(int libc_fd, msghdr *msg, int flags)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _recvmsg(libc_fd, msg, flags);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t _sendto(int libc_fd, void const *buf, ::size_t len, int flags,
|
|
|
|
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_sendto(libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
FD_FUNC_WRAPPER(sendto, libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t sendto(int libc_fd, void const *buf, ::size_t len, int flags,
|
|
|
|
sockaddr const *dest_addr, socklen_t dest_addrlen)
|
|
|
|
{
|
|
|
|
return _sendto(libc_fd, buf, len, flags, dest_addr, dest_addrlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" ssize_t send(int libc_fd, void const *buf, ::size_t len, int flags)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_send(libc_fd, buf, len, flags);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(send, libc_fd, buf, len, flags);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int _getsockopt(int libc_fd, int level, int optname,
|
|
|
|
void *optval, socklen_t *optlen)
|
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_getsockopt(libc_fd, level, optname, optval, optlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(getsockopt, libc_fd, level, optname, optval, optlen);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int getsockopt(int libc_fd, int level, int optname,
|
2017-02-12 10:59:37 +01:00
|
|
|
void *optval, socklen_t *optlen)
|
|
|
|
{
|
|
|
|
return _getsockopt(libc_fd, level, optname, optval, optlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
extern "C" int _setsockopt(int libc_fd, int level, int optname,
|
2017-02-12 10:59:37 +01:00
|
|
|
void const *optval, socklen_t optlen)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_setsockopt(libc_fd, level, optname, optval, optlen);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(setsockopt, libc_fd, level, optname, optval, optlen);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
extern "C" int setsockopt(int libc_fd, int level, int optname,
|
2017-02-12 10:59:37 +01:00
|
|
|
void const *optval, socklen_t optlen)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
|
|
|
return _setsockopt(libc_fd, level, optname, optval, optlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int _shutdown(int libc_fd, int how)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_shutdown(libc_fd, how);
|
|
|
|
|
|
|
|
FD_FUNC_WRAPPER(shutdown, libc_fd, how);
|
|
|
|
}
|
2015-06-29 17:02:08 +02:00
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int shutdown(int libc_fd, int how)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _shutdown(libc_fd, how);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
extern "C" int _socket(int domain, int type, int protocol)
|
|
|
|
{
|
|
|
|
if (*Libc::config_socket())
|
|
|
|
return socket_fs_socket(domain, type, protocol);
|
|
|
|
|
2015-06-29 17:02:08 +02:00
|
|
|
Plugin *plugin;
|
|
|
|
File_descriptor *new_fdo;
|
|
|
|
|
|
|
|
plugin = plugin_registry()->get_plugin_for_socket(domain, type, protocol);
|
|
|
|
|
|
|
|
if (!plugin) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
Genode::error("no plugin found for socket()");
|
2015-06-29 17:02:08 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
new_fdo = plugin->socket(domain, type, protocol);
|
|
|
|
if (!new_fdo) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
Genode::error("plugin()->socket() failed");
|
2015-06-29 17:02:08 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return new_fdo->libc_fd;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-02-12 10:59:37 +01:00
|
|
|
extern "C" int socket(int domain, int type, int protocol)
|
2015-06-29 17:02:08 +02:00
|
|
|
{
|
2017-02-12 10:59:37 +01:00
|
|
|
return _socket(domain, type, protocol);
|
2015-06-29 17:02:08 +02:00
|
|
|
}
|