mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 10:32:44 +01:00
Merge pull request #6778 from miri64/posix_sockets/enh/port-to-vfs
posix_sockets: port to vfs for file descriptors
This commit is contained in:
commit
ac7671762d
@ -371,8 +371,8 @@ endif
|
|||||||
|
|
||||||
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
ifneq (,$(filter posix_sockets,$(USEMODULE)))
|
||||||
USEMODULE += bitfield
|
USEMODULE += bitfield
|
||||||
USEMODULE += posix
|
|
||||||
USEMODULE += random
|
USEMODULE += random
|
||||||
|
USEMODULE += vfs
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter rtt_stdio,$(USEMODULE)))
|
ifneq (,$(filter rtt_stdio,$(USEMODULE)))
|
||||||
|
144
cpu/atmega_common/posix_unistd.c
Normal file
144
cpu/atmega_common/posix_unistd.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Freie Universität Berlin
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Implements various POSIX syscalls
|
||||||
|
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
#include "vfs.h"
|
||||||
|
#elif defined(MODULE_UART_STDIO)
|
||||||
|
#include "uart_stdio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int close(int fd)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
int res = vfs_close(fd);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
off_t lseek(int fd, off_t off, int whence)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
off_t res = vfs_lseek(fd, off, whence);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
(void)off;
|
||||||
|
(void)whence;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int fcntl(int fd, int cmd, int arg)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
int res = vfs_fcntl(fd, cmd, arg);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
(void)cmd;
|
||||||
|
(void)arg;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int fstat(int fd, struct stat *buf)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
int res = vfs_fstat(fd, buf);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
(void)buf;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t read(int fd, void *dest, size_t count)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
ssize_t res = vfs_read(fd, dest, count);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#elif defined(MODULE_UART_STDIO)
|
||||||
|
if (fd == 0) {
|
||||||
|
return uart_stdio_read(dest, count);
|
||||||
|
}
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
(void)dest;
|
||||||
|
(void)count;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t write(int fd, const void *src, size_t count)
|
||||||
|
{
|
||||||
|
#ifdef MODULE_VFS
|
||||||
|
ssize_t res = vfs_write(fd, src, count);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
#elif defined(MODULE_UART_STDIO)
|
||||||
|
if (fd == 0) {
|
||||||
|
return uart_stdio_write(src, count);
|
||||||
|
}
|
||||||
|
errno = EBADF;
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
(void)fd;
|
||||||
|
(void)src;
|
||||||
|
(void)count;
|
||||||
|
errno = ENODEV;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @} */
|
@ -23,11 +23,11 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "bitfield.h"
|
#include "bitfield.h"
|
||||||
#include "fd.h"
|
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "net/ipv4/addr.h"
|
#include "net/ipv4/addr.h"
|
||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
#include "vfs.h"
|
||||||
|
|
||||||
#include "sys/socket.h"
|
#include "sys/socket.h"
|
||||||
#include "netinet/in.h"
|
#include "netinet/in.h"
|
||||||
@ -39,6 +39,7 @@
|
|||||||
/* enough to create sockets both with socket() and accept() */
|
/* enough to create sockets both with socket() and accept() */
|
||||||
#define _ACTUAL_SOCKET_POOL_SIZE (SOCKET_POOL_SIZE + \
|
#define _ACTUAL_SOCKET_POOL_SIZE (SOCKET_POOL_SIZE + \
|
||||||
(SOCKET_POOL_SIZE * SOCKET_TCP_QUEUE_SIZE))
|
(SOCKET_POOL_SIZE * SOCKET_TCP_QUEUE_SIZE))
|
||||||
|
#define SOCKET_BLKSIZE (512)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Unitfied connection type.
|
* @brief Unitfied connection type.
|
||||||
@ -90,6 +91,14 @@ static mutex_t _socket_pool_mutex = MUTEX_INIT;
|
|||||||
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
|
||||||
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
||||||
|
|
||||||
|
static ssize_t socket_recvfrom(socket_t *s, void *restrict buffer,
|
||||||
|
size_t length, int flags,
|
||||||
|
struct sockaddr *restrict address,
|
||||||
|
socklen_t *restrict address_len);
|
||||||
|
static ssize_t socket_sendto(socket_t *s, const void *buffer, size_t length,
|
||||||
|
int flags, const struct sockaddr *address,
|
||||||
|
socklen_t address_len);
|
||||||
|
|
||||||
static socket_t *_get_free_socket(void)
|
static socket_t *_get_free_socket(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _ACTUAL_SOCKET_POOL_SIZE; i++) {
|
for (int i = 0; i < _ACTUAL_SOCKET_POOL_SIZE; i++) {
|
||||||
@ -232,13 +241,11 @@ static int _sockaddr_to_ep(const struct sockaddr *address, socklen_t address_len
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_close(int socket)
|
static int socket_close(vfs_file_t *filp)
|
||||||
{
|
{
|
||||||
socket_t *s;
|
socket_t *s = filp->private_data.ptr;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
assert(((unsigned)socket) < _ACTUAL_SOCKET_POOL_SIZE);
|
|
||||||
s = &_socket_pool[socket];
|
|
||||||
assert((s->domain == AF_INET) || (s->domain == AF_INET6));
|
assert((s->domain == AF_INET) || (s->domain == AF_INET6));
|
||||||
mutex_lock(&_socket_pool_mutex);
|
mutex_lock(&_socket_pool_mutex);
|
||||||
if (s->sock != NULL) {
|
if (s->sock != NULL) {
|
||||||
@ -279,16 +286,42 @@ static int socket_close(int socket)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t socket_read(int socket, void *buf, size_t n)
|
static inline int socket_fstat(vfs_file_t *filp, struct stat *buf)
|
||||||
{
|
{
|
||||||
return recv(socket, buf, n, 0);
|
(void)filp;
|
||||||
|
memset(buf, 0, sizeof(struct stat));
|
||||||
|
buf->st_mode |= (S_IFSOCK | S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
|
buf->st_blksize = SOCKET_BLKSIZE;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t socket_write(int socket, const void *buf, size_t n)
|
static inline off_t socket_lseek(vfs_file_t *filp, off_t off, int whence)
|
||||||
{
|
{
|
||||||
return send(socket, buf, n, 0);
|
(void)filp;
|
||||||
|
(void)off;
|
||||||
|
(void)whence;
|
||||||
|
return -ESPIPE; /* see http://pubs.opengroup.org/onlinepubs/9699919799/functions/lseek.html */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ssize_t socket_read(vfs_file_t *filp, void *buf, size_t n)
|
||||||
|
{
|
||||||
|
return socket_recvfrom(filp->private_data.ptr, buf, n, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline ssize_t socket_write(vfs_file_t *filp, const void *buf, size_t n)
|
||||||
|
{
|
||||||
|
return socket_sendto(filp->private_data.ptr, buf, n, 0, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const vfs_file_ops_t socket_ops = {
|
||||||
|
.close = socket_close,
|
||||||
|
.fcntl = NULL, /* TODO: provide when needed */
|
||||||
|
.fstat = socket_fstat,
|
||||||
|
.lseek = socket_lseek,
|
||||||
|
.read = socket_read,
|
||||||
|
.write = socket_write,
|
||||||
|
};
|
||||||
|
|
||||||
int socket(int domain, int type, int protocol)
|
int socket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@ -307,8 +340,7 @@ int socket(int domain, int type, int protocol)
|
|||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int fd = fd_new(s - _socket_pool, socket_read, socket_write,
|
int fd = vfs_bind(VFS_ANY_FD, 0, &socket_ops, s);
|
||||||
socket_close);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
errno = ENFILE;
|
errno = ENFILE;
|
||||||
@ -593,8 +625,7 @@ static int _getpeername(socket_t *s, struct sockaddr *__restrict address,
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
|
|
||||||
if (s->sock == NULL) {
|
if (s->sock == NULL) {
|
||||||
errno = ENOTCONN;
|
return -ENOTCONN;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
#ifdef MODULE_SOCK_IP
|
#ifdef MODULE_SOCK_IP
|
||||||
@ -621,11 +652,7 @@ static int _getpeername(socket_t *s, struct sockaddr *__restrict address,
|
|||||||
res = -EOPNOTSUPP;
|
res = -EOPNOTSUPP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
if (res >= 0) {
|
||||||
errno = -res;
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
struct sockaddr_storage sa;
|
struct sockaddr_storage sa;
|
||||||
socklen_t sa_len = _ep_to_sockaddr(&ep, &sa);
|
socklen_t sa_len = _ep_to_sockaddr(&ep, &sa);
|
||||||
*address_len = _addr_truncate(address, *address_len, &sa,
|
*address_len = _addr_truncate(address, *address_len, &sa,
|
||||||
@ -638,6 +665,7 @@ int getpeername(int socket, struct sockaddr *__restrict address,
|
|||||||
socklen_t *__restrict address_len)
|
socklen_t *__restrict address_len)
|
||||||
{
|
{
|
||||||
socket_t *s;
|
socket_t *s;
|
||||||
|
int res;
|
||||||
|
|
||||||
mutex_lock(&_socket_pool_mutex);
|
mutex_lock(&_socket_pool_mutex);
|
||||||
s = _get_socket(socket);
|
s = _get_socket(socket);
|
||||||
@ -646,7 +674,11 @@ int getpeername(int socket, struct sockaddr *__restrict address,
|
|||||||
errno = ENOTSOCK;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return _getpeername(s, address, address_len);
|
if ((res = _getpeername(s, address, address_len)) < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getsockname(int socket, struct sockaddr *__restrict address,
|
int getsockname(int socket, struct sockaddr *__restrict address,
|
||||||
@ -773,27 +805,22 @@ int listen(int socket, int backlog)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
static ssize_t socket_recvfrom(socket_t *s, void *restrict buffer,
|
||||||
struct sockaddr *restrict address,
|
size_t length, int flags,
|
||||||
socklen_t *restrict address_len)
|
struct sockaddr *restrict address,
|
||||||
|
socklen_t *restrict address_len)
|
||||||
{
|
{
|
||||||
socket_t *s;
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
struct _sock_tl_ep ep = { .port = 0 };
|
struct _sock_tl_ep ep = { .port = 0 };
|
||||||
|
|
||||||
(void)flags;
|
(void)flags;
|
||||||
mutex_lock(&_socket_pool_mutex);
|
|
||||||
s = _get_socket(socket);
|
|
||||||
mutex_unlock(&_socket_pool_mutex);
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
errno = ENOTSOCK;
|
return -ENOTSOCK;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
if (s->sock == NULL) { /* socket is not connected */
|
if (s->sock == NULL) { /* socket is not connected */
|
||||||
#ifdef MODULE_SOCK_TCP
|
#ifdef MODULE_SOCK_TCP
|
||||||
if (s->type == SOCK_STREAM) {
|
if (s->type == SOCK_STREAM) {
|
||||||
errno = ENOTCONN;
|
return -ENOTCONN;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* bind implicitly */
|
/* bind implicitly */
|
||||||
@ -811,34 +838,24 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
|||||||
switch (s->type) {
|
switch (s->type) {
|
||||||
#ifdef MODULE_SOCK_IP
|
#ifdef MODULE_SOCK_IP
|
||||||
case SOCK_RAW:
|
case SOCK_RAW:
|
||||||
if ((res = sock_ip_recv(&s->sock->raw, buffer, length, recv_timeout
|
res = sock_ip_recv(&s->sock->raw, buffer, length, recv_timeout,
|
||||||
(sock_ip_ep_t *)&ep)) < 0) {
|
(sock_ip_ep_t *)&ep);
|
||||||
errno = -res;
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULE_SOCK_TCP
|
#ifdef MODULE_SOCK_TCP
|
||||||
case SOCK_STREAM:
|
case SOCK_STREAM:
|
||||||
if ((res = sock_tcp_read(&s->sock->tcp.sock, buffer, length,
|
res = sock_tcp_read(&s->sock->tcp.sock, buffer, length,
|
||||||
recv_timeout)) < 0) {
|
recv_timeout);
|
||||||
errno = -res;
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULE_SOCK_UDP
|
#ifdef MODULE_SOCK_UDP
|
||||||
case SOCK_DGRAM:
|
case SOCK_DGRAM:
|
||||||
if ((res = sock_udp_recv(&s->sock->udp, buffer, length, recv_timeout,
|
res = sock_udp_recv(&s->sock->udp, buffer, length, recv_timeout,
|
||||||
&ep)) < 0) {
|
&ep);
|
||||||
errno = -res;
|
|
||||||
res = -1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
errno = EOPNOTSUPP;
|
res = -EOPNOTSUPP;
|
||||||
res = -1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((res >= 0) && (address != NULL) && (address_len != 0)) {
|
if ((res >= 0) && (address != NULL) && (address_len != 0)) {
|
||||||
@ -862,19 +879,34 @@ ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags,
|
||||||
const struct sockaddr *address, socklen_t address_len)
|
struct sockaddr *restrict address,
|
||||||
|
socklen_t *restrict address_len)
|
||||||
{
|
{
|
||||||
socket_t *s;
|
socket_t *s;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
mutex_lock(&_socket_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_socket_pool_mutex);
|
||||||
|
res = socket_recvfrom(s, buffer, length, flags, address, address_len);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t socket_sendto(socket_t *s, const void *buffer, size_t length,
|
||||||
|
int flags, const struct sockaddr *address,
|
||||||
|
socklen_t address_len)
|
||||||
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
#if defined(MODULE_SOCK_IP) || defined(MODULE_SOCK_UDP)
|
#if defined(MODULE_SOCK_IP) || defined(MODULE_SOCK_UDP)
|
||||||
struct _sock_tl_ep ep = { .port = 0 };
|
struct _sock_tl_ep ep = { .port = 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void)flags;
|
(void)flags;
|
||||||
mutex_lock(&_socket_pool_mutex);
|
|
||||||
s = _get_socket(socket);
|
|
||||||
mutex_unlock(&_socket_pool_mutex);
|
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
errno = ENOTSOCK;
|
errno = ENOTSOCK;
|
||||||
return -1;
|
return -1;
|
||||||
@ -936,6 +968,23 @@ ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t sendto(int socket, const void *buffer, size_t length, int flags,
|
||||||
|
const struct sockaddr *address, socklen_t address_len)
|
||||||
|
{
|
||||||
|
socket_t *s;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
mutex_lock(&_socket_pool_mutex);
|
||||||
|
s = _get_socket(socket);
|
||||||
|
mutex_unlock(&_socket_pool_mutex);
|
||||||
|
res = socket_sendto(s, buffer, length, flags, address, address_len);
|
||||||
|
if (res < 0) {
|
||||||
|
errno = -res;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a partial implementation of setsockopt for changing the receive
|
* This is a partial implementation of setsockopt for changing the receive
|
||||||
* timeout value of a socket.
|
* timeout value of a socket.
|
||||||
|
Loading…
Reference in New Issue
Block a user