[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Update patches
From: |
Samuel Thibault |
Subject: |
Re: [PATCH] Update patches |
Date: |
Tue, 28 Aug 2018 20:50:08 +0200 |
User-agent: |
NeoMutt/20170113 (1.7.2) |
Hello,
Unfortunately your mailer dropped all ^M characters so the patch can't
be applied. Could you re-send it as a compressed file to make sure that
it doesn't get mangled?
Thanks,
Samuel
Joan Lledó, le mar. 07 août 2018 18:09:55 +0200, a ecrit:
> PORT: Use always interruptible functions for waiting
> Return SYS_ARCH_INTR when a waiting thread is cancelled
> POLL: Use always interruptible functions for waiting
> Fix some debug messages
> MAX_SOCKETS: Protect the socket list every time it's read
> All but AUTOCONF: Converted to DOS format to mach lwip sources
> All: Remove fuzziness
>
> ---
> debian/patches/bug-36167 | 8 +-
> debian/patches/errno | 20 +-
> debian/patches/max_sockets | 75 +-
> debian/patches/poll | 146 ++--
> debian/patches/port | 1943
> +++++++++++++++++++++-----------------------
> debian/patches/posix | 1733 ++++++++++++++++++++-------------------
> 6 files changed, 1917 insertions(+), 2008 deletions(-)
>
> diff --git a/debian/patches/bug-36167 b/debian/patches/bug-36167
> index 4220301..e0a6d92 100644
> --- a/debian/patches/bug-36167
> +++ b/debian/patches/bug-36167
> @@ -1,10 +1,8 @@
> Already upstream
>
> -diff --git a/src/core/tcp.c b/src/core/tcp.c
> -index 7103a52..ccfa3c1 100644
> --- a/src/core/tcp.c
> +++ b/src/core/tcp.c
> -@@ -804,7 +804,7 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
> +@@ -804,7 +804,7 @@
> pcb->rcv_wnd = TCP_WND_MAX(pcb);
> } else if (pcb->rcv_wnd == 0) {
> /* rcv_wnd overflowed */
> @@ -13,11 +11,9 @@ index 7103a52..ccfa3c1 100644
> /* In passive close, we allow this, since the FIN bit is added to
> rcv_wnd
> by the stack itself, since it is not mandatory for an application
> to call tcp_recved() for the FIN bit, but e.g. the netconn API
> does so. */
> -diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h
> -index 3845b9f..fb7fa17 100644
> --- a/src/include/lwip/tcp.h
> +++ b/src/include/lwip/tcp.h
> -@@ -424,6 +424,9 @@ const char* tcp_debug_state_str(enum tcp_state s);
> +@@ -424,6 +424,9 @@
> /* for compatibility with older implementation */
> #define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6)
>
> diff --git a/debian/patches/errno b/debian/patches/errno
> index 1cf5d42..9aed02a 100644
> --- a/debian/patches/errno
> +++ b/debian/patches/errno
> @@ -1,10 +1,8 @@
> Already upstream
>
> -Index: lwip/src/api/sockets.c
> -===================================================================
> ---- lwip.orig/src/api/sockets.c
> -+++ lwip/src/api/sockets.c
> -@@ -213,7 +213,7 @@ struct lwip_sock {
> +--- a/src/api/sockets.c
> ++++ b/src/api/sockets.c
> +@@ -223,7 +223,7 @@
> /** error happened for this socket, set by event_callback(), tested by
> select */
> u16_t errevent;
> /** last error that occurred on this socket (in fact, all our errnos fit
> into an u8_t) */
> @@ -13,7 +11,7 @@ Index: lwip/src/api/sockets.c
> /** counter of how many threads are waiting for this socket using select
> */
> SELWAIT_T select_waiting;
> };
> -@@ -299,7 +299,7 @@ static volatile int select_cb_ctr;
> +@@ -309,7 +309,7 @@
>
> #define sock_set_errno(sk, e) do { \
> const int sockerr = (e); \
> @@ -22,7 +20,7 @@ Index: lwip/src/api/sockets.c
> set_errno(sockerr); \
> } while (0)
>
> -@@ -309,8 +309,8 @@ static void event_callback(struct netcon
> +@@ -319,8 +319,8 @@
> static void lwip_getsockopt_callback(void *arg);
> static void lwip_setsockopt_callback(void *arg);
> #endif
> @@ -33,7 +31,7 @@ Index: lwip/src/api/sockets.c
>
> #if LWIP_IPV4 && LWIP_IPV6
> static void
> -@@ -1792,7 +1792,7 @@ lwip_getsockname(int s, struct sockaddr
> +@@ -1804,7 +1804,7 @@
> int
> lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t
> *optlen)
> {
> @@ -42,7 +40,7 @@ Index: lwip/src/api/sockets.c
> struct lwip_sock *sock = get_socket(s);
> #if !LWIP_TCPIP_CORE_LOCKING
> LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
> -@@ -1887,10 +1887,10 @@ lwip_getsockopt_callback(void *arg)
> +@@ -1899,10 +1899,10 @@
> /** lwip_getsockopt_impl: the actual implementation of getsockopt:
> * same argument as lwip_getsockopt, either called directly or through
> callback
> */
> @@ -55,7 +53,7 @@ Index: lwip/src/api/sockets.c
> struct lwip_sock *sock = tryget_socket(s);
> if (!sock) {
> return EBADF;
> -@@ -2198,7 +2198,7 @@ lwip_getsockopt_impl(int s, int level, i
> +@@ -2210,7 +2210,7 @@
> int
> lwip_setsockopt(int s, int level, int optname, const void *optval,
> socklen_t optlen)
> {
> @@ -64,7 +62,7 @@ Index: lwip/src/api/sockets.c
> struct lwip_sock *sock = get_socket(s);
> #if !LWIP_TCPIP_CORE_LOCKING
> LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data);
> -@@ -2288,10 +2288,10 @@ lwip_setsockopt_callback(void *arg)
> +@@ -2300,10 +2300,10 @@
> /** lwip_setsockopt_impl: the actual implementation of setsockopt:
> * same argument as lwip_setsockopt, either called directly or through
> callback
> */
> diff --git a/debian/patches/max_sockets b/debian/patches/max_sockets
> index 53b4555..1862444 100644
> --- a/debian/patches/max_sockets
> +++ b/debian/patches/max_sockets
> @@ -33,7 +33,7 @@ Won't get to upstream
> * in seconds. (does not require sockets.c, and will affect tcp.c)
> --- a/src/api/sockets.c
> +++ b/src/api/sockets.c
> -@@ -198,6 +198,12 @@
> +@@ -208,6 +208,12 @@
>
> /** Contains all internal pointers and states used for a socket */
> struct lwip_sock {
> @@ -46,7 +46,7 @@ Won't get to upstream
> /** sockets currently are built on netconns, each socket has one netconn
> */
> struct netconn *conn;
> /** data that was left from the previous read */
> -@@ -287,8 +293,13 @@
> +@@ -297,8 +303,13 @@
> static void lwip_socket_drop_registered_memberships(int s);
> #endif /* LWIP_IGMP */
>
> @@ -60,7 +60,7 @@ Won't get to upstream
> /** The global list of tasks waiting for select */
> static struct lwip_select_cb *select_cb_list;
> /** This counter is increased from lwip_select when the list is changed
> -@@ -359,15 +370,26 @@
> +@@ -369,15 +380,29 @@
>
> s -= LWIP_SOCKET_OFFSET;
>
> @@ -76,10 +76,13 @@ Won't get to upstream
> }
>
> +#if LWIP_SOCKET_OPEN_COUNT
> ++ SYS_ARCH_DECL_PROTECT(lev);
> ++ SYS_ARCH_PROTECT(lev);
> + for(sock = sockets; sock != NULL; sock = sock->next) {
> + if(sock->count == s)
> + break;
> + }
> ++ SYS_ARCH_UNPROTECT(lev);
> +#else /* LWIP_SOCKET_OPEN_COUNT */
> sock = &sockets[s];
> +#endif /* LWIP_SOCKET_OPEN_COUNT */
> @@ -89,9 +92,14 @@ Won't get to upstream
> LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s +
> LWIP_SOCKET_OFFSET));
> set_errno(EBADF);
> return NULL;
> -@@ -386,13 +408,26 @@
> +@@ -395,14 +420,33 @@
> + static struct lwip_sock *
> tryget_socket(int s)
> {
> ++#if LWIP_SOCKET_OPEN_COUNT
> ++ struct lwip_sock *sock;
> ++#endif /* LWIP_SOCKET_OPEN_COUNT */
> ++
> s -= LWIP_SOCKET_OFFSET;
> - if ((s < 0) || (s >= NUM_SOCKETS)) {
> + if ((s < 0)
> @@ -102,11 +110,13 @@ Won't get to upstream
> return NULL;
> }
> +#if LWIP_SOCKET_OPEN_COUNT
> -+ struct lwip_sock *sock;
> ++ SYS_ARCH_DECL_PROTECT(lev);
> ++ SYS_ARCH_PROTECT(lev);
> + for(sock = sockets; sock != NULL; sock = sock->next) {
> + if(sock->count == s)
> + break;
> + }
> ++ SYS_ARCH_UNPROTECT(lev);
> + return sock;
> +#else /* LWIP_SOCKET_OPEN_COUNT */
> if (!sockets[s].conn) {
> @@ -117,7 +127,7 @@ Won't get to upstream
> }
>
> /**
> -@@ -407,30 +442,70 @@
> +@@ -417,30 +461,70 @@
> alloc_socket(struct netconn *newconn, int accepted)
> {
> int i;
> @@ -199,33 +209,34 @@ Won't get to upstream
> }
>
> /** Free a socket. The socket's netconn must have been
> -@@ -442,9 +517,14 @@
> - static void
> +@@ -453,6 +537,9 @@
> free_socket(struct lwip_sock *sock, int is_tcp)
> {
> -- void *lastdata;
> --
> -- lastdata = sock->lastdata;
> -+ void *lastdata = sock->lastdata;
> + void *lastdata;
> +#if LWIP_SOCKET_OPEN_COUNT
> + struct lwip_sock **it = &sockets;
> -+
> -+ while(*it != sock) it = &(*it)->next;
> -+ *it = (*it)->next;
> -+ mem_free(sock);
> -+#else /* LWIP_SOCKET_OPEN_COUNT */
> ++#endif /* LWIP_SOCKET_OPEN_COUNT */
> +
> + lastdata = sock->lastdata;
> sock->lastdata = NULL;
> - sock->lastoffset = 0;
> +@@ -460,7 +547,15 @@
> sock->err = 0;
> -@@ -452,6 +532,7 @@
> +
> /* Protect socket array */
> - SYS_ARCH_SET(sock->conn, NULL);
> - /* don't use 'sock' after this line, as another task might have allocated
> it */
> +- SYS_ARCH_SET(sock->conn, NULL);
> ++ SYS_ARCH_DECL_PROTECT(lev);
> ++ SYS_ARCH_PROTECT(lev);
> ++ sock->conn = NULL;
> ++#if LWIP_SOCKET_OPEN_COUNT
> ++ while(*it != sock) it = &(*it)->next;
> ++ *it = (*it)->next;
> ++ mem_free(sock);
> +#endif /* LWIP_SOCKET_OPEN_COUNT */
> ++ SYS_ARCH_UNPROTECT(lev);
> + /* don't use 'sock' after this line, as another task might have allocated
> it */
>
> if (lastdata != NULL) {
> - if (is_tcp) {
> -@@ -512,7 +593,9 @@
> +@@ -522,7 +617,9 @@
> sock_set_errno(sock, ENFILE);
> return -1;
> }
> @@ -238,12 +249,12 @@ Won't get to upstream
> --- a/port/include/lwipopts.h
> +++ b/port/include/lwipopts.h
> @@ -26,6 +26,9 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS 0
> -
> -+/* Don't limit the number of sockets */
> -+#define LWIP_SOCKET_OPEN_COUNT 1
> -+
> - /* We're using lwip_poll() */
> - #define LWIP_POLL 1
> -
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS 0
> +
> ++/* Don't limit the number of sockets */
> ++#define LWIP_SOCKET_OPEN_COUNT 1
> ++
> + /* We're using lwip_poll() */
> + #define LWIP_POLL 1
> +
> diff --git a/debian/patches/poll b/debian/patches/poll
> index c060cf3..198e258 100644
> --- a/debian/patches/poll
> +++ b/debian/patches/poll
> @@ -2,7 +2,7 @@ Already upstream
>
> --- a/src/api/sockets.c
> +++ b/src/api/sockets.c
> -@@ -238,6 +238,12 @@
> +@@ -248,6 +248,12 @@
> fd_set *writeset;
> /** unimplemented: exceptset passed to select */
> fd_set *exceptset;
> @@ -15,7 +15,7 @@ Already upstream
> /** don't signal the same semaphore twice: set to 1 when signalled */
> int sem_signalled;
> /** semaphore to wake up a task waiting for select */
> -@@ -1288,6 +1294,51 @@
> +@@ -1302,6 +1308,51 @@
> return lwip_sendmsg(s, &msg, 0);
> }
>
> @@ -67,7 +67,7 @@ Already upstream
> /**
> * Go through the readset and writeset lists and see which socket of the
> sockets
> * set in the sets has events. On return, readset, writeset and exceptset
> have
> -@@ -1411,6 +1462,10 @@
> +@@ -1425,6 +1476,10 @@
> select_cb.readset = readset;
> select_cb.writeset = writeset;
> select_cb.exceptset = exceptset;
> @@ -78,7 +78,7 @@ Already upstream
> select_cb.sem_signalled = 0;
> #if LWIP_NETCONN_SEM_PER_THREAD
> select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET();
> -@@ -1422,20 +1477,7 @@
> +@@ -1436,20 +1491,7 @@
> }
> #endif /* LWIP_NETCONN_SEM_PER_THREAD */
>
> @@ -100,7 +100,7 @@ Already upstream
>
> /* Increase select_waiting for each socket we are interested in */
> maxfdp2 = maxfdp1;
> -@@ -1505,21 +1547,7 @@
> +@@ -1519,21 +1561,7 @@
> SYS_ARCH_UNPROTECT(lev);
> }
> }
> @@ -123,7 +123,7 @@ Already upstream
>
> #if LWIP_NETCONN_SEM_PER_THREAD
> if (select_cb.sem_signalled && (!waited || (waitres ==
> SYS_ARCH_TIMEOUT))) {
> -@@ -1563,6 +1591,253 @@
> +@@ -1577,6 +1605,253 @@
> return nready;
> }
>
> @@ -304,7 +304,7 @@ Already upstream
> + LWIP_ASSERT("timeout > 0", timeout > 0);
> + msectimeout = timeout;
> + }
> -+ waitres = sys_arch_sem_wait_intr(SELECT_SEM_PTR(select_cb.sem),
> msectimeout);
> ++ waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem),
> msectimeout);
> +#if LWIP_NETCONN_SEM_PER_THREAD
> + waited = 1;
> +#endif
> @@ -332,12 +332,12 @@ Already upstream
> +
> + if (waitres == SYS_ARCH_TIMEOUT) {
> + /* Timeout */
> -+ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n"));
> ++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n"));
> + goto return_success;
> + }
> + }
> +
> -+ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
> ++ LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready));
> +return_success:
> + set_errno(0);
> + return nready;
> @@ -377,7 +377,7 @@ Already upstream
> /**
> * Callback registered in the netconn layer for each socket-netconn.
> * Processes recvevent (data available) and wakes up tasks waiting for
> select.
> -@@ -1649,20 +1924,27 @@
> +@@ -1663,20 +1938,27 @@
> if (scb->sem_signalled == 0) {
> /* semaphore not signalled yet */
> int do_signal = 0;
> @@ -419,7 +419,7 @@ Already upstream
> if (do_signal) {
> --- a/src/include/lwip/opt.h
> +++ b/src/include/lwip/opt.h
> -@@ -1751,6 +1751,17 @@
> +@@ -1751,6 +1751,17 @@
> #endif
>
> /**
> @@ -439,49 +439,49 @@ Already upstream
> * names (read, write & close). (only used if you use sockets.c)
> --- a/src/include/lwip/lwip_sockets.h
> +++ b/src/include/lwip/lwip_sockets.h
> -@@ -430,6 +430,21 @@
> - #error "external FD_SETSIZE too small for number of sockets"
> - #endif /* FD_SET */
> -
> -+#if LWIP_POLL == 2
> -+#define POLLIN 0x01
> -+#define POLLOUT 0x02
> -+#define POLLERR 0x04
> -+#define POLLNVAL 0x08
> -+/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
> -+typedef int nfds_t;
> -+struct pollfd
> -+{
> -+ int fd;
> -+ short events;
> -+ short revents;
> -+};
> -+#endif
> -+
> - /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> - * by your system, set this to 0 and include <sys/time.h> in cc.h */
> - #ifndef LWIP_TIMEVAL_PRIVATE
> -@@ -466,6 +481,9 @@
> - #define lwip_sendto sendto
> - #define lwip_socket socket
> - #define lwip_select select
> -+#if LWIP_POLL
> -+#define lwip_poll poll
> -+#endif
> - #define lwip_ioctlsocket ioctl
> -
> - #if LWIP_POSIX_SOCKETS_IO_NAMES
> -@@ -516,6 +534,10 @@
> - #define socket(domain,type,protocol)
> lwip_socket(domain,type,protocol)
> - /** @ingroup socket */
> - #define select(maxfdp1,readset,writeset,exceptset,timeout)
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> -+#if LWIP_POLL
> -+/** @ingroup socket */
> -+#define poll(fds,nfds,timeout)
> lwip_poll(fds,nfds,timeout)
> -+#endif
> - /** @ingroup socket */
> - #define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> -
> +@@ -432,6 +432,21 @@
> + #error "external FD_SETSIZE too small for number of sockets"
> + #endif /* FD_SET */
> +
> ++#if LWIP_POLL == 2
> ++#define POLLIN 0x01
> ++#define POLLOUT 0x02
> ++#define POLLERR 0x04
> ++#define POLLNVAL 0x08
> ++/* No support for POLLPRI, POLLHUP, POLLMSG, POLLRDBAND, POLLWRBAND. */
> ++typedef int nfds_t;
> ++struct pollfd
> ++{
> ++ int fd;
> ++ short events;
> ++ short revents;
> ++};
> ++#endif
> ++
> + /** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> + * by your system, set this to 0 and include <sys/time.h> in cc.h */
> + #ifndef LWIP_TIMEVAL_PRIVATE
> +@@ -468,6 +483,9 @@
> + #define lwip_sendto sendto
> + #define lwip_socket socket
> + #define lwip_select select
> ++#if LWIP_POLL
> ++#define lwip_poll poll
> ++#endif
> + #define lwip_ioctlsocket ioctl
> +
> + #if LWIP_POSIX_SOCKETS_IO_NAMES
> +@@ -518,6 +536,10 @@
> + #define socket(domain,type,protocol)
> lwip_socket(domain,type,protocol)
> + /** @ingroup socket */
> + #define select(maxfdp1,readset,writeset,exceptset,timeout)
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> ++#if LWIP_POLL
> ++/** @ingroup socket */
> ++#define poll(fds,nfds,timeout)
> lwip_poll(fds,nfds,timeout)
> ++#endif
> + /** @ingroup socket */
> + #define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> +
> --- a/src/include/lwip/sockets.h
> +++ b/src/include/lwip/sockets.h
> @@ -75,6 +75,9 @@
> @@ -497,24 +497,24 @@ Already upstream
> --- a/port/include/lwipopts.h
> +++ b/port/include/lwipopts.h
> @@ -26,6 +26,9 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS 0
> -
> -+/* We're using lwip_poll() */
> -+#define LWIP_POLL 1
> -+
> - /* Use Glibc's sockets headers */
> - #define LWIP_STD_SOCKETS 1
> - #define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS 0
> +
> ++/* We're using lwip_poll() */
> ++#define LWIP_POLL 1
> ++
> + /* Use Glibc's sockets headers */
> + #define LWIP_STD_SOCKETS 1
> + #define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
> --- a/port/include/arch/cc.h
> +++ b/port/include/arch/cc.h
> -@@ -46,6 +46,9 @@
> - #include <netinet/tcp.h>
> - #include <netinet/udp.h>
> -
> -+/* We use poll() instead of select()*/
> -+#include <poll.h>
> -+
> - /* Use our own htons() and pals */
> - #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> -
> +@@ -40,6 +40,9 @@
> + /* Use our own ioctls */
> + #include <sys/ioctl.h>
> +
> ++/* We use poll() instead of select()*/
> ++#include <poll.h>
> ++
> + /* Use our own htons() and pals */
> + #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> +
> diff --git a/debian/patches/port b/debian/patches/port
> index c6c9d82..b0ab392 100644
> --- a/debian/patches/port
> +++ b/debian/patches/port
> @@ -3,1022 +3,941 @@ Not intended to be upstream
> --- /dev/null
> +++ b/port/include/arch/cc.h
> @@ -0,0 +1,68 @@
> -+/*
> -+ Copyright (C) 2017 Free Software Foundation, Inc.
> -+ Written by Joan Lledó.
> -+
> -+ This file is part of the GNU Hurd.
> -+
> -+ The GNU Hurd is free software; you can redistribute it and/or
> -+ modify it under the terms of the GNU General Public License as
> -+ published by the Free Software Foundation; either version 2, or (at
> -+ your option) any later version.
> -+
> -+ The GNU Hurd is distributed in the hope that it will be useful, but
> -+ WITHOUT ANY WARRANTY; without even the implied warranty of
> -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+ General Public License for more details.
> -+
> -+ You should have received a copy of the GNU General Public License
> -+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> -+
> -+#ifndef LWIP_ARCH_CC_H
> -+#define LWIP_ARCH_CC_H
> -+
> -+#include <stdlib.h> /* rand() */
> -+#include <stdio.h> /* printf() */
> -+
> -+/* Use Glibc's fcntl() macros */
> -+#include <fcntl.h>
> -+
> -+/* Use Glibc's <errno.h> */
> -+#include <errno.h>
> -+#define LWIP_ERR_T int
> -+
> -+/* System provides its own struct timeval */
> -+#define LWIP_TIMEVAL_PRIVATE 0
> -+#include <sys/time.h>
> -+
> -+/* We need INT_MAX */
> -+#include <limits.h>
> -+
> -+/* Use our own ioctls */
> -+#include <sys/ioctl.h>
> -+
> -+/* Use our own htons() and pals */
> -+#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> -+
> -+/* printf() codes */
> -+#define S16_F "d"
> -+#define U16_F "u"
> -+#define X16_F "x"
> -+
> -+#define S32_F "d"
> -+#define U32_F "u"
> -+#define X32_F "x"
> -+
> -+#ifdef LWIP_DEBUG
> -+#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
> -+#endif
> -+
> -+/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
> -+#define LWIP_ERROR(message, expression, handler) \
> -+ do { \
> -+ if (!(expression)) { \
> -+ printf("Assertion \"%s\" failed at line %d in %s\n", \
> -+ message, __LINE__, __FILE__); fflush(NULL); \
> -+ handler;} \
> -+ } while(0)
> -+
> -+#endif /* LWIP_ARCH_CC_H */
> ++/*
> ++ Copyright (C) 2017 Free Software Foundation, Inc.
> ++ Written by Joan Lledó.
> ++
> ++ This file is part of the GNU Hurd.
> ++
> ++ The GNU Hurd is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU General Public License as
> ++ published by the Free Software Foundation; either version 2, or (at
> ++ your option) any later version.
> ++
> ++ The GNU Hurd is distributed in the hope that it will be useful, but
> ++ WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> ++ General Public License for more details.
> ++
> ++ You should have received a copy of the GNU General Public License
> ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> ++
> ++#ifndef LWIP_ARCH_CC_H
> ++#define LWIP_ARCH_CC_H
> ++
> ++#include <stdlib.h> /* rand() */
> ++#include <stdio.h> /* printf() */
> ++
> ++/* Use Glibc's fcntl() macros */
> ++#include <fcntl.h>
> ++
> ++/* Use Glibc's <errno.h> */
> ++#include <errno.h>
> ++#define LWIP_ERR_T int
> ++
> ++/* System provides its own struct timeval */
> ++#define LWIP_TIMEVAL_PRIVATE 0
> ++#include <sys/time.h>
> ++
> ++/* We need INT_MAX */
> ++#include <limits.h>
> ++
> ++/* Use our own ioctls */
> ++#include <sys/ioctl.h>
> ++
> ++/* Use our own htons() and pals */
> ++#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> ++
> ++/* printf() codes */
> ++#define S16_F "d"
> ++#define U16_F "u"
> ++#define X16_F "x"
> ++
> ++#define S32_F "d"
> ++#define U32_F "u"
> ++#define X32_F "x"
> ++
> ++#ifdef LWIP_DEBUG
> ++#define LWIP_PLATFORM_DIAG(x) do { printf x; fflush(NULL);} while(0)
> ++#endif
> ++
> ++/* Redefine LWIP_ERROR to not abort the process if the assertion failed */
> ++#define LWIP_ERROR(message, expression, handler) \
> ++ do { \
> ++ if (!(expression)) { \
> ++ printf("Assertion \"%s\" failed at line %d in %s\n", \
> ++ message, __LINE__, __FILE__); fflush(NULL); \
> ++ handler;} \
> ++ } while(0)
> ++
> ++#endif /* LWIP_ARCH_CC_H */
> --- /dev/null
> +++ b/port/include/arch/sys_arch.h
> -@@ -0,0 +1,64 @@
> -+/*
> -+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ * this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> -+ * this list of conditions and the following disclaimer in the
> documentation
> -+ * and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ * derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+#ifndef LWIP_ARCH_SYS_ARCH_H
> -+#define LWIP_ARCH_SYS_ARCH_H
> -+
> -+#define SYS_MBOX_NULL NULL
> -+#define SYS_SEM_NULL NULL
> -+
> -+/* Return code for an interrupted timed wait */
> -+#define SYS_ARCH_INTR 0xfffffffeUL
> -+
> -+typedef u32_t sys_prot_t;
> -+
> -+struct sys_sem;
> -+typedef struct sys_sem * sys_sem_t;
> -+#define sys_sem_valid(sem) (*(sem) != NULL)
> -+#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL;
> }}while(0)
> -+
> -+struct sys_mutex;
> -+typedef struct sys_mutex * sys_mutex_t;
> -+#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
> -+#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
> -+
> -+struct sys_mbox;
> -+typedef struct sys_mbox * sys_mbox_t;
> -+#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
> -+#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
> -+
> -+struct sys_thread;
> -+typedef struct sys_thread * sys_thread_t;
> -+
> -+u32_t sys_arch_sem_wait_intr(sys_sem_t *sem, u32_t timeout);
> -+
> -+#endif /* LWIP_ARCH_SYS_ARCH_H */
> -+
> +@@ -0,0 +1,62 @@
> ++/*
> ++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ * this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> ++ * this list of conditions and the following disclaimer in the
> documentation
> ++ * and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ * derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++#ifndef LWIP_ARCH_SYS_ARCH_H
> ++#define LWIP_ARCH_SYS_ARCH_H
> ++
> ++#define SYS_MBOX_NULL NULL
> ++#define SYS_SEM_NULL NULL
> ++
> ++/* Return code for an interrupted timed wait */
> ++#define SYS_ARCH_INTR 0xfffffffeUL
> ++
> ++typedef u32_t sys_prot_t;
> ++
> ++struct sys_sem;
> ++typedef struct sys_sem * sys_sem_t;
> ++#define sys_sem_valid(sem) (*(sem) != NULL)
> ++#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL;
> }}while(0)
> ++
> ++struct sys_mutex;
> ++typedef struct sys_mutex * sys_mutex_t;
> ++#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
> ++#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
> ++
> ++struct sys_mbox;
> ++typedef struct sys_mbox * sys_mbox_t;
> ++#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
> ++#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
> ++
> ++struct sys_thread;
> ++typedef struct sys_thread * sys_thread_t;
> ++
> ++#endif /* LWIP_ARCH_SYS_ARCH_H */
> ++
> --- /dev/null
> +++ b/port/include/lwipopts.h
> @@ -0,0 +1,131 @@
> -+/*
> -+ Copyright (C) 2017 Free Software Foundation, Inc.
> -+ Written by Joan Lledó.
> -+
> -+ This file is part of the GNU Hurd.
> -+
> -+ The GNU Hurd is free software; you can redistribute it and/or
> -+ modify it under the terms of the GNU General Public License as
> -+ published by the Free Software Foundation; either version 2, or (at
> -+ your option) any later version.
> -+
> -+ The GNU Hurd is distributed in the hope that it will be useful, but
> -+ WITHOUT ANY WARRANTY; without even the implied warranty of
> -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+ General Public License for more details.
> -+
> -+ You should have received a copy of the GNU General Public License
> -+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> -+
> -+#ifndef HURD_LWIP_LWIPOPTS_H
> -+#define HURD_LWIP_LWIPOPTS_H
> -+
> -+/* An OS is present */
> -+#define NO_SYS 0
> -+
> -+/* Don't rename Sockets API functions */
> -+#define LWIP_COMPAT_SOCKETS 0
> -+
> -+/* Use Glibc malloc()/free() */
> -+#define MEM_LIBC_MALLOC 1
> -+#define MEMP_MEM_MALLOC 1
> -+#define MEM_USE_POOLS 0
> -+#define MEM_ALIGNMENT 4
> -+
> -+/* Only send complete packets to the device */
> -+#define LWIP_NETIF_TX_SINGLE_PBUF 1
> -+
> -+/* Randomize local ports */
> -+#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
> -+
> -+/* Glibc sends more than one packet in a row during an ARP resolution */
> -+#define ARP_QUEUEING 1
> -+#define ARP_QUEUE_LEN 10
> -+
> -+/* Netif API is needed to add or remove interfaces on run time */
> -+#define LWIP_NETIF_API 1
> -+
> -+/* IPv4 stuff */
> -+#define IP_FORWARD 1
> -+
> -+/* SLAAC support and other IPv6 stuff */
> -+#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
> -+#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
> -+#define LWIP_IPV6_AUTOCONFIG 1
> -+#define LWIP_IPV6_FORWARD 1
> -+#define MEMP_NUM_MLD6_GROUP 16
> -+#define LWIP_IPV6_NUM_ADDRESSES 6
> -+
> -+/* TCP tuning */
> -+#define TCP_MSS 1460
> -+#define TCP_WND 0xFFFF
> -+#define TCP_SND_BUF TCP_WND
> -+
> -+/* Throughput settings */
> -+#define LWIP_CHECKSUM_ON_COPY 1
> -+
> -+/* Disable stats */
> -+#define LWIP_STATS 0
> -+#define LWIP_STATS_DISPLAY 0
> -+
> -+/* Enable all socket operations */
> -+#define LWIP_TCP_KEEPALIVE 1
> -+#define LWIP_SO_SNDTIMEO 1
> -+#define LWIP_SO_RCVTIMEO 1
> -+#define LWIP_SO_RCVBUF 1
> -+#define LWIP_SO_LINGER 1
> -+#define SO_REUSE 1
> -+#define LWIP_MULTICAST_TX_OPTIONS 1
> -+
> -+/* Enable modules */
> -+#define LWIP_ARP 1
> -+#define LWIP_ETHERNET 1
> -+#define LWIP_IPV4 1
> -+#define LWIP_ICMP 1
> -+#define LWIP_IGMP 1
> -+#define LWIP_RAW 1
> -+#define LWIP_UDP 1
> -+#define LWIP_UDPLITE 1
> -+#define LWIP_TCP 1
> -+#define LWIP_IPV6 1
> -+#define LWIP_ICMP6 1
> -+#define LWIP_IPV6_MLD 1
> -+#define LWIP_NETIF_LOOPBACK 1
> -+
> -+/* Debug mode */
> -+#ifdef LWIP_DEBUG
> -+#define ETHARP_DEBUG LWIP_DBG_OFF
> -+#define NETIF_DEBUG LWIP_DBG_OFF
> -+#define PBUF_DEBUG LWIP_DBG_OFF
> -+#define API_LIB_DEBUG LWIP_DBG_OFF
> -+#define API_MSG_DEBUG LWIP_DBG_OFF
> -+#define SOCKETS_DEBUG LWIP_DBG_OFF
> -+#define ICMP_DEBUG LWIP_DBG_OFF
> -+#define IGMP_DEBUG LWIP_DBG_OFF
> -+#define INET_DEBUG LWIP_DBG_OFF
> -+#define IP_DEBUG LWIP_DBG_OFF
> -+#define IP_REASS_DEBUG LWIP_DBG_OFF
> -+#define RAW_DEBUG LWIP_DBG_OFF
> -+#define MEM_DEBUG LWIP_DBG_OFF
> -+#define MEMP_DEBUG LWIP_DBG_OFF
> -+#define SYS_DEBUG LWIP_DBG_OFF
> -+#define TIMERS_DEBUG LWIP_DBG_OFF
> -+#define TCP_DEBUG LWIP_DBG_OFF
> -+#define TCP_INPUT_DEBUG LWIP_DBG_OFF
> -+#define TCP_FR_DEBUG LWIP_DBG_OFF
> -+#define TCP_RTO_DEBUG LWIP_DBG_OFF
> -+#define TCP_CWND_DEBUG LWIP_DBG_OFF
> -+#define TCP_WND_DEBUG LWIP_DBG_OFF
> -+#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
> -+#define TCP_RST_DEBUG LWIP_DBG_OFF
> -+#define TCP_QLEN_DEBUG LWIP_DBG_OFF
> -+#define UDP_DEBUG LWIP_DBG_OFF
> -+#define TCPIP_DEBUG LWIP_DBG_OFF
> -+#define SLIP_DEBUG LWIP_DBG_OFF
> -+#define DHCP_DEBUG LWIP_DBG_OFF
> -+#define AUTOIP_DEBUG LWIP_DBG_OFF
> -+#define DNS_DEBUG LWIP_DBG_OFF
> -+#define IP6_DEBUG LWIP_DBG_OFF
> -+#endif
> -+
> -+#endif
> ++/*
> ++ Copyright (C) 2017 Free Software Foundation, Inc.
> ++ Written by Joan Lledó.
> ++
> ++ This file is part of the GNU Hurd.
> ++
> ++ The GNU Hurd is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU General Public License as
> ++ published by the Free Software Foundation; either version 2, or (at
> ++ your option) any later version.
> ++
> ++ The GNU Hurd is distributed in the hope that it will be useful, but
> ++ WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> ++ General Public License for more details.
> ++
> ++ You should have received a copy of the GNU General Public License
> ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> ++
> ++#ifndef HURD_LWIP_LWIPOPTS_H
> ++#define HURD_LWIP_LWIPOPTS_H
> ++
> ++/* An OS is present */
> ++#define NO_SYS 0
> ++
> ++/* Don't rename Sockets API functions */
> ++#define LWIP_COMPAT_SOCKETS 0
> ++
> ++/* Use Glibc malloc()/free() */
> ++#define MEM_LIBC_MALLOC 1
> ++#define MEMP_MEM_MALLOC 1
> ++#define MEM_USE_POOLS 0
> ++#define MEM_ALIGNMENT 4
> ++
> ++/* Only send complete packets to the device */
> ++#define LWIP_NETIF_TX_SINGLE_PBUF 1
> ++
> ++/* Randomize local ports */
> ++#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
> ++
> ++/* Glibc sends more than one packet in a row during an ARP resolution */
> ++#define ARP_QUEUEING 1
> ++#define ARP_QUEUE_LEN 10
> ++
> ++/* Netif API is needed to add or remove interfaces on run time */
> ++#define LWIP_NETIF_API 1
> ++
> ++/* IPv4 stuff */
> ++#define IP_FORWARD 1
> ++
> ++/* SLAAC support and other IPv6 stuff */
> ++#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1
> ++#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
> ++#define LWIP_IPV6_AUTOCONFIG 1
> ++#define LWIP_IPV6_FORWARD 1
> ++#define MEMP_NUM_MLD6_GROUP 16
> ++#define LWIP_IPV6_NUM_ADDRESSES 6
> ++
> ++/* TCP tuning */
> ++#define TCP_MSS 1460
> ++#define TCP_WND 0xFFFF
> ++#define TCP_SND_BUF TCP_WND
> ++
> ++/* Throughput settings */
> ++#define LWIP_CHECKSUM_ON_COPY 1
> ++
> ++/* Disable stats */
> ++#define LWIP_STATS 0
> ++#define LWIP_STATS_DISPLAY 0
> ++
> ++/* Enable all socket operations */
> ++#define LWIP_TCP_KEEPALIVE 1
> ++#define LWIP_SO_SNDTIMEO 1
> ++#define LWIP_SO_RCVTIMEO 1
> ++#define LWIP_SO_RCVBUF 1
> ++#define LWIP_SO_LINGER 1
> ++#define SO_REUSE 1
> ++#define LWIP_MULTICAST_TX_OPTIONS 1
> ++
> ++/* Enable modules */
> ++#define LWIP_ARP 1
> ++#define LWIP_ETHERNET 1
> ++#define LWIP_IPV4 1
> ++#define LWIP_ICMP 1
> ++#define LWIP_IGMP 1
> ++#define LWIP_RAW 1
> ++#define LWIP_UDP 1
> ++#define LWIP_UDPLITE 1
> ++#define LWIP_TCP 1
> ++#define LWIP_IPV6 1
> ++#define LWIP_ICMP6 1
> ++#define LWIP_IPV6_MLD 1
> ++#define LWIP_NETIF_LOOPBACK 1
> ++
> ++/* Debug mode */
> ++#ifdef LWIP_DEBUG
> ++#define ETHARP_DEBUG LWIP_DBG_OFF
> ++#define NETIF_DEBUG LWIP_DBG_OFF
> ++#define PBUF_DEBUG LWIP_DBG_OFF
> ++#define API_LIB_DEBUG LWIP_DBG_OFF
> ++#define API_MSG_DEBUG LWIP_DBG_OFF
> ++#define SOCKETS_DEBUG LWIP_DBG_OFF
> ++#define ICMP_DEBUG LWIP_DBG_OFF
> ++#define IGMP_DEBUG LWIP_DBG_OFF
> ++#define INET_DEBUG LWIP_DBG_OFF
> ++#define IP_DEBUG LWIP_DBG_OFF
> ++#define IP_REASS_DEBUG LWIP_DBG_OFF
> ++#define RAW_DEBUG LWIP_DBG_OFF
> ++#define MEM_DEBUG LWIP_DBG_OFF
> ++#define MEMP_DEBUG LWIP_DBG_OFF
> ++#define SYS_DEBUG LWIP_DBG_OFF
> ++#define TIMERS_DEBUG LWIP_DBG_OFF
> ++#define TCP_DEBUG LWIP_DBG_OFF
> ++#define TCP_INPUT_DEBUG LWIP_DBG_OFF
> ++#define TCP_FR_DEBUG LWIP_DBG_OFF
> ++#define TCP_RTO_DEBUG LWIP_DBG_OFF
> ++#define TCP_CWND_DEBUG LWIP_DBG_OFF
> ++#define TCP_WND_DEBUG LWIP_DBG_OFF
> ++#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
> ++#define TCP_RST_DEBUG LWIP_DBG_OFF
> ++#define TCP_QLEN_DEBUG LWIP_DBG_OFF
> ++#define UDP_DEBUG LWIP_DBG_OFF
> ++#define TCPIP_DEBUG LWIP_DBG_OFF
> ++#define SLIP_DEBUG LWIP_DBG_OFF
> ++#define DHCP_DEBUG LWIP_DBG_OFF
> ++#define AUTOIP_DEBUG LWIP_DBG_OFF
> ++#define DNS_DEBUG LWIP_DBG_OFF
> ++#define IP6_DEBUG LWIP_DBG_OFF
> ++#endif
> ++
> ++#endif
> --- /dev/null
> +++ b/port/sys_arch.c
> -@@ -0,0 +1,747 @@
> -+/*
> -+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ * this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> -+ * this list of conditions and the following disclaimer in the
> documentation
> -+ * and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ * derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+
> -+/*
> -+ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
> -+ *
> -+ * - Fixed an unlikely sys_thread_new() race condition.
> -+ *
> -+ * - Made current_thread() work with threads which where
> -+ * not created with sys_thread_new(). This includes
> -+ * the main thread and threads made with pthread_create().
> -+ *
> -+ * - Catch overflows where more than SYS_MBOX_SIZE messages
> -+ * are waiting to be read. The sys_mbox_post() routine
> -+ * will block until there is more room instead of just
> -+ * leaking messages.
> -+ */
> -+#include "lwip/debug.h"
> -+
> -+#include <string.h>
> -+#include <sys/time.h>
> -+#include <sys/types.h>
> -+#include <stdlib.h>
> -+#include <unistd.h>
> -+#include <pthread.h>
> -+
> -+#include "lwip/def.h"
> -+
> -+#ifdef LWIP_UNIX_MACH
> -+#include <mach/mach.h>
> -+#include <mach/mach_time.h>
> -+#endif
> -+
> -+#include "lwip/sys.h"
> -+#include "lwip/opt.h"
> -+#include "lwip/stats.h"
> -+
> -+static void
> -+get_monotonic_time(struct timespec *ts)
> -+{
> -+#ifdef LWIP_UNIX_MACH
> -+ /* darwin impl (no CLOCK_MONOTONIC) */
> -+ uint64_t t = mach_absolute_time();
> -+ mach_timebase_info_data_t timebase_info = {0, 0};
> -+ mach_timebase_info(&timebase_info);
> -+ uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
> -+ uint64_t sec = nano/1000000000L;
> -+ nano -= sec * 1000000000L;
> -+ ts->tv_sec = sec;
> -+ ts->tv_nsec = nano;
> -+#else
> -+ clock_gettime(CLOCK_MONOTONIC, ts);
> -+#endif
> -+}
> -+
> -+#if !NO_SYS
> -+
> -+static struct sys_thread *threads = NULL;
> -+static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
> -+
> -+struct sys_mbox_msg {
> -+ struct sys_mbox_msg *next;
> -+ void *msg;
> -+};
> -+
> -+#define SYS_MBOX_SIZE 128
> -+
> -+struct sys_mbox {
> -+ int first, last;
> -+ void *msgs[SYS_MBOX_SIZE];
> -+ struct sys_sem *not_empty;
> -+ struct sys_sem *not_full;
> -+ struct sys_sem *mutex;
> -+ int wait_send;
> -+};
> -+
> -+struct sys_sem {
> -+ unsigned int c;
> -+ pthread_condattr_t condattr;
> -+ pthread_cond_t cond;
> -+ pthread_mutex_t mutex;
> -+};
> -+
> -+struct sys_mutex {
> -+ pthread_mutex_t mutex;
> -+};
> -+
> -+struct sys_thread {
> -+ struct sys_thread *next;
> -+ pthread_t pthread;
> -+};
> -+
> -+#if SYS_LIGHTWEIGHT_PROT
> -+static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
> -+static pthread_t lwprot_thread = (pthread_t)0xDEAD;
> -+static int lwprot_count = 0;
> -+#endif /* SYS_LIGHTWEIGHT_PROT */
> -+
> -+static struct sys_sem *sys_sem_new_internal(u8_t count);
> -+static void sys_sem_free_internal(struct sys_sem *sem);
> -+
> -+static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
> -+ u32_t timeout);
> -+
> -+static u32_t cond_wait_intr(pthread_cond_t * cond, pthread_mutex_t * mutex,
> -+ u32_t timeout);
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Threads */
> -+static struct sys_thread *
> -+introduce_thread(pthread_t id)
> -+{
> -+ struct sys_thread *thread;
> -+
> -+ thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
> -+
> -+ if (thread != NULL) {
> -+ pthread_mutex_lock(&threads_mutex);
> -+ thread->next = threads;
> -+ thread->pthread = id;
> -+ threads = thread;
> -+ pthread_mutex_unlock(&threads_mutex);
> -+ }
> -+
> -+ return thread;
> -+}
> -+
> -+sys_thread_t
> -+sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int
> stacksize, int prio)
> -+{
> -+ int code;
> -+ pthread_t tmp;
> -+ struct sys_thread *st = NULL;
> -+ LWIP_UNUSED_ARG(name);
> -+ LWIP_UNUSED_ARG(stacksize);
> -+ LWIP_UNUSED_ARG(prio);
> -+
> -+ code = pthread_create(&tmp,
> -+ NULL,
> -+ (void *(*)(void *))
> -+ function,
> -+ arg);
> -+
> -+ if (0 == code) {
> -+ st = introduce_thread(tmp);
> -+ }
> -+
> -+ if (NULL == st) {
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
> -+ code, (unsigned long)st));
> -+ abort();
> -+ }
> -+ return st;
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Mailbox */
> -+err_t
> -+sys_mbox_new(struct sys_mbox **mb, int size)
> -+{
> -+ struct sys_mbox *mbox;
> -+ LWIP_UNUSED_ARG(size);
> -+
> -+ mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
> -+ if (mbox == NULL) {
> -+ return ERR_MEM;
> -+ }
> -+ mbox->first = mbox->last = 0;
> -+ mbox->not_empty = sys_sem_new_internal(0);
> -+ mbox->not_full = sys_sem_new_internal(0);
> -+ mbox->mutex = sys_sem_new_internal(1);
> -+ mbox->wait_send = 0;
> -+
> -+ SYS_STATS_INC_USED(mbox);
> -+ *mb = mbox;
> -+ return ERR_OK;
> -+}
> -+
> -+void
> -+sys_mbox_free(struct sys_mbox **mb)
> -+{
> -+ if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
> -+ struct sys_mbox *mbox = *mb;
> -+ SYS_STATS_DEC(mbox.used);
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+ sys_sem_free_internal(mbox->not_empty);
> -+ sys_sem_free_internal(mbox->not_full);
> -+ sys_sem_free_internal(mbox->mutex);
> -+ mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
> -+ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
> -+ free(mbox);
> -+ }
> -+}
> -+
> -+err_t
> -+sys_mbox_trypost(struct sys_mbox **mb, void *msg)
> -+{
> -+ u8_t first;
> -+ struct sys_mbox *mbox;
> -+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+ mbox = *mb;
> -+
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
> -+ (void *)mbox, (void *)msg));
> -+
> -+ if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> -+ sys_sem_signal(&mbox->mutex);
> -+ return ERR_MEM;
> -+ }
> -+
> -+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> -+
> -+ if (mbox->last == mbox->first) {
> -+ first = 1;
> -+ } else {
> -+ first = 0;
> -+ }
> -+
> -+ mbox->last++;
> -+
> -+ if (first) {
> -+ sys_sem_signal(&mbox->not_empty);
> -+ }
> -+
> -+ sys_sem_signal(&mbox->mutex);
> -+
> -+ return ERR_OK;
> -+}
> -+
> -+void
> -+sys_mbox_post(struct sys_mbox **mb, void *msg)
> -+{
> -+ u8_t first;
> -+ struct sys_mbox *mbox;
> -+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+ mbox = *mb;
> -+
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox,
> (void *)msg));
> -+
> -+ while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> -+ mbox->wait_send++;
> -+ sys_sem_signal(&mbox->mutex);
> -+ sys_arch_sem_wait(&mbox->not_full, 0);
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+ mbox->wait_send--;
> -+ }
> -+
> -+ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> -+
> -+ if (mbox->last == mbox->first) {
> -+ first = 1;
> -+ } else {
> -+ first = 0;
> -+ }
> -+
> -+ mbox->last++;
> -+
> -+ if (first) {
> -+ sys_sem_signal(&mbox->not_empty);
> -+ }
> -+
> -+ sys_sem_signal(&mbox->mutex);
> -+}
> -+
> -+u32_t
> -+sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
> -+{
> -+ struct sys_mbox *mbox;
> -+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+ mbox = *mb;
> -+
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+ if (mbox->first == mbox->last) {
> -+ sys_sem_signal(&mbox->mutex);
> -+ return SYS_MBOX_EMPTY;
> -+ }
> -+
> -+ if (msg != NULL) {
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void
> *)mbox, *msg));
> -+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> -+ }
> -+ else{
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void
> *)mbox));
> -+ }
> -+
> -+ mbox->first++;
> -+
> -+ if (mbox->wait_send) {
> -+ sys_sem_signal(&mbox->not_full);
> -+ }
> -+
> -+ sys_sem_signal(&mbox->mutex);
> -+
> -+ return 0;
> -+}
> -+
> -+u32_t
> -+sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
> -+{
> -+ u32_t time_needed = 0;
> -+ struct sys_mbox *mbox;
> -+ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> -+ mbox = *mb;
> -+
> -+ /* The mutex lock is quick so we don't bother with the timeout
> -+ stuff here. */
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+
> -+ while (mbox->first == mbox->last) {
> -+ sys_sem_signal(&mbox->mutex);
> -+
> -+ /* We block while waiting for a mail to arrive in the mailbox. We
> -+ must be prepared to timeout. */
> -+ if (timeout != 0) {
> -+ time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
> -+
> -+ if (time_needed == SYS_ARCH_TIMEOUT) {
> -+ return SYS_ARCH_TIMEOUT;
> -+ }
> -+ } else {
> -+ sys_arch_sem_wait(&mbox->not_empty, 0);
> -+ }
> -+
> -+ sys_arch_sem_wait(&mbox->mutex, 0);
> -+ }
> -+
> -+ if (msg != NULL) {
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void
> *)mbox, *msg));
> -+ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> -+ }
> -+ else{
> -+ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void
> *)mbox));
> -+ }
> -+
> -+ mbox->first++;
> -+
> -+ if (mbox->wait_send) {
> -+ sys_sem_signal(&mbox->not_full);
> -+ }
> -+
> -+ sys_sem_signal(&mbox->mutex);
> -+
> -+ return time_needed;
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Semaphore */
> -+static struct sys_sem *
> -+sys_sem_new_internal(u8_t count)
> -+{
> -+ struct sys_sem *sem;
> -+
> -+ sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
> -+ if (sem != NULL) {
> -+ sem->c = count;
> -+ pthread_condattr_init(&(sem->condattr));
> -+#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) &&
> __ANDROID_API__ < 21))
> -+ pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
> -+#endif
> -+ pthread_cond_init(&(sem->cond), &(sem->condattr));
> -+ pthread_mutex_init(&(sem->mutex), NULL);
> -+ }
> -+ return sem;
> -+}
> -+
> -+err_t
> -+sys_sem_new(struct sys_sem **sem, u8_t count)
> -+{
> -+ SYS_STATS_INC_USED(sem);
> -+ *sem = sys_sem_new_internal(count);
> -+ if (*sem == NULL) {
> -+ return ERR_MEM;
> -+ }
> -+ return ERR_OK;
> -+}
> -+
> -+static u32_t
> -+cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> -+{
> -+ struct timespec rtime1, rtime2, ts;
> -+ int ret;
> -+
> -+ if (timeout == 0) {
> -+ pthread_cond_wait(cond, mutex);
> -+ return 0;
> -+ }
> -+
> -+ /* Get a timestamp and add the timeout value. */
> -+ get_monotonic_time(&rtime1);
> -+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) &&
> __ANDROID_API__ < 21)
> -+ ts.tv_sec = timeout / 1000L;
> -+ ts.tv_nsec = (timeout % 1000L) * 1000000L;
> -+ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> -+#else
> -+ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> -+ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> -+ if (ts.tv_nsec >= 1000000000L) {
> -+ ts.tv_sec++;
> -+ ts.tv_nsec -= 1000000000L;
> -+ }
> -+
> -+ ret = pthread_cond_timedwait(cond, mutex, &ts);
> -+#endif
> -+ if (ret == ETIMEDOUT) {
> -+ return SYS_ARCH_TIMEOUT;
> -+ }
> -+
> -+ /* Calculate for how long we waited for the cond. */
> -+ get_monotonic_time(&rtime2);
> -+ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> -+ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> -+ if (ts.tv_nsec < 0) {
> -+ ts.tv_sec--;
> -+ ts.tv_nsec += 1000000000L;
> -+ }
> -+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+u32_t
> -+sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
> -+{
> -+ u32_t time_needed = 0;
> -+ struct sys_sem *sem;
> -+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+ sem = *s;
> -+
> -+ pthread_mutex_lock(&(sem->mutex));
> -+ while (sem->c <= 0) {
> -+ if (timeout > 0) {
> -+ time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
> -+
> -+ if (time_needed == SYS_ARCH_TIMEOUT) {
> -+ pthread_mutex_unlock(&(sem->mutex));
> -+ return SYS_ARCH_TIMEOUT;
> -+ }
> -+ /* pthread_mutex_unlock(&(sem->mutex));
> -+ return time_needed; */
> -+ } else {
> -+ cond_wait(&(sem->cond), &(sem->mutex), 0);
> -+ }
> -+ }
> -+ sem->c--;
> -+ pthread_mutex_unlock(&(sem->mutex));
> -+ return (u32_t)time_needed;
> -+}
> -+
> -+/*
> -+ * Like cond_wait(), but it calls Hurd's non portable
> -+ * functions to receive cancellation requests
> -+ */
> -+static u32_t
> -+cond_wait_intr(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> -+{
> -+ struct timespec rtime1, rtime2, ts;
> -+ int ret;
> -+
> -+#ifdef __GNU__
> -+ #define pthread_cond_wait pthread_hurd_cond_wait_np
> -+ #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
> -+#endif
> -+
> -+ if (timeout == 0) {
> -+ ret = pthread_cond_wait(cond, mutex);
> -+ return ret;
> -+ }
> -+
> -+ /* Get a timestamp and add the timeout value. */
> -+ get_monotonic_time(&rtime1);
> -+#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) &&
> __ANDROID_API__ < 21)
> -+ ts.tv_sec = timeout / 1000L;
> -+ ts.tv_nsec = (timeout % 1000L) * 1000000L;
> -+ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> -+#else
> -+ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> -+ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> -+ if (ts.tv_nsec >= 1000000000L) {
> -+ ts.tv_sec++;
> -+ ts.tv_nsec -= 1000000000L;
> -+ }
> -+
> -+ ret = pthread_cond_timedwait(cond, mutex, &ts);
> -+#endif
> -+ if (ret == ETIMEDOUT) {
> -+ return SYS_ARCH_TIMEOUT;
> -+ } else if (ret == EINTR) {
> -+ return SYS_ARCH_INTR;
> -+ }
> -+
> -+ /* Calculate for how long we waited for the cond. */
> -+ get_monotonic_time(&rtime2);
> -+ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> -+ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> -+ if (ts.tv_nsec < 0) {
> -+ ts.tv_sec--;
> -+ ts.tv_nsec += 1000000000L;
> -+ }
> -+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+/*
> -+ * Like sys_arch_sem_wait(), but it handles thread cancellations.
> -+ */
> -+u32_t
> -+sys_arch_sem_wait_intr(struct sys_sem **s, u32_t timeout)
> -+{
> -+ u32_t time_needed = 0;
> -+ struct sys_sem *sem;
> -+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+ sem = *s;
> -+
> -+ pthread_mutex_lock(&(sem->mutex));
> -+ while (sem->c <= 0) {
> -+ if (timeout > 0) {
> -+ time_needed = cond_wait_intr(&(sem->cond), &(sem->mutex), timeout);
> -+
> -+ if (time_needed == SYS_ARCH_TIMEOUT) {
> -+ pthread_mutex_unlock(&(sem->mutex));
> -+ return SYS_ARCH_TIMEOUT;
> -+ } else if(time_needed == SYS_ARCH_INTR) {
> -+ /* This means we were interrupted, so don't wait again */
> -+ sem->c++;
> -+
> -+ if (sem->c > 1) {
> -+ sem->c = 1;
> -+ }
> -+ }
> -+ } else {
> -+ if(cond_wait_intr(&(sem->cond), &(sem->mutex), 0)) {
> -+ /* This means we were interrupted, so don't wait again */
> -+ sem->c++;
> -+
> -+ if (sem->c > 1) {
> -+ sem->c = 1;
> -+ }
> -+ }
> -+ }
> -+ }
> -+ sem->c--;
> -+ pthread_mutex_unlock(&(sem->mutex));
> -+ return (u32_t)time_needed;
> -+}
> -+
> -+void
> -+sys_sem_signal(struct sys_sem **s)
> -+{
> -+ struct sys_sem *sem;
> -+ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> -+ sem = *s;
> -+
> -+ pthread_mutex_lock(&(sem->mutex));
> -+ sem->c++;
> -+
> -+ if (sem->c > 1) {
> -+ sem->c = 1;
> -+ }
> -+
> -+ pthread_cond_broadcast(&(sem->cond));
> -+ pthread_mutex_unlock(&(sem->mutex));
> -+}
> -+
> -+static void
> -+sys_sem_free_internal(struct sys_sem *sem)
> -+{
> -+ pthread_cond_destroy(&(sem->cond));
> -+ pthread_condattr_destroy(&(sem->condattr));
> -+ pthread_mutex_destroy(&(sem->mutex));
> -+ free(sem);
> -+}
> -+
> -+void
> -+sys_sem_free(struct sys_sem **sem)
> -+{
> -+ if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
> -+ SYS_STATS_DEC(sem.used);
> -+ sys_sem_free_internal(*sem);
> -+ }
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Mutex */
> -+/** Create a new mutex
> -+ * @param mutex pointer to the mutex to create
> -+ * @return a new mutex */
> -+err_t
> -+sys_mutex_new(struct sys_mutex **mutex)
> -+{
> -+ struct sys_mutex *mtx;
> -+
> -+ mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
> -+ if (mtx != NULL) {
> -+ pthread_mutex_init(&(mtx->mutex), NULL);
> -+ *mutex = mtx;
> -+ return ERR_OK;
> -+ }
> -+ else {
> -+ return ERR_MEM;
> -+ }
> -+}
> -+
> -+/** Lock a mutex
> -+ * @param mutex the mutex to lock */
> -+void
> -+sys_mutex_lock(struct sys_mutex **mutex)
> -+{
> -+ pthread_mutex_lock(&((*mutex)->mutex));
> -+}
> -+
> -+/** Unlock a mutex
> -+ * @param mutex the mutex to unlock */
> -+void
> -+sys_mutex_unlock(struct sys_mutex **mutex)
> -+{
> -+ pthread_mutex_unlock(&((*mutex)->mutex));
> -+}
> -+
> -+/** Delete a mutex
> -+ * @param mutex the mutex to delete */
> -+void
> -+sys_mutex_free(struct sys_mutex **mutex)
> -+{
> -+ pthread_mutex_destroy(&((*mutex)->mutex));
> -+ free(*mutex);
> -+}
> -+
> -+#endif /* !NO_SYS */
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Time */
> -+u32_t
> -+sys_now(void)
> -+{
> -+ struct timespec ts;
> -+
> -+ get_monotonic_time(&ts);
> -+ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> -+}
> -+
> -+u32_t
> -+sys_jiffies(void)
> -+{
> -+ struct timespec ts;
> -+
> -+ get_monotonic_time(&ts);
> -+ return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Init */
> -+
> -+void
> -+sys_init(void)
> -+{
> -+}
> -+
> -+/*-----------------------------------------------------------------------------------*/
> -+/* Critical section */
> -+#if SYS_LIGHTWEIGHT_PROT
> -+/** sys_prot_t sys_arch_protect(void)
> -+
> -+This optional function does a "fast" critical region protection and returns
> -+the previous protection level. This function is only called during very
> short
> -+critical regions. An embedded system which supports ISR-based drivers might
> -+want to implement this function by disabling interrupts. Task-based systems
> -+might want to implement this by using a mutex or disabling tasking. This
> -+function should support recursive calls from the same task or interrupt. In
> -+other words, sys_arch_protect() could be called while already protected. In
> -+that case the return value indicates that it is already protected.
> -+
> -+sys_arch_protect() is only required if your port is supporting an operating
> -+system.
> -+*/
> -+sys_prot_t
> -+sys_arch_protect(void)
> -+{
> -+ /* Note that for the UNIX port, we are using a lightweight mutex, and
> our
> -+ * own counter (which is locked by the mutex). The return code is not
> actually
> -+ * used. */
> -+ if (lwprot_thread != pthread_self())
> -+ {
> -+ /* We are locking the mutex where it has not been locked before *
> -+ * or is being locked by another thread */
> -+ pthread_mutex_lock(&lwprot_mutex);
> -+ lwprot_thread = pthread_self();
> -+ lwprot_count = 1;
> -+ }
> -+ else
> -+ /* It is already locked by THIS thread */
> -+ lwprot_count++;
> -+ return 0;
> -+}
> -+
> -+/** void sys_arch_unprotect(sys_prot_t pval)
> -+
> -+This optional function does a "fast" set of critical region protection to
> the
> -+value specified by pval. See the documentation for sys_arch_protect() for
> -+more information. This function is only required if your port is supporting
> -+an operating system.
> -+*/
> -+void
> -+sys_arch_unprotect(sys_prot_t pval)
> -+{
> -+ LWIP_UNUSED_ARG(pval);
> -+ if (lwprot_thread == pthread_self())
> -+ {
> -+ if (--lwprot_count == 0)
> -+ {
> -+ lwprot_thread = (pthread_t) 0xDEAD;
> -+ pthread_mutex_unlock(&lwprot_mutex);
> -+ }
> -+ }
> -+}
> -+#endif /* SYS_LIGHTWEIGHT_PROT */
> +@@ -0,0 +1,668 @@
> ++/*
> ++ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ * this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> ++ * this list of conditions and the following disclaimer in the
> documentation
> ++ * and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ * derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++
> ++/*
> ++ * Wed Apr 17 16:05:29 EDT 2002 (James Roth)
> ++ *
> ++ * - Fixed an unlikely sys_thread_new() race condition.
> ++ *
> ++ * - Made current_thread() work with threads which where
> ++ * not created with sys_thread_new(). This includes
> ++ * the main thread and threads made with pthread_create().
> ++ *
> ++ * - Catch overflows where more than SYS_MBOX_SIZE messages
> ++ * are waiting to be read. The sys_mbox_post() routine
> ++ * will block until there is more room instead of just
> ++ * leaking messages.
> ++ */
> ++#include "lwip/debug.h"
> ++
> ++#include <string.h>
> ++#include <sys/time.h>
> ++#include <sys/types.h>
> ++#include <stdlib.h>
> ++#include <unistd.h>
> ++#include <pthread.h>
> ++
> ++#include "lwip/def.h"
> ++
> ++#ifdef LWIP_UNIX_MACH
> ++#include <mach/mach.h>
> ++#include <mach/mach_time.h>
> ++#endif
> ++
> ++#include "lwip/sys.h"
> ++#include "lwip/opt.h"
> ++#include "lwip/stats.h"
> ++
> ++static void
> ++get_monotonic_time(struct timespec *ts)
> ++{
> ++#ifdef LWIP_UNIX_MACH
> ++ /* darwin impl (no CLOCK_MONOTONIC) */
> ++ uint64_t t = mach_absolute_time();
> ++ mach_timebase_info_data_t timebase_info = {0, 0};
> ++ mach_timebase_info(&timebase_info);
> ++ uint64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
> ++ uint64_t sec = nano/1000000000L;
> ++ nano -= sec * 1000000000L;
> ++ ts->tv_sec = sec;
> ++ ts->tv_nsec = nano;
> ++#else
> ++ clock_gettime(CLOCK_MONOTONIC, ts);
> ++#endif
> ++}
> ++
> ++#if !NO_SYS
> ++
> ++static struct sys_thread *threads = NULL;
> ++static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
> ++
> ++struct sys_mbox_msg {
> ++ struct sys_mbox_msg *next;
> ++ void *msg;
> ++};
> ++
> ++#define SYS_MBOX_SIZE 128
> ++
> ++struct sys_mbox {
> ++ int first, last;
> ++ void *msgs[SYS_MBOX_SIZE];
> ++ struct sys_sem *not_empty;
> ++ struct sys_sem *not_full;
> ++ struct sys_sem *mutex;
> ++ int wait_send;
> ++};
> ++
> ++struct sys_sem {
> ++ unsigned int c;
> ++ pthread_condattr_t condattr;
> ++ pthread_cond_t cond;
> ++ pthread_mutex_t mutex;
> ++};
> ++
> ++struct sys_mutex {
> ++ pthread_mutex_t mutex;
> ++};
> ++
> ++struct sys_thread {
> ++ struct sys_thread *next;
> ++ pthread_t pthread;
> ++};
> ++
> ++#if SYS_LIGHTWEIGHT_PROT
> ++static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
> ++static pthread_t lwprot_thread = (pthread_t)0xDEAD;
> ++static int lwprot_count = 0;
> ++#endif /* SYS_LIGHTWEIGHT_PROT */
> ++
> ++static struct sys_sem *sys_sem_new_internal(u8_t count);
> ++static void sys_sem_free_internal(struct sys_sem *sem);
> ++
> ++static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
> ++ u32_t timeout);
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Threads */
> ++static struct sys_thread *
> ++introduce_thread(pthread_t id)
> ++{
> ++ struct sys_thread *thread;
> ++
> ++ thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
> ++
> ++ if (thread != NULL) {
> ++ pthread_mutex_lock(&threads_mutex);
> ++ thread->next = threads;
> ++ thread->pthread = id;
> ++ threads = thread;
> ++ pthread_mutex_unlock(&threads_mutex);
> ++ }
> ++
> ++ return thread;
> ++}
> ++
> ++sys_thread_t
> ++sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int
> stacksize, int prio)
> ++{
> ++ int code;
> ++ pthread_t tmp;
> ++ struct sys_thread *st = NULL;
> ++ LWIP_UNUSED_ARG(name);
> ++ LWIP_UNUSED_ARG(stacksize);
> ++ LWIP_UNUSED_ARG(prio);
> ++
> ++ code = pthread_create(&tmp,
> ++ NULL,
> ++ (void *(*)(void *))
> ++ function,
> ++ arg);
> ++
> ++ if (0 == code) {
> ++ st = introduce_thread(tmp);
> ++ }
> ++
> ++ if (NULL == st) {
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx",
> ++ code, (unsigned long)st));
> ++ abort();
> ++ }
> ++ return st;
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Mailbox */
> ++err_t
> ++sys_mbox_new(struct sys_mbox **mb, int size)
> ++{
> ++ struct sys_mbox *mbox;
> ++ LWIP_UNUSED_ARG(size);
> ++
> ++ mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
> ++ if (mbox == NULL) {
> ++ return ERR_MEM;
> ++ }
> ++ mbox->first = mbox->last = 0;
> ++ mbox->not_empty = sys_sem_new_internal(0);
> ++ mbox->not_full = sys_sem_new_internal(0);
> ++ mbox->mutex = sys_sem_new_internal(1);
> ++ mbox->wait_send = 0;
> ++
> ++ SYS_STATS_INC_USED(mbox);
> ++ *mb = mbox;
> ++ return ERR_OK;
> ++}
> ++
> ++void
> ++sys_mbox_free(struct sys_mbox **mb)
> ++{
> ++ if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
> ++ struct sys_mbox *mbox = *mb;
> ++ SYS_STATS_DEC(mbox.used);
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++ sys_sem_free_internal(mbox->not_empty);
> ++ sys_sem_free_internal(mbox->not_full);
> ++ sys_sem_free_internal(mbox->mutex);
> ++ mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
> ++ /* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
> ++ free(mbox);
> ++ }
> ++}
> ++
> ++err_t
> ++sys_mbox_trypost(struct sys_mbox **mb, void *msg)
> ++{
> ++ u8_t first;
> ++ struct sys_mbox *mbox;
> ++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++ mbox = *mb;
> ++
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
> ++ (void *)mbox, (void *)msg));
> ++
> ++ if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> ++ sys_sem_signal(&mbox->mutex);
> ++ return ERR_MEM;
> ++ }
> ++
> ++ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> ++
> ++ if (mbox->last == mbox->first) {
> ++ first = 1;
> ++ } else {
> ++ first = 0;
> ++ }
> ++
> ++ mbox->last++;
> ++
> ++ if (first) {
> ++ sys_sem_signal(&mbox->not_empty);
> ++ }
> ++
> ++ sys_sem_signal(&mbox->mutex);
> ++
> ++ return ERR_OK;
> ++}
> ++
> ++void
> ++sys_mbox_post(struct sys_mbox **mb, void *msg)
> ++{
> ++ u8_t first;
> ++ struct sys_mbox *mbox;
> ++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++ mbox = *mb;
> ++
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox,
> (void *)msg));
> ++
> ++ while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
> ++ mbox->wait_send++;
> ++ sys_sem_signal(&mbox->mutex);
> ++ sys_arch_sem_wait(&mbox->not_full, 0);
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++ mbox->wait_send--;
> ++ }
> ++
> ++ mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
> ++
> ++ if (mbox->last == mbox->first) {
> ++ first = 1;
> ++ } else {
> ++ first = 0;
> ++ }
> ++
> ++ mbox->last++;
> ++
> ++ if (first) {
> ++ sys_sem_signal(&mbox->not_empty);
> ++ }
> ++
> ++ sys_sem_signal(&mbox->mutex);
> ++}
> ++
> ++u32_t
> ++sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
> ++{
> ++ struct sys_mbox *mbox;
> ++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++ mbox = *mb;
> ++
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++ if (mbox->first == mbox->last) {
> ++ sys_sem_signal(&mbox->mutex);
> ++ return SYS_MBOX_EMPTY;
> ++ }
> ++
> ++ if (msg != NULL) {
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void
> *)mbox, *msg));
> ++ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> ++ }
> ++ else{
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void
> *)mbox));
> ++ }
> ++
> ++ mbox->first++;
> ++
> ++ if (mbox->wait_send) {
> ++ sys_sem_signal(&mbox->not_full);
> ++ }
> ++
> ++ sys_sem_signal(&mbox->mutex);
> ++
> ++ return 0;
> ++}
> ++
> ++u32_t
> ++sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
> ++{
> ++ u32_t time_needed = 0;
> ++ struct sys_mbox *mbox;
> ++ LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
> ++ mbox = *mb;
> ++
> ++ /* The mutex lock is quick so we don't bother with the timeout
> ++ stuff here. */
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++
> ++ while (mbox->first == mbox->last) {
> ++ sys_sem_signal(&mbox->mutex);
> ++
> ++ /* We block while waiting for a mail to arrive in the mailbox. We
> ++ must be prepared to timeout. */
> ++ if (timeout != 0) {
> ++ time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
> ++
> ++ if (time_needed == SYS_ARCH_TIMEOUT) {
> ++ return SYS_ARCH_TIMEOUT;
> ++ }
> ++ } else {
> ++ sys_arch_sem_wait(&mbox->not_empty, 0);
> ++ }
> ++
> ++ sys_arch_sem_wait(&mbox->mutex, 0);
> ++ }
> ++
> ++ if (msg != NULL) {
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void
> *)mbox, *msg));
> ++ *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
> ++ }
> ++ else{
> ++ LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void
> *)mbox));
> ++ }
> ++
> ++ mbox->first++;
> ++
> ++ if (mbox->wait_send) {
> ++ sys_sem_signal(&mbox->not_full);
> ++ }
> ++
> ++ sys_sem_signal(&mbox->mutex);
> ++
> ++ return time_needed;
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Semaphore */
> ++static struct sys_sem *
> ++sys_sem_new_internal(u8_t count)
> ++{
> ++ struct sys_sem *sem;
> ++
> ++ sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
> ++ if (sem != NULL) {
> ++ sem->c = count;
> ++ pthread_condattr_init(&(sem->condattr));
> ++#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) &&
> __ANDROID_API__ < 21))
> ++ pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
> ++#endif
> ++ pthread_cond_init(&(sem->cond), &(sem->condattr));
> ++ pthread_mutex_init(&(sem->mutex), NULL);
> ++ }
> ++ return sem;
> ++}
> ++
> ++err_t
> ++sys_sem_new(struct sys_sem **sem, u8_t count)
> ++{
> ++ SYS_STATS_INC_USED(sem);
> ++ *sem = sys_sem_new_internal(count);
> ++ if (*sem == NULL) {
> ++ return ERR_MEM;
> ++ }
> ++ return ERR_OK;
> ++}
> ++
> ++/*
> ++ * Like cond_wait(), but it calls Hurd's non portable
> ++ * functions to receive cancellation requests
> ++ */
> ++static u32_t
> ++cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
> ++{
> ++ struct timespec rtime1, rtime2, ts;
> ++ int ret;
> ++
> ++#ifdef __GNU__
> ++ #define pthread_cond_wait pthread_hurd_cond_wait_np
> ++ #define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
> ++#endif
> ++
> ++ if (timeout == 0) {
> ++ ret = pthread_cond_wait(cond, mutex);
> ++ return ret;
> ++ }
> ++
> ++ /* Get a timestamp and add the timeout value. */
> ++ get_monotonic_time(&rtime1);
> ++#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) &&
> __ANDROID_API__ < 21)
> ++ ts.tv_sec = timeout / 1000L;
> ++ ts.tv_nsec = (timeout % 1000L) * 1000000L;
> ++ ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
> ++#else
> ++ ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
> ++ ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
> ++ if (ts.tv_nsec >= 1000000000L) {
> ++ ts.tv_sec++;
> ++ ts.tv_nsec -= 1000000000L;
> ++ }
> ++
> ++ ret = pthread_cond_timedwait(cond, mutex, &ts);
> ++#endif
> ++ if (ret == ETIMEDOUT) {
> ++ return SYS_ARCH_TIMEOUT;
> ++ } else if (ret == EINTR) {
> ++ return SYS_ARCH_INTR;
> ++ }
> ++
> ++ /* Calculate for how long we waited for the cond. */
> ++ get_monotonic_time(&rtime2);
> ++ ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
> ++ ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
> ++ if (ts.tv_nsec < 0) {
> ++ ts.tv_sec--;
> ++ ts.tv_nsec += 1000000000L;
> ++ }
> ++ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> ++}
> ++
> ++/*
> ++ * Like sys_arch_sem_wait(), but it handles thread cancellations.
> ++ */
> ++u32_t
> ++sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
> ++{
> ++ u32_t time_needed = 0;
> ++ struct sys_sem *sem;
> ++ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> ++ sem = *s;
> ++
> ++ pthread_mutex_lock(&(sem->mutex));
> ++ while (sem->c <= 0) {
> ++ if (timeout > 0) {
> ++ time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
> ++
> ++ if (time_needed == SYS_ARCH_TIMEOUT) {
> ++ pthread_mutex_unlock(&(sem->mutex));
> ++ return SYS_ARCH_TIMEOUT;
> ++ } else if(time_needed == SYS_ARCH_INTR) {
> ++ /* This means we were interrupted */
> ++ pthread_mutex_unlock(&(sem->mutex));
> ++ return SYS_ARCH_INTR;
> ++ }
> ++ } else {
> ++ if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
> ++ /* This means we were interrupted */
> ++ pthread_mutex_unlock(&(sem->mutex));
> ++ return SYS_ARCH_INTR;
> ++ }
> ++ }
> ++ }
> ++ sem->c--;
> ++ pthread_mutex_unlock(&(sem->mutex));
> ++ return (u32_t)time_needed;
> ++}
> ++
> ++void
> ++sys_sem_signal(struct sys_sem **s)
> ++{
> ++ struct sys_sem *sem;
> ++ LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
> ++ sem = *s;
> ++
> ++ pthread_mutex_lock(&(sem->mutex));
> ++ sem->c++;
> ++
> ++ if (sem->c > 1) {
> ++ sem->c = 1;
> ++ }
> ++
> ++ pthread_cond_broadcast(&(sem->cond));
> ++ pthread_mutex_unlock(&(sem->mutex));
> ++}
> ++
> ++static void
> ++sys_sem_free_internal(struct sys_sem *sem)
> ++{
> ++ pthread_cond_destroy(&(sem->cond));
> ++ pthread_condattr_destroy(&(sem->condattr));
> ++ pthread_mutex_destroy(&(sem->mutex));
> ++ free(sem);
> ++}
> ++
> ++void
> ++sys_sem_free(struct sys_sem **sem)
> ++{
> ++ if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
> ++ SYS_STATS_DEC(sem.used);
> ++ sys_sem_free_internal(*sem);
> ++ }
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Mutex */
> ++/** Create a new mutex
> ++ * @param mutex pointer to the mutex to create
> ++ * @return a new mutex */
> ++err_t
> ++sys_mutex_new(struct sys_mutex **mutex)
> ++{
> ++ struct sys_mutex *mtx;
> ++
> ++ mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
> ++ if (mtx != NULL) {
> ++ pthread_mutex_init(&(mtx->mutex), NULL);
> ++ *mutex = mtx;
> ++ return ERR_OK;
> ++ }
> ++ else {
> ++ return ERR_MEM;
> ++ }
> ++}
> ++
> ++/** Lock a mutex
> ++ * @param mutex the mutex to lock */
> ++void
> ++sys_mutex_lock(struct sys_mutex **mutex)
> ++{
> ++ pthread_mutex_lock(&((*mutex)->mutex));
> ++}
> ++
> ++/** Unlock a mutex
> ++ * @param mutex the mutex to unlock */
> ++void
> ++sys_mutex_unlock(struct sys_mutex **mutex)
> ++{
> ++ pthread_mutex_unlock(&((*mutex)->mutex));
> ++}
> ++
> ++/** Delete a mutex
> ++ * @param mutex the mutex to delete */
> ++void
> ++sys_mutex_free(struct sys_mutex **mutex)
> ++{
> ++ pthread_mutex_destroy(&((*mutex)->mutex));
> ++ free(*mutex);
> ++}
> ++
> ++#endif /* !NO_SYS */
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Time */
> ++u32_t
> ++sys_now(void)
> ++{
> ++ struct timespec ts;
> ++
> ++ get_monotonic_time(&ts);
> ++ return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
> ++}
> ++
> ++u32_t
> ++sys_jiffies(void)
> ++{
> ++ struct timespec ts;
> ++
> ++ get_monotonic_time(&ts);
> ++ return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Init */
> ++
> ++void
> ++sys_init(void)
> ++{
> ++}
> ++
> ++/*-----------------------------------------------------------------------------------*/
> ++/* Critical section */
> ++#if SYS_LIGHTWEIGHT_PROT
> ++/** sys_prot_t sys_arch_protect(void)
> ++
> ++This optional function does a "fast" critical region protection and returns
> ++the previous protection level. This function is only called during very
> short
> ++critical regions. An embedded system which supports ISR-based drivers might
> ++want to implement this function by disabling interrupts. Task-based systems
> ++might want to implement this by using a mutex or disabling tasking. This
> ++function should support recursive calls from the same task or interrupt. In
> ++other words, sys_arch_protect() could be called while already protected. In
> ++that case the return value indicates that it is already protected.
> ++
> ++sys_arch_protect() is only required if your port is supporting an operating
> ++system.
> ++*/
> ++sys_prot_t
> ++sys_arch_protect(void)
> ++{
> ++ /* Note that for the UNIX port, we are using a lightweight mutex, and
> our
> ++ * own counter (which is locked by the mutex). The return code is not
> actually
> ++ * used. */
> ++ if (lwprot_thread != pthread_self())
> ++ {
> ++ /* We are locking the mutex where it has not been locked before *
> ++ * or is being locked by another thread */
> ++ pthread_mutex_lock(&lwprot_mutex);
> ++ lwprot_thread = pthread_self();
> ++ lwprot_count = 1;
> ++ }
> ++ else
> ++ /* It is already locked by THIS thread */
> ++ lwprot_count++;
> ++ return 0;
> ++}
> ++
> ++/** void sys_arch_unprotect(sys_prot_t pval)
> ++
> ++This optional function does a "fast" set of critical region protection to
> the
> ++value specified by pval. See the documentation for sys_arch_protect() for
> ++more information. This function is only required if your port is supporting
> ++an operating system.
> ++*/
> ++void
> ++sys_arch_unprotect(sys_prot_t pval)
> ++{
> ++ LWIP_UNUSED_ARG(pval);
> ++ if (lwprot_thread == pthread_self())
> ++ {
> ++ if (--lwprot_count == 0)
> ++ {
> ++ lwprot_thread = (pthread_t) 0xDEAD;
> ++ pthread_mutex_unlock(&lwprot_mutex);
> ++ }
> ++ }
> ++}
> ++#endif /* SYS_LIGHTWEIGHT_PROT */
> diff --git a/debian/patches/posix b/debian/patches/posix
> index 1818c4d..e92f542 100644
> --- a/debian/patches/posix
> +++ b/debian/patches/posix
> @@ -18,117 +18,117 @@ Won't get to upstream
> --- /dev/null
> +++ b/port/include/posix/inet.h
> @@ -0,0 +1,63 @@
> -+/*
> -+ Copyright (C) 2018 Free Software Foundation, Inc.
> -+ Written by Joan Lledó.
> -+
> -+ This file is part of the GNU Hurd.
> -+
> -+ The GNU Hurd is free software; you can redistribute it and/or
> -+ modify it under the terms of the GNU General Public License as
> -+ published by the Free Software Foundation; either version 2, or (at
> -+ your option) any later version.
> -+
> -+ The GNU Hurd is distributed in the hope that it will be useful, but
> -+ WITHOUT ANY WARRANTY; without even the implied warranty of
> -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+ General Public License for more details.
> -+
> -+ You should have received a copy of the GNU General Public License
> -+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> -+
> -+#ifndef HURD_LWIP_POSIX_INET_H
> -+#define HURD_LWIP_POSIX_INET_H
> -+
> -+#include <arpa/inet.h>
> -+#include <netinet/in.h>
> -+#include <netinet/tcp.h>
> -+#include <netinet/udp.h>
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
> -+ __SOCKADDR_COMMON_SIZE - \
> -+ sizeof (in_port_t) - \
> -+ sizeof (struct in_addr)
> -+
> -+#if LWIP_IPV4
> -+
> -+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr)
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> -+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> -+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t
> are an u32_t effectively! */
> -+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> -+
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr)
> {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
> -+
> (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
> -+
> (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
> -+
> (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
> -+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)
> {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
> -+
> (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
> -+
> (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
> -+
> (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
> -+/* ATTENTION: the next define only works because both in6_addr and
> ip6_addr_t are an u32_t[4] effectively! */
> -+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> -+#endif /* LWIP_IPV6 */
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* HURD_LWIP_POSIX_INET_H */
> ++/*
> ++ Copyright (C) 2018 Free Software Foundation, Inc.
> ++ Written by Joan Lledó.
> ++
> ++ This file is part of the GNU Hurd.
> ++
> ++ The GNU Hurd is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU General Public License as
> ++ published by the Free Software Foundation; either version 2, or (at
> ++ your option) any later version.
> ++
> ++ The GNU Hurd is distributed in the hope that it will be useful, but
> ++ WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> ++ General Public License for more details.
> ++
> ++ You should have received a copy of the GNU General Public License
> ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> ++
> ++#ifndef HURD_LWIP_POSIX_INET_H
> ++#define HURD_LWIP_POSIX_INET_H
> ++
> ++#include <arpa/inet.h>
> ++#include <netinet/in.h>
> ++#include <netinet/tcp.h>
> ++#include <netinet/udp.h>
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++#define SIN_ZERO_LEN sizeof (struct sockaddr) - \
> ++ __SOCKADDR_COMMON_SIZE - \
> ++ sizeof (in_port_t) - \
> ++ sizeof (struct in_addr)
> ++
> ++#if LWIP_IPV4
> ++
> ++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr)
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> ++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> ++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t
> are an u32_t effectively! */
> ++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> ++
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr)
> {(target_in6addr)->s6_addr32[0] = (source_ip6addr)->addr[0]; \
> ++
> (target_in6addr)->s6_addr32[1] = (source_ip6addr)->addr[1]; \
> ++
> (target_in6addr)->s6_addr32[2] = (source_ip6addr)->addr[2]; \
> ++
> (target_in6addr)->s6_addr32[3] = (source_ip6addr)->addr[3];}
> ++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)
> {(target_ip6addr)->addr[0] = (source_in6addr)->s6_addr32[0]; \
> ++
> (target_ip6addr)->addr[1] = (source_in6addr)->s6_addr32[1]; \
> ++
> (target_ip6addr)->addr[2] = (source_in6addr)->s6_addr32[2]; \
> ++
> (target_ip6addr)->addr[3] = (source_in6addr)->s6_addr32[3];}
> ++/* ATTENTION: the next define only works because both in6_addr and
> ip6_addr_t are an u32_t[4] effectively! */
> ++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> ++#endif /* LWIP_IPV6 */
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* HURD_LWIP_POSIX_INET_H */
> --- /dev/null
> +++ b/port/include/posix/socket.h
> @@ -0,0 +1,45 @@
> -+/*
> -+ Copyright (C) 2018 Free Software Foundation, Inc.
> -+ Written by Joan Lledó.
> -+
> -+ This file is part of the GNU Hurd.
> -+
> -+ The GNU Hurd is free software; you can redistribute it and/or
> -+ modify it under the terms of the GNU General Public License as
> -+ published by the Free Software Foundation; either version 2, or (at
> -+ your option) any later version.
> -+
> -+ The GNU Hurd is distributed in the hope that it will be useful, but
> -+ WITHOUT ANY WARRANTY; without even the implied warranty of
> -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> -+ General Public License for more details.
> -+
> -+ You should have received a copy of the GNU General Public License
> -+ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> -+
> -+#ifndef HURD_LWIP_POSIX_SOCKET_H
> -+#define HURD_LWIP_POSIX_SOCKET_H
> -+
> -+#include <sys/socket.h>
> -+#include <poll.h>
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+/* Unsuported indetifiers */
> -+#ifndef SO_NO_CHECK
> -+#define SO_NO_CHECK 0x0
> -+#endif
> -+#ifndef MSG_MORE
> -+#define MSG_MORE 0x0
> -+#endif
> -+#ifndef TCP_KEEPALIVE
> -+#define TCP_KEEPALIVE 0x0
> -+#endif
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* HURD_LWIP_POSIX_SOCKET_H */
> ++/*
> ++ Copyright (C) 2018 Free Software Foundation, Inc.
> ++ Written by Joan Lledó.
> ++
> ++ This file is part of the GNU Hurd.
> ++
> ++ The GNU Hurd is free software; you can redistribute it and/or
> ++ modify it under the terms of the GNU General Public License as
> ++ published by the Free Software Foundation; either version 2, or (at
> ++ your option) any later version.
> ++
> ++ The GNU Hurd is distributed in the hope that it will be useful, but
> ++ WITHOUT ANY WARRANTY; without even the implied warranty of
> ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> ++ General Public License for more details.
> ++
> ++ You should have received a copy of the GNU General Public License
> ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */
> ++
> ++#ifndef HURD_LWIP_POSIX_SOCKET_H
> ++#define HURD_LWIP_POSIX_SOCKET_H
> ++
> ++#include <sys/socket.h>
> ++#include <poll.h>
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++/* Unsuported indetifiers */
> ++#ifndef SO_NO_CHECK
> ++#define SO_NO_CHECK 0x0
> ++#endif
> ++#ifndef MSG_MORE
> ++#define MSG_MORE 0x0
> ++#endif
> ++#ifndef TCP_KEEPALIVE
> ++#define TCP_KEEPALIVE 0x0
> ++#endif
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* HURD_LWIP_POSIX_SOCKET_H */
> --- a/src/include/lwip/inet.h
> +++ b/src/include/lwip/inet.h
> @@ -41,132 +41,11 @@
> @@ -270,7 +270,7 @@ Won't get to upstream
> #endif /* LWIP_HDR_INET_H */
> --- a/src/include/lwip/ip.h
> +++ b/src/include/lwip/ip.h
> -@@ -94,9 +94,16 @@ struct ip_pcb {
> +@@ -94,9 +94,16 @@
> /*
> * Option flags per-socket. These are the same like SO_XXX in sockets.h
> */
> @@ -290,742 +290,742 @@ Won't get to upstream
> --- /dev/null
> +++ b/src/include/lwip/lwip_inet.h
> @@ -0,0 +1,164 @@
> -+/*
> -+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ * this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> -+ * this list of conditions and the following disclaimer in the
> documentation
> -+ * and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ * derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+#ifndef LWIP_HDR_PRIV_INET_H
> -+#define LWIP_HDR_PRIV_INET_H
> -+
> -+#include "lwip/opt.h"
> -+#include "lwip/def.h"
> -+#include "lwip/ip_addr.h"
> -+#include "lwip/ip6_addr.h"
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
> -+ to prevent this code from redefining it. */
> -+#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
> -+typedef u32_t in_addr_t;
> -+#endif
> -+
> -+struct in_addr {
> -+ in_addr_t s_addr;
> -+};
> -+
> -+struct in6_addr {
> -+ union {
> -+ u32_t u32_addr[4];
> -+ u8_t u8_addr[16];
> -+ } un;
> -+#define s6_addr un.u8_addr
> -+};
> -+
> -+/** 255.255.255.255 */
> -+#define INADDR_NONE IPADDR_NONE
> -+/** 127.0.0.1 */
> -+#define INADDR_LOOPBACK IPADDR_LOOPBACK
> -+/** 0.0.0.0 */
> -+#define INADDR_ANY IPADDR_ANY
> -+/** 255.255.255.255 */
> -+#define INADDR_BROADCAST IPADDR_BROADCAST
> -+
> -+/** This macro can be used to initialize a variable of type struct in6_addr
> -+ to the IPv6 wildcard address. */
> -+#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
> -+/** This macro can be used to initialize a variable of type struct in6_addr
> -+ to the IPv6 loopback address. */
> -+#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
> -+/** This variable is initialized by the system to contain the wildcard IPv6
> address. */
> -+extern const struct in6_addr in6addr_any;
> -+
> -+/* Definitions of the bits in an (IPv4) Internet address integer.
> -+
> -+ On subnets, host and network parts are found according to
> -+ the subnet mask, not these masks. */
> -+#define IN_CLASSA(a) IP_CLASSA(a)
> -+#define IN_CLASSA_NET IP_CLASSA_NET
> -+#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT
> -+#define IN_CLASSA_HOST IP_CLASSA_HOST
> -+#define IN_CLASSA_MAX IP_CLASSA_MAX
> -+
> -+#define IN_CLASSB(b) IP_CLASSB(b)
> -+#define IN_CLASSB_NET IP_CLASSB_NET
> -+#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT
> -+#define IN_CLASSB_HOST IP_CLASSB_HOST
> -+#define IN_CLASSB_MAX IP_CLASSB_MAX
> -+
> -+#define IN_CLASSC(c) IP_CLASSC(c)
> -+#define IN_CLASSC_NET IP_CLASSC_NET
> -+#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT
> -+#define IN_CLASSC_HOST IP_CLASSC_HOST
> -+#define IN_CLASSC_MAX IP_CLASSC_MAX
> -+
> -+#define IN_CLASSD(d) IP_CLASSD(d)
> -+#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */
> -+#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but
> */
> -+#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */
> -+#define IN_CLASSD_MAX IP_CLASSD_MAX
> -+
> -+#define IN_MULTICAST(a) IP_MULTICAST(a)
> -+
> -+#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a)
> -+#define IN_BADCLASS(a) IP_BADCLASS(a)
> -+
> -+#define IN_LOOPBACKNET IP_LOOPBACKNET
> -+
> -+
> -+#ifndef INET_ADDRSTRLEN
> -+#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX
> -+#endif
> -+#if LWIP_IPV6
> -+#ifndef INET6_ADDRSTRLEN
> -+#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX
> -+#endif
> -+#endif
> -+
> -+#if LWIP_IPV4
> -+
> -+#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr)
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> -+#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> -+/* ATTENTION: the next define only works because both s_addr and ip4_addr_t
> are an u32_t effectively! */
> -+#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> -+
> -+/* directly map this to the lwip internal functions */
> -+#define inet_addr(cp) ipaddr_addr(cp)
> -+#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
> -+#define inet_ntoa(addr) ip4addr_ntoa((const
> ip4_addr_t*)&(addr))
> -+#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const
> ip4_addr_t*)&(addr), buf, buflen)
> -+
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr)
> {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
> -+
> (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
> -+
> (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
> -+
> (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
> -+#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)
> {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
> -+
> (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
> -+
> (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
> -+
> (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
> -+/* ATTENTION: the next define only works because both in6_addr and
> ip6_addr_t are an u32_t[4] effectively! */
> -+#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> -+
> -+/* directly map this to the lwip internal functions */
> -+#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr)
> -+#define inet6_ntoa(addr) ip6addr_ntoa((const
> ip6_addr_t*)&(addr))
> -+#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const
> ip6_addr_t*)&(addr), buf, buflen)
> -+
> -+#endif /* LWIP_IPV6 */
> -+
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* LWIP_HDR_PRIV_INET_H */
> ++/*
> ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ * this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> ++ * this list of conditions and the following disclaimer in the
> documentation
> ++ * and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ * derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++#ifndef LWIP_HDR_PRIV_INET_H
> ++#define LWIP_HDR_PRIV_INET_H
> ++
> ++#include "lwip/opt.h"
> ++#include "lwip/def.h"
> ++#include "lwip/ip_addr.h"
> ++#include "lwip/ip6_addr.h"
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
> ++ to prevent this code from redefining it. */
> ++#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
> ++typedef u32_t in_addr_t;
> ++#endif
> ++
> ++struct in_addr {
> ++ in_addr_t s_addr;
> ++};
> ++
> ++struct in6_addr {
> ++ union {
> ++ u32_t u32_addr[4];
> ++ u8_t u8_addr[16];
> ++ } un;
> ++#define s6_addr un.u8_addr
> ++};
> ++
> ++/** 255.255.255.255 */
> ++#define INADDR_NONE IPADDR_NONE
> ++/** 127.0.0.1 */
> ++#define INADDR_LOOPBACK IPADDR_LOOPBACK
> ++/** 0.0.0.0 */
> ++#define INADDR_ANY IPADDR_ANY
> ++/** 255.255.255.255 */
> ++#define INADDR_BROADCAST IPADDR_BROADCAST
> ++
> ++/** This macro can be used to initialize a variable of type struct in6_addr
> ++ to the IPv6 wildcard address. */
> ++#define IN6ADDR_ANY_INIT {{{0,0,0,0}}}
> ++/** This macro can be used to initialize a variable of type struct in6_addr
> ++ to the IPv6 loopback address. */
> ++#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}}
> ++/** This variable is initialized by the system to contain the wildcard IPv6
> address. */
> ++extern const struct in6_addr in6addr_any;
> ++
> ++/* Definitions of the bits in an (IPv4) Internet address integer.
> ++
> ++ On subnets, host and network parts are found according to
> ++ the subnet mask, not these masks. */
> ++#define IN_CLASSA(a) IP_CLASSA(a)
> ++#define IN_CLASSA_NET IP_CLASSA_NET
> ++#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT
> ++#define IN_CLASSA_HOST IP_CLASSA_HOST
> ++#define IN_CLASSA_MAX IP_CLASSA_MAX
> ++
> ++#define IN_CLASSB(b) IP_CLASSB(b)
> ++#define IN_CLASSB_NET IP_CLASSB_NET
> ++#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT
> ++#define IN_CLASSB_HOST IP_CLASSB_HOST
> ++#define IN_CLASSB_MAX IP_CLASSB_MAX
> ++
> ++#define IN_CLASSC(c) IP_CLASSC(c)
> ++#define IN_CLASSC_NET IP_CLASSC_NET
> ++#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT
> ++#define IN_CLASSC_HOST IP_CLASSC_HOST
> ++#define IN_CLASSC_MAX IP_CLASSC_MAX
> ++
> ++#define IN_CLASSD(d) IP_CLASSD(d)
> ++#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */
> ++#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but
> */
> ++#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */
> ++#define IN_CLASSD_MAX IP_CLASSD_MAX
> ++
> ++#define IN_MULTICAST(a) IP_MULTICAST(a)
> ++
> ++#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a)
> ++#define IN_BADCLASS(a) IP_BADCLASS(a)
> ++
> ++#define IN_LOOPBACKNET IP_LOOPBACKNET
> ++
> ++
> ++#ifndef INET_ADDRSTRLEN
> ++#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX
> ++#endif
> ++#if LWIP_IPV6
> ++#ifndef INET6_ADDRSTRLEN
> ++#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX
> ++#endif
> ++#endif
> ++
> ++#if LWIP_IPV4
> ++
> ++#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr)
> ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr))
> ++#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr)
> (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr))
> ++/* ATTENTION: the next define only works because both s_addr and ip4_addr_t
> are an u32_t effectively! */
> ++#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr)
> ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr))
> ++
> ++/* directly map this to the lwip internal functions */
> ++#define inet_addr(cp) ipaddr_addr(cp)
> ++#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr)
> ++#define inet_ntoa(addr) ip4addr_ntoa((const
> ip4_addr_t*)&(addr))
> ++#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const
> ip4_addr_t*)&(addr), buf, buflen)
> ++
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr)
> {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \
> ++
> (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \
> ++
> (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \
> ++
> (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];}
> ++#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr)
> {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \
> ++
> (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \
> ++
> (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \
> ++
> (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];}
> ++/* ATTENTION: the next define only works because both in6_addr and
> ip6_addr_t are an u32_t[4] effectively! */
> ++#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr)
> ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr))
> ++
> ++/* directly map this to the lwip internal functions */
> ++#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr)
> ++#define inet6_ntoa(addr) ip6addr_ntoa((const
> ip6_addr_t*)&(addr))
> ++#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const
> ip6_addr_t*)&(addr), buf, buflen)
> ++
> ++#endif /* LWIP_IPV6 */
> ++
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* LWIP_HDR_PRIV_INET_H */
> --- /dev/null
> +++ b/src/include/lwip/lwip_sockets.h
> @@ -0,0 +1,569 @@
> -+/**
> -+ * @file
> -+ * Socket API (to be used from non-TCPIP threads)
> -+ */
> -+
> -+/*
> -+ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> -+ * All rights reserved.
> -+ *
> -+ * Redistribution and use in source and binary forms, with or without
> modification,
> -+ * are permitted provided that the following conditions are met:
> -+ *
> -+ * 1. Redistributions of source code must retain the above copyright notice,
> -+ * this list of conditions and the following disclaimer.
> -+ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> -+ * this list of conditions and the following disclaimer in the
> documentation
> -+ * and/or other materials provided with the distribution.
> -+ * 3. The name of the author may not be used to endorse or promote products
> -+ * derived from this software without specific prior written permission.
> -+ *
> -+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> -+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> -+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> -+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> -+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> -+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> -+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> -+ * OF SUCH DAMAGE.
> -+ *
> -+ * This file is part of the lwIP TCP/IP stack.
> -+ *
> -+ * Author: Adam Dunkels <adam@sics.se>
> -+ *
> -+ */
> -+
> -+
> -+#ifndef LWIP_HDR_PRIV_SOCKETS_H
> -+#define LWIP_HDR_PRIV_SOCKETS_H
> -+
> -+#include "lwip/opt.h"
> -+
> -+#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
> -+
> -+#include "lwip/ip_addr.h"
> -+#include "lwip/err.h"
> -+#include "lwip/inet.h"
> -+#include "lwip/errno.h"
> -+
> -+#ifdef __cplusplus
> -+extern "C" {
> -+#endif
> -+
> -+#define _HAVE_SA_LEN 1
> -+
> -+/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
> -+ to prevent this code from redefining it. */
> -+#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
> -+typedef u8_t sa_family_t;
> -+#endif
> -+/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
> -+ to prevent this code from redefining it. */
> -+#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
> -+typedef u16_t in_port_t;
> -+#endif
> -+
> -+#if LWIP_IPV4
> -+/* members are in network byte order */
> -+struct sockaddr_in {
> -+ u8_t sin_len;
> -+ sa_family_t sin_family;
> -+ in_port_t sin_port;
> -+ struct in_addr sin_addr;
> -+#define SIN_ZERO_LEN 8
> -+ char sin_zero[SIN_ZERO_LEN];
> -+};
> -+#endif /* LWIP_IPV4 */
> -+
> -+#if LWIP_IPV6
> -+struct sockaddr_in6 {
> -+ u8_t sin6_len; /* length of this structure */
> -+ sa_family_t sin6_family; /* AF_INET6 */
> -+ in_port_t sin6_port; /* Transport layer port # */
> -+ u32_t sin6_flowinfo; /* IPv6 flow information */
> -+ struct in6_addr sin6_addr; /* IPv6 address */
> -+ u32_t sin6_scope_id; /* Set of interfaces for scope */
> -+};
> -+#endif /* LWIP_IPV6 */
> -+
> -+struct sockaddr {
> -+ u8_t sa_len;
> -+ sa_family_t sa_family;
> -+ char sa_data[14];
> -+};
> -+
> -+struct sockaddr_storage {
> -+ u8_t s2_len;
> -+ sa_family_t ss_family;
> -+ char s2_data1[2];
> -+ u32_t s2_data2[3];
> -+#if LWIP_IPV6
> -+ u32_t s2_data3[3];
> -+#endif /* LWIP_IPV6 */
> -+};
> -+
> -+/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
> -+ to prevent this code from redefining it. */
> -+#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
> -+typedef u32_t socklen_t;
> -+#endif
> -+
> -+struct lwip_sock;
> -+
> -+#if !LWIP_TCPIP_CORE_LOCKING
> -+/** Maximum optlen used by setsockopt/getsockopt */
> -+#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
> -+
> -+/** This struct is used to pass data to the set/getsockopt_internal
> -+ * functions running in tcpip_thread context (only a void* is allowed) */
> -+struct lwip_setgetsockopt_data {
> -+ /** socket index for which to change options */
> -+ int s;
> -+ /** level of the option to process */
> -+ int level;
> -+ /** name of the option to process */
> -+ int optname;
> -+ /** set: value to set the option to
> -+ * get: value of the option is stored here */
> -+#if LWIP_MPU_COMPATIBLE
> -+ u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
> -+#else
> -+ union {
> -+ void *p;
> -+ const void *pc;
> -+ } optval;
> -+#endif
> -+ /** size of *optval */
> -+ socklen_t optlen;
> -+ /** if an error occurs, it is temporarily stored here */
> -+ err_t err;
> -+ /** semaphore to wake up the calling task */
> -+ void* completed_sem;
> -+};
> -+#endif /* !LWIP_TCPIP_CORE_LOCKING */
> -+
> -+#if !defined(iovec)
> -+struct iovec {
> -+ void *iov_base;
> -+ size_t iov_len;
> -+};
> -+#endif
> -+
> -+struct msghdr {
> -+ void *msg_name;
> -+ socklen_t msg_namelen;
> -+ struct iovec *msg_iov;
> -+ int msg_iovlen;
> -+ void *msg_control;
> -+ socklen_t msg_controllen;
> -+ int msg_flags;
> -+};
> -+
> -+/* Socket protocol types (TCP/UDP/RAW) */
> -+#define SOCK_STREAM 1
> -+#define SOCK_DGRAM 2
> -+#define SOCK_RAW 3
> -+
> -+/*
> -+ * Option flags per-socket. These must match the SOF_ flags in ip.h
> (checked in init.c)
> -+ */
> -+#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
> -+#define SO_KEEPALIVE 0x0008 /* keep connections alive */
> -+#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast
> messages (see IP_SOF_BROADCAST option) */
> -+
> -+
> -+/*
> -+ * Additional options, not kept in so_options.
> -+ */
> -+#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info
> recording */
> -+#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
> -+#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface
> addresses */
> -+#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when
> possible */
> -+#define SO_LINGER 0x0080 /* linger on close if data present */
> -+#define SO_DONTLINGER ((int)(~SO_LINGER))
> -+#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in
> line */
> -+#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port
> reuse */
> -+#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
> -+#define SO_RCVBUF 0x1002 /* receive buffer size */
> -+#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
> -+#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
> -+#define SO_SNDTIMEO 0x1005 /* send timeout */
> -+#define SO_RCVTIMEO 0x1006 /* receive timeout */
> -+#define SO_ERROR 0x1007 /* get error status and clear */
> -+#define SO_TYPE 0x1008 /* get socket type */
> -+#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
> -+#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
> -+
> -+
> -+/*
> -+ * Structure used for manipulating linger option.
> -+ */
> -+struct linger {
> -+ int l_onoff; /* option on/off */
> -+ int l_linger; /* linger time in seconds */
> -+};
> -+
> -+/*
> -+ * Level number for (get/set)sockopt() to apply to socket itself.
> -+ */
> -+#define SOL_SOCKET 0xfff /* options for socket level */
> -+
> -+
> -+#define AF_UNSPEC 0
> -+#define AF_INET 2
> -+#if LWIP_IPV6
> -+#define AF_INET6 10
> -+#else /* LWIP_IPV6 */
> -+#define AF_INET6 AF_UNSPEC
> -+#endif /* LWIP_IPV6 */
> -+#define PF_INET AF_INET
> -+#define PF_INET6 AF_INET6
> -+#define PF_UNSPEC AF_UNSPEC
> -+
> -+#define IPPROTO_IP 0
> -+#define IPPROTO_ICMP 1
> -+#define IPPROTO_TCP 6
> -+#define IPPROTO_UDP 17
> -+#if LWIP_IPV6
> -+#define IPPROTO_IPV6 41
> -+#define IPPROTO_ICMPV6 58
> -+#endif /* LWIP_IPV6 */
> -+#define IPPROTO_UDPLITE 136
> -+#define IPPROTO_RAW 255
> -+
> -+/* Flags we can use with send and recv. */
> -+#define MSG_PEEK 0x01 /* Peeks at an incoming message */
> -+#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function
> block until the full amount of data requested can be returned */
> -+#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data.
> The significance and semantics of out-of-band data are protocol-specific */
> -+#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
> -+#define MSG_MORE 0x10 /* Sender will send more */
> -+
> -+
> -+/*
> -+ * Options for level IPPROTO_IP
> -+ */
> -+#define IP_TOS 1
> -+#define IP_TTL 2
> -+
> -+#if LWIP_TCP
> -+/*
> -+ * Options for level IPPROTO_TCP
> -+ */
> -+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
> -+#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for
> pcb->keep_idle milliseconds */
> -+#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as
> TCP_KEEPALIVE, but use seconds for get/setsockopt */
> -+#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for
> get/setsockopt */
> -+#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of
> probes sent for get/setsockopt */
> -+#endif /* LWIP_TCP */
> -+
> -+#if LWIP_IPV6
> -+/*
> -+ * Options for level IPPROTO_IPV6
> -+ */
> -+#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6
> checksum for raw sockets. */
> -+#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict
> AF_INET6 sockets to IPv6 communications only. */
> -+#endif /* LWIP_IPV6 */
> -+
> -+#if LWIP_UDP && LWIP_UDPLITE
> -+/*
> -+ * Options for level IPPROTO_UDPLITE
> -+ */
> -+#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
> -+#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
> -+#endif /* LWIP_UDP && LWIP_UDPLITE*/
> -+
> -+
> -+#if LWIP_MULTICAST_TX_OPTIONS
> -+/*
> -+ * Options and types for UDP multicast traffic handling
> -+ */
> -+#define IP_MULTICAST_TTL 5
> -+#define IP_MULTICAST_IF 6
> -+#define IP_MULTICAST_LOOP 7
> -+#endif /* LWIP_MULTICAST_TX_OPTIONS */
> -+
> -+#if LWIP_IGMP
> -+/*
> -+ * Options and types related to multicast membership
> -+ */
> -+#define IP_ADD_MEMBERSHIP 3
> -+#define IP_DROP_MEMBERSHIP 4
> -+
> -+typedef struct ip_mreq {
> -+ struct in_addr imr_multiaddr; /* IP multicast address of group */
> -+ struct in_addr imr_interface; /* local IP address of interface */
> -+} ip_mreq;
> -+#endif /* LWIP_IGMP */
> -+
> -+/*
> -+ * The Type of Service provides an indication of the abstract
> -+ * parameters of the quality of service desired. These parameters are
> -+ * to be used to guide the selection of the actual service parameters
> -+ * when transmitting a datagram through a particular network. Several
> -+ * networks offer service precedence, which somehow treats high
> -+ * precedence traffic as more important than other traffic (generally
> -+ * by accepting only traffic above a certain precedence at time of high
> -+ * load). The major choice is a three way tradeoff between low-delay,
> -+ * high-reliability, and high-throughput.
> -+ * The use of the Delay, Throughput, and Reliability indications may
> -+ * increase the cost (in some sense) of the service. In many networks
> -+ * better performance for one of these parameters is coupled with worse
> -+ * performance on another. Except for very unusual cases at most two
> -+ * of these three indications should be set.
> -+ */
> -+#define IPTOS_TOS_MASK 0x1E
> -+#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
> -+#define IPTOS_LOWDELAY 0x10
> -+#define IPTOS_THROUGHPUT 0x08
> -+#define IPTOS_RELIABILITY 0x04
> -+#define IPTOS_LOWCOST 0x02
> -+#define IPTOS_MINCOST IPTOS_LOWCOST
> -+
> -+/*
> -+ * The Network Control precedence designation is intended to be used
> -+ * within a network only. The actual use and control of that
> -+ * designation is up to each network. The Internetwork Control
> -+ * designation is intended for use by gateway control originators only.
> -+ * If the actual use of these precedence designations is of concern to
> -+ * a particular network, it is the responsibility of that network to
> -+ * control the access to, and use of, those precedence designations.
> -+ */
> -+#define IPTOS_PREC_MASK 0xe0
> -+#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
> -+#define IPTOS_PREC_NETCONTROL 0xe0
> -+#define IPTOS_PREC_INTERNETCONTROL 0xc0
> -+#define IPTOS_PREC_CRITIC_ECP 0xa0
> -+#define IPTOS_PREC_FLASHOVERRIDE 0x80
> -+#define IPTOS_PREC_FLASH 0x60
> -+#define IPTOS_PREC_IMMEDIATE 0x40
> -+#define IPTOS_PREC_PRIORITY 0x20
> -+#define IPTOS_PREC_ROUTINE 0x00
> -+
> -+
> -+/*
> -+ * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
> -+ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
> -+ *
> -+ * Ioctl's have the command encoded in the lower word,
> -+ * and the size of any in or out parameters in the upper
> -+ * word. The high 2 bits of the upper word are used
> -+ * to encode the in/out status of the parameter; for now
> -+ * we restrict parameters to at most 128 bytes.
> -+ */
> -+#if !defined(FIONREAD) || !defined(FIONBIO)
> -+#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
> -+#define IOC_VOID 0x20000000UL /* no parameters */
> -+#define IOC_OUT 0x40000000UL /* copy out parameters */
> -+#define IOC_IN 0x80000000UL /* copy in parameters */
> -+#define IOC_INOUT (IOC_IN|IOC_OUT)
> -+ /* 0x20000000 distinguishes new &
> -+ old ioctl's */
> -+#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
> -+
> -+#define _IOR(x,y,t)
> (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> -+
> -+#define _IOW(x,y,t)
> (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> -+#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
> -+
> -+#ifndef FIONREAD
> -+#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
> -+#endif
> -+#ifndef FIONBIO
> -+#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking
> i/o */
> -+#endif
> -+
> -+/* Socket I/O Controls: unimplemented */
> -+#ifndef SIOCSHIWAT
> -+#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
> -+#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
> -+#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */
> -+#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */
> -+#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
> -+#endif
> -+
> -+/* commands for fnctl */
> -+#ifndef F_GETFL
> -+#define F_GETFL 3
> -+#endif
> -+#ifndef F_SETFL
> -+#define F_SETFL 4
> -+#endif
> -+
> -+/* File status flags and file access modes for fnctl,
> -+ these are bits in an int. */
> -+#ifndef O_NONBLOCK
> -+#define O_NONBLOCK 1 /* nonblocking I/O */
> -+#endif
> -+#ifndef O_NDELAY
> -+#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */
> -+#endif
> -+
> -+#ifndef SHUT_RD
> -+ #define SHUT_RD 0
> -+ #define SHUT_WR 1
> -+ #define SHUT_RDWR 2
> -+#endif
> -+
> -+/* FD_SET used for lwip_select */
> -+#ifndef FD_SET
> -+#undef FD_SETSIZE
> -+/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
> -+#define FD_SETSIZE MEMP_NUM_NETCONN
> -+#define FDSETSAFESET(n, code) do { \
> -+ if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) -
> LWIP_SOCKET_OFFSET) >= 0)) { \
> -+ code; }} while(0)
> -+#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET <
> MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
> -+ (code) : 0)
> -+#define FD_SET(n, p) FDSETSAFESET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> -+#define FD_CLR(n, p) FDSETSAFESET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> -+#define FD_ISSET(n,p) FDSETSAFEGET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> -+#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
> -+
> -+typedef struct fd_set
> -+{
> -+ unsigned char fd_bits [(FD_SETSIZE+7)/8];
> -+} fd_set;
> -+
> -+#elif LWIP_SOCKET_OFFSET
> -+#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
> -+#elif FD_SETSIZE < MEMP_NUM_NETCONN
> -+#error "external FD_SETSIZE too small for number of sockets"
> -+#endif /* FD_SET */
> -+
> -+/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> -+ * by your system, set this to 0 and include <sys/time.h> in cc.h */
> -+#ifndef LWIP_TIMEVAL_PRIVATE
> -+#define LWIP_TIMEVAL_PRIVATE 1
> -+#endif
> -+
> -+#if LWIP_TIMEVAL_PRIVATE
> -+struct timeval {
> -+ long tv_sec; /* seconds */
> -+ long tv_usec; /* and microseconds */
> -+};
> -+#endif /* LWIP_TIMEVAL_PRIVATE */
> -+
> -+#define lwip_socket_init() /* Compatibility define, no init needed. */
> -+void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1:
> initialize thread-local semaphore */
> -+void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1:
> destroy thread-local semaphore */
> -+
> -+#if LWIP_COMPAT_SOCKETS == 2
> -+/* This helps code parsers/code completion by not having the COMPAT
> functions as defines */
> -+#define lwip_accept accept
> -+#define lwip_bind bind
> -+#define lwip_shutdown shutdown
> -+#define lwip_getpeername getpeername
> -+#define lwip_getsockname getsockname
> -+#define lwip_setsockopt setsockopt
> -+#define lwip_getsockopt getsockopt
> -+#define lwip_close closesocket
> -+#define lwip_connect connect
> -+#define lwip_listen listen
> -+#define lwip_recv recv
> -+#define lwip_recvfrom recvfrom
> -+#define lwip_send send
> -+#define lwip_sendmsg sendmsg
> -+#define lwip_sendto sendto
> -+#define lwip_socket socket
> -+#define lwip_select select
> -+#define lwip_ioctlsocket ioctl
> -+
> -+#if LWIP_POSIX_SOCKETS_IO_NAMES
> -+#define lwip_read read
> -+#define lwip_write write
> -+#define lwip_writev writev
> -+#undef lwip_close
> -+#define lwip_close close
> -+#define closesocket(s) close(s)
> -+#define lwip_fcntl fcntl
> -+#define lwip_ioctl ioctl
> -+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> -+#endif /* LWIP_COMPAT_SOCKETS == 2 */
> -+
> -+#if LWIP_COMPAT_SOCKETS
> -+#if LWIP_COMPAT_SOCKETS != 2
> -+/** @ingroup socket */
> -+#define accept(s,addr,addrlen)
> lwip_accept(s,addr,addrlen)
> -+/** @ingroup socket */
> -+#define bind(s,name,namelen) lwip_bind(s,name,namelen)
> -+/** @ingroup socket */
> -+#define shutdown(s,how) lwip_shutdown(s,how)
> -+/** @ingroup socket */
> -+#define getpeername(s,name,namelen)
> lwip_getpeername(s,name,namelen)
> -+/** @ingroup socket */
> -+#define getsockname(s,name,namelen)
> lwip_getsockname(s,name,namelen)
> -+/** @ingroup socket */
> -+#define setsockopt(s,level,optname,opval,optlen)
> lwip_setsockopt(s,level,optname,opval,optlen)
> -+/** @ingroup socket */
> -+#define getsockopt(s,level,optname,opval,optlen)
> lwip_getsockopt(s,level,optname,opval,optlen)
> -+/** @ingroup socket */
> -+#define closesocket(s) lwip_close(s)
> -+/** @ingroup socket */
> -+#define connect(s,name,namelen)
> lwip_connect(s,name,namelen)
> -+/** @ingroup socket */
> -+#define listen(s,backlog) lwip_listen(s,backlog)
> -+/** @ingroup socket */
> -+#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
> -+/** @ingroup socket */
> -+#define recvfrom(s,mem,len,flags,from,fromlen)
> lwip_recvfrom(s,mem,len,flags,from,fromlen)
> -+/** @ingroup socket */
> -+#define send(s,dataptr,size,flags)
> lwip_send(s,dataptr,size,flags)
> -+/** @ingroup socket */
> -+#define sendmsg(s,message,flags)
> lwip_sendmsg(s,message,flags)
> -+/** @ingroup socket */
> -+#define sendto(s,dataptr,size,flags,to,tolen)
> lwip_sendto(s,dataptr,size,flags,to,tolen)
> -+/** @ingroup socket */
> -+#define socket(domain,type,protocol)
> lwip_socket(domain,type,protocol)
> -+/** @ingroup socket */
> -+#define select(maxfdp1,readset,writeset,exceptset,timeout)
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> -+/** @ingroup socket */
> -+#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> -+
> -+#if LWIP_POSIX_SOCKETS_IO_NAMES
> -+/** @ingroup socket */
> -+#define read(s,mem,len) lwip_read(s,mem,len)
> -+/** @ingroup socket */
> -+#define write(s,dataptr,len) lwip_write(s,dataptr,len)
> -+/** @ingroup socket */
> -+#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
> -+/** @ingroup socket */
> -+#define close(s) lwip_close(s)
> -+/** @ingroup socket */
> -+#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val)
> -+/** @ingroup socket */
> -+#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> -+#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> -+#endif /* LWIP_COMPAT_SOCKETS != 2 */
> -+
> -+#if LWIP_IPV4 && LWIP_IPV6
> -+/** @ingroup socket */
> -+#define inet_ntop(af,src,dst,size) \
> -+ (((af) == AF_INET6) ? ip6addr_ntoa_r((const
> ip6_addr_t*)(src),(dst),(size)) \
> -+ : (((af) == AF_INET) ? ip4addr_ntoa_r((const
> ip4_addr_t*)(src),(dst),(size)) : NULL))
> -+/** @ingroup socket */
> -+#define inet_pton(af,src,dst) \
> -+ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
> -+ : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
> -+#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
> -+#define inet_ntop(af,src,dst,size) \
> -+ (((af) == AF_INET) ? ip4addr_ntoa_r((const
> ip4_addr_t*)(src),(dst),(size)) : NULL)
> -+#define inet_pton(af,src,dst) \
> -+ (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
> -+#else /* LWIP_IPV4 && LWIP_IPV6 */
> -+#define inet_ntop(af,src,dst,size) \
> -+ (((af) == AF_INET6) ? ip6addr_ntoa_r((const
> ip6_addr_t*)(src),(dst),(size)) : NULL)
> -+#define inet_pton(af,src,dst) \
> -+ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
> -+#endif /* LWIP_IPV4 && LWIP_IPV6 */
> -+
> -+#endif /* LWIP_COMPAT_SOCKETS */
> -+
> -+#ifdef __cplusplus
> -+}
> -+#endif
> -+
> -+#endif /* LWIP_SOCKET */
> -+
> -+#endif /* LWIP_HDR_PRIV_SOCKETS_H */
> ++/**
> ++ * @file
> ++ * Socket API (to be used from non-TCPIP threads)
> ++ */
> ++
> ++/*
> ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
> ++ * All rights reserved.
> ++ *
> ++ * Redistribution and use in source and binary forms, with or without
> modification,
> ++ * are permitted provided that the following conditions are met:
> ++ *
> ++ * 1. Redistributions of source code must retain the above copyright notice,
> ++ * this list of conditions and the following disclaimer.
> ++ * 2. Redistributions in binary form must reproduce the above copyright
> notice,
> ++ * this list of conditions and the following disclaimer in the
> documentation
> ++ * and/or other materials provided with the distribution.
> ++ * 3. The name of the author may not be used to endorse or promote products
> ++ * derived from this software without specific prior written permission.
> ++ *
> ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> IMPLIED
> ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
> NO EVENT
> ++ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> ++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> PROCUREMENT
> ++ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS
> ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
> ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
> ARISING
> ++ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
> POSSIBILITY
> ++ * OF SUCH DAMAGE.
> ++ *
> ++ * This file is part of the lwIP TCP/IP stack.
> ++ *
> ++ * Author: Adam Dunkels <adam@sics.se>
> ++ *
> ++ */
> ++
> ++
> ++#ifndef LWIP_HDR_PRIV_SOCKETS_H
> ++#define LWIP_HDR_PRIV_SOCKETS_H
> ++
> ++#include "lwip/opt.h"
> ++
> ++#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
> ++
> ++#include "lwip/ip_addr.h"
> ++#include "lwip/err.h"
> ++#include "lwip/inet.h"
> ++#include "lwip/errno.h"
> ++
> ++#ifdef __cplusplus
> ++extern "C" {
> ++#endif
> ++
> ++#define _HAVE_SA_LEN 1
> ++
> ++/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED
> ++ to prevent this code from redefining it. */
> ++#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED)
> ++typedef u8_t sa_family_t;
> ++#endif
> ++/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED
> ++ to prevent this code from redefining it. */
> ++#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED)
> ++typedef u16_t in_port_t;
> ++#endif
> ++
> ++#if LWIP_IPV4
> ++/* members are in network byte order */
> ++struct sockaddr_in {
> ++ u8_t sin_len;
> ++ sa_family_t sin_family;
> ++ in_port_t sin_port;
> ++ struct in_addr sin_addr;
> ++#define SIN_ZERO_LEN 8
> ++ char sin_zero[SIN_ZERO_LEN];
> ++};
> ++#endif /* LWIP_IPV4 */
> ++
> ++#if LWIP_IPV6
> ++struct sockaddr_in6 {
> ++ u8_t sin6_len; /* length of this structure */
> ++ sa_family_t sin6_family; /* AF_INET6 */
> ++ in_port_t sin6_port; /* Transport layer port # */
> ++ u32_t sin6_flowinfo; /* IPv6 flow information */
> ++ struct in6_addr sin6_addr; /* IPv6 address */
> ++ u32_t sin6_scope_id; /* Set of interfaces for scope */
> ++};
> ++#endif /* LWIP_IPV6 */
> ++
> ++struct sockaddr {
> ++ u8_t sa_len;
> ++ sa_family_t sa_family;
> ++ char sa_data[14];
> ++};
> ++
> ++struct sockaddr_storage {
> ++ u8_t s2_len;
> ++ sa_family_t ss_family;
> ++ char s2_data1[2];
> ++ u32_t s2_data2[3];
> ++#if LWIP_IPV6
> ++ u32_t s2_data3[3];
> ++#endif /* LWIP_IPV6 */
> ++};
> ++
> ++/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED
> ++ to prevent this code from redefining it. */
> ++#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED)
> ++typedef u32_t socklen_t;
> ++#endif
> ++
> ++struct lwip_sock;
> ++
> ++#if !LWIP_TCPIP_CORE_LOCKING
> ++/** Maximum optlen used by setsockopt/getsockopt */
> ++#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16
> ++
> ++/** This struct is used to pass data to the set/getsockopt_internal
> ++ * functions running in tcpip_thread context (only a void* is allowed) */
> ++struct lwip_setgetsockopt_data {
> ++ /** socket index for which to change options */
> ++ int s;
> ++ /** level of the option to process */
> ++ int level;
> ++ /** name of the option to process */
> ++ int optname;
> ++ /** set: value to set the option to
> ++ * get: value of the option is stored here */
> ++#if LWIP_MPU_COMPATIBLE
> ++ u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN];
> ++#else
> ++ union {
> ++ void *p;
> ++ const void *pc;
> ++ } optval;
> ++#endif
> ++ /** size of *optval */
> ++ socklen_t optlen;
> ++ /** if an error occurs, it is temporarily stored here */
> ++ err_t err;
> ++ /** semaphore to wake up the calling task */
> ++ void* completed_sem;
> ++};
> ++#endif /* !LWIP_TCPIP_CORE_LOCKING */
> ++
> ++#if !defined(iovec)
> ++struct iovec {
> ++ void *iov_base;
> ++ size_t iov_len;
> ++};
> ++#endif
> ++
> ++struct msghdr {
> ++ void *msg_name;
> ++ socklen_t msg_namelen;
> ++ struct iovec *msg_iov;
> ++ int msg_iovlen;
> ++ void *msg_control;
> ++ socklen_t msg_controllen;
> ++ int msg_flags;
> ++};
> ++
> ++/* Socket protocol types (TCP/UDP/RAW) */
> ++#define SOCK_STREAM 1
> ++#define SOCK_DGRAM 2
> ++#define SOCK_RAW 3
> ++
> ++/*
> ++ * Option flags per-socket. These must match the SOF_ flags in ip.h
> (checked in init.c)
> ++ */
> ++#define SO_REUSEADDR 0x0004 /* Allow local address reuse */
> ++#define SO_KEEPALIVE 0x0008 /* keep connections alive */
> ++#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast
> messages (see IP_SOF_BROADCAST option) */
> ++
> ++
> ++/*
> ++ * Additional options, not kept in so_options.
> ++ */
> ++#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info
> recording */
> ++#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
> ++#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface
> addresses */
> ++#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when
> possible */
> ++#define SO_LINGER 0x0080 /* linger on close if data present */
> ++#define SO_DONTLINGER ((int)(~SO_LINGER))
> ++#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in
> line */
> ++#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port
> reuse */
> ++#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */
> ++#define SO_RCVBUF 0x1002 /* receive buffer size */
> ++#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */
> ++#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */
> ++#define SO_SNDTIMEO 0x1005 /* send timeout */
> ++#define SO_RCVTIMEO 0x1006 /* receive timeout */
> ++#define SO_ERROR 0x1007 /* get error status and clear */
> ++#define SO_TYPE 0x1008 /* get socket type */
> ++#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */
> ++#define SO_NO_CHECK 0x100a /* don't create UDP checksum */
> ++
> ++
> ++/*
> ++ * Structure used for manipulating linger option.
> ++ */
> ++struct linger {
> ++ int l_onoff; /* option on/off */
> ++ int l_linger; /* linger time in seconds */
> ++};
> ++
> ++/*
> ++ * Level number for (get/set)sockopt() to apply to socket itself.
> ++ */
> ++#define SOL_SOCKET 0xfff /* options for socket level */
> ++
> ++
> ++#define AF_UNSPEC 0
> ++#define AF_INET 2
> ++#if LWIP_IPV6
> ++#define AF_INET6 10
> ++#else /* LWIP_IPV6 */
> ++#define AF_INET6 AF_UNSPEC
> ++#endif /* LWIP_IPV6 */
> ++#define PF_INET AF_INET
> ++#define PF_INET6 AF_INET6
> ++#define PF_UNSPEC AF_UNSPEC
> ++
> ++#define IPPROTO_IP 0
> ++#define IPPROTO_ICMP 1
> ++#define IPPROTO_TCP 6
> ++#define IPPROTO_UDP 17
> ++#if LWIP_IPV6
> ++#define IPPROTO_IPV6 41
> ++#define IPPROTO_ICMPV6 58
> ++#endif /* LWIP_IPV6 */
> ++#define IPPROTO_UDPLITE 136
> ++#define IPPROTO_RAW 255
> ++
> ++/* Flags we can use with send and recv. */
> ++#define MSG_PEEK 0x01 /* Peeks at an incoming message */
> ++#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function
> block until the full amount of data requested can be returned */
> ++#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data.
> The significance and semantics of out-of-band data are protocol-specific */
> ++#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */
> ++#define MSG_MORE 0x10 /* Sender will send more */
> ++
> ++
> ++/*
> ++ * Options for level IPPROTO_IP
> ++ */
> ++#define IP_TOS 1
> ++#define IP_TTL 2
> ++
> ++#if LWIP_TCP
> ++/*
> ++ * Options for level IPPROTO_TCP
> ++ */
> ++#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
> ++#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for
> pcb->keep_idle milliseconds */
> ++#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as
> TCP_KEEPALIVE, but use seconds for get/setsockopt */
> ++#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for
> get/setsockopt */
> ++#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of
> probes sent for get/setsockopt */
> ++#endif /* LWIP_TCP */
> ++
> ++#if LWIP_IPV6
> ++/*
> ++ * Options for level IPPROTO_IPV6
> ++ */
> ++#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6
> checksum for raw sockets. */
> ++#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict
> AF_INET6 sockets to IPv6 communications only. */
> ++#endif /* LWIP_IPV6 */
> ++
> ++#if LWIP_UDP && LWIP_UDPLITE
> ++/*
> ++ * Options for level IPPROTO_UDPLITE
> ++ */
> ++#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */
> ++#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */
> ++#endif /* LWIP_UDP && LWIP_UDPLITE*/
> ++
> ++
> ++#if LWIP_MULTICAST_TX_OPTIONS
> ++/*
> ++ * Options and types for UDP multicast traffic handling
> ++ */
> ++#define IP_MULTICAST_TTL 5
> ++#define IP_MULTICAST_IF 6
> ++#define IP_MULTICAST_LOOP 7
> ++#endif /* LWIP_MULTICAST_TX_OPTIONS */
> ++
> ++#if LWIP_IGMP
> ++/*
> ++ * Options and types related to multicast membership
> ++ */
> ++#define IP_ADD_MEMBERSHIP 3
> ++#define IP_DROP_MEMBERSHIP 4
> ++
> ++typedef struct ip_mreq {
> ++ struct in_addr imr_multiaddr; /* IP multicast address of group */
> ++ struct in_addr imr_interface; /* local IP address of interface */
> ++} ip_mreq;
> ++#endif /* LWIP_IGMP */
> ++
> ++/*
> ++ * The Type of Service provides an indication of the abstract
> ++ * parameters of the quality of service desired. These parameters are
> ++ * to be used to guide the selection of the actual service parameters
> ++ * when transmitting a datagram through a particular network. Several
> ++ * networks offer service precedence, which somehow treats high
> ++ * precedence traffic as more important than other traffic (generally
> ++ * by accepting only traffic above a certain precedence at time of high
> ++ * load). The major choice is a three way tradeoff between low-delay,
> ++ * high-reliability, and high-throughput.
> ++ * The use of the Delay, Throughput, and Reliability indications may
> ++ * increase the cost (in some sense) of the service. In many networks
> ++ * better performance for one of these parameters is coupled with worse
> ++ * performance on another. Except for very unusual cases at most two
> ++ * of these three indications should be set.
> ++ */
> ++#define IPTOS_TOS_MASK 0x1E
> ++#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK)
> ++#define IPTOS_LOWDELAY 0x10
> ++#define IPTOS_THROUGHPUT 0x08
> ++#define IPTOS_RELIABILITY 0x04
> ++#define IPTOS_LOWCOST 0x02
> ++#define IPTOS_MINCOST IPTOS_LOWCOST
> ++
> ++/*
> ++ * The Network Control precedence designation is intended to be used
> ++ * within a network only. The actual use and control of that
> ++ * designation is up to each network. The Internetwork Control
> ++ * designation is intended for use by gateway control originators only.
> ++ * If the actual use of these precedence designations is of concern to
> ++ * a particular network, it is the responsibility of that network to
> ++ * control the access to, and use of, those precedence designations.
> ++ */
> ++#define IPTOS_PREC_MASK 0xe0
> ++#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK)
> ++#define IPTOS_PREC_NETCONTROL 0xe0
> ++#define IPTOS_PREC_INTERNETCONTROL 0xc0
> ++#define IPTOS_PREC_CRITIC_ECP 0xa0
> ++#define IPTOS_PREC_FLASHOVERRIDE 0x80
> ++#define IPTOS_PREC_FLASH 0x60
> ++#define IPTOS_PREC_IMMEDIATE 0x40
> ++#define IPTOS_PREC_PRIORITY 0x20
> ++#define IPTOS_PREC_ROUTINE 0x00
> ++
> ++
> ++/*
> ++ * Commands for ioctlsocket(), taken from the BSD file fcntl.h.
> ++ * lwip_ioctl only supports FIONREAD and FIONBIO, for now
> ++ *
> ++ * Ioctl's have the command encoded in the lower word,
> ++ * and the size of any in or out parameters in the upper
> ++ * word. The high 2 bits of the upper word are used
> ++ * to encode the in/out status of the parameter; for now
> ++ * we restrict parameters to at most 128 bytes.
> ++ */
> ++#if !defined(FIONREAD) || !defined(FIONBIO)
> ++#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */
> ++#define IOC_VOID 0x20000000UL /* no parameters */
> ++#define IOC_OUT 0x40000000UL /* copy out parameters */
> ++#define IOC_IN 0x80000000UL /* copy in parameters */
> ++#define IOC_INOUT (IOC_IN|IOC_OUT)
> ++ /* 0x20000000 distinguishes new &
> ++ old ioctl's */
> ++#define _IO(x,y) (IOC_VOID|((x)<<8)|(y))
> ++
> ++#define _IOR(x,y,t)
> (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> ++
> ++#define _IOW(x,y,t)
> (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
> ++#endif /* !defined(FIONREAD) || !defined(FIONBIO) */
> ++
> ++#ifndef FIONREAD
> ++#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */
> ++#endif
> ++#ifndef FIONBIO
> ++#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking
> i/o */
> ++#endif
> ++
> ++/* Socket I/O Controls: unimplemented */
> ++#ifndef SIOCSHIWAT
> ++#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */
> ++#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */
> ++#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */
> ++#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */
> ++#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */
> ++#endif
> ++
> ++/* commands for fnctl */
> ++#ifndef F_GETFL
> ++#define F_GETFL 3
> ++#endif
> ++#ifndef F_SETFL
> ++#define F_SETFL 4
> ++#endif
> ++
> ++/* File status flags and file access modes for fnctl,
> ++ these are bits in an int. */
> ++#ifndef O_NONBLOCK
> ++#define O_NONBLOCK 1 /* nonblocking I/O */
> ++#endif
> ++#ifndef O_NDELAY
> ++#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */
> ++#endif
> ++
> ++#ifndef SHUT_RD
> ++ #define SHUT_RD 0
> ++ #define SHUT_WR 1
> ++ #define SHUT_RDWR 2
> ++#endif
> ++
> ++/* FD_SET used for lwip_select */
> ++#ifndef FD_SET
> ++#undef FD_SETSIZE
> ++/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */
> ++#define FD_SETSIZE MEMP_NUM_NETCONN
> ++#define FDSETSAFESET(n, code) do { \
> ++ if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) -
> LWIP_SOCKET_OFFSET) >= 0)) { \
> ++ code; }} while(0)
> ++#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET <
> MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\
> ++ (code) : 0)
> ++#define FD_SET(n, p) FDSETSAFESET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> ++#define FD_CLR(n, p) FDSETSAFESET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> ++#define FD_ISSET(n,p) FDSETSAFEGET(n,
> (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET)
> & 7)))
> ++#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p)))
> ++
> ++typedef struct fd_set
> ++{
> ++ unsigned char fd_bits [(FD_SETSIZE+7)/8];
> ++} fd_set;
> ++
> ++#elif LWIP_SOCKET_OFFSET
> ++#error LWIP_SOCKET_OFFSET does not work with external FD_SET!
> ++#elif FD_SETSIZE < MEMP_NUM_NETCONN
> ++#error "external FD_SETSIZE too small for number of sockets"
> ++#endif /* FD_SET */
> ++
> ++/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided
> ++ * by your system, set this to 0 and include <sys/time.h> in cc.h */
> ++#ifndef LWIP_TIMEVAL_PRIVATE
> ++#define LWIP_TIMEVAL_PRIVATE 1
> ++#endif
> ++
> ++#if LWIP_TIMEVAL_PRIVATE
> ++struct timeval {
> ++ long tv_sec; /* seconds */
> ++ long tv_usec; /* and microseconds */
> ++};
> ++#endif /* LWIP_TIMEVAL_PRIVATE */
> ++
> ++#define lwip_socket_init() /* Compatibility define, no init needed. */
> ++void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1:
> initialize thread-local semaphore */
> ++void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1:
> destroy thread-local semaphore */
> ++
> ++#if LWIP_COMPAT_SOCKETS == 2
> ++/* This helps code parsers/code completion by not having the COMPAT
> functions as defines */
> ++#define lwip_accept accept
> ++#define lwip_bind bind
> ++#define lwip_shutdown shutdown
> ++#define lwip_getpeername getpeername
> ++#define lwip_getsockname getsockname
> ++#define lwip_setsockopt setsockopt
> ++#define lwip_getsockopt getsockopt
> ++#define lwip_close closesocket
> ++#define lwip_connect connect
> ++#define lwip_listen listen
> ++#define lwip_recv recv
> ++#define lwip_recvfrom recvfrom
> ++#define lwip_send send
> ++#define lwip_sendmsg sendmsg
> ++#define lwip_sendto sendto
> ++#define lwip_socket socket
> ++#define lwip_select select
> ++#define lwip_ioctlsocket ioctl
> ++
> ++#if LWIP_POSIX_SOCKETS_IO_NAMES
> ++#define lwip_read read
> ++#define lwip_write write
> ++#define lwip_writev writev
> ++#undef lwip_close
> ++#define lwip_close close
> ++#define closesocket(s) close(s)
> ++#define lwip_fcntl fcntl
> ++#define lwip_ioctl ioctl
> ++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> ++#endif /* LWIP_COMPAT_SOCKETS == 2 */
> ++
> ++#if LWIP_COMPAT_SOCKETS
> ++#if LWIP_COMPAT_SOCKETS != 2
> ++/** @ingroup socket */
> ++#define accept(s,addr,addrlen)
> lwip_accept(s,addr,addrlen)
> ++/** @ingroup socket */
> ++#define bind(s,name,namelen) lwip_bind(s,name,namelen)
> ++/** @ingroup socket */
> ++#define shutdown(s,how) lwip_shutdown(s,how)
> ++/** @ingroup socket */
> ++#define getpeername(s,name,namelen)
> lwip_getpeername(s,name,namelen)
> ++/** @ingroup socket */
> ++#define getsockname(s,name,namelen)
> lwip_getsockname(s,name,namelen)
> ++/** @ingroup socket */
> ++#define setsockopt(s,level,optname,opval,optlen)
> lwip_setsockopt(s,level,optname,opval,optlen)
> ++/** @ingroup socket */
> ++#define getsockopt(s,level,optname,opval,optlen)
> lwip_getsockopt(s,level,optname,opval,optlen)
> ++/** @ingroup socket */
> ++#define closesocket(s) lwip_close(s)
> ++/** @ingroup socket */
> ++#define connect(s,name,namelen)
> lwip_connect(s,name,namelen)
> ++/** @ingroup socket */
> ++#define listen(s,backlog) lwip_listen(s,backlog)
> ++/** @ingroup socket */
> ++#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags)
> ++/** @ingroup socket */
> ++#define recvfrom(s,mem,len,flags,from,fromlen)
> lwip_recvfrom(s,mem,len,flags,from,fromlen)
> ++/** @ingroup socket */
> ++#define send(s,dataptr,size,flags)
> lwip_send(s,dataptr,size,flags)
> ++/** @ingroup socket */
> ++#define sendmsg(s,message,flags)
> lwip_sendmsg(s,message,flags)
> ++/** @ingroup socket */
> ++#define sendto(s,dataptr,size,flags,to,tolen)
> lwip_sendto(s,dataptr,size,flags,to,tolen)
> ++/** @ingroup socket */
> ++#define socket(domain,type,protocol)
> lwip_socket(domain,type,protocol)
> ++/** @ingroup socket */
> ++#define select(maxfdp1,readset,writeset,exceptset,timeout)
> lwip_select(maxfdp1,readset,writeset,exceptset,timeout)
> ++/** @ingroup socket */
> ++#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> ++
> ++#if LWIP_POSIX_SOCKETS_IO_NAMES
> ++/** @ingroup socket */
> ++#define read(s,mem,len) lwip_read(s,mem,len)
> ++/** @ingroup socket */
> ++#define write(s,dataptr,len) lwip_write(s,dataptr,len)
> ++/** @ingroup socket */
> ++#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt)
> ++/** @ingroup socket */
> ++#define close(s) lwip_close(s)
> ++/** @ingroup socket */
> ++#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val)
> ++/** @ingroup socket */
> ++#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp)
> ++#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
> ++#endif /* LWIP_COMPAT_SOCKETS != 2 */
> ++
> ++#if LWIP_IPV4 && LWIP_IPV6
> ++/** @ingroup socket */
> ++#define inet_ntop(af,src,dst,size) \
> ++ (((af) == AF_INET6) ? ip6addr_ntoa_r((const
> ip6_addr_t*)(src),(dst),(size)) \
> ++ : (((af) == AF_INET) ? ip4addr_ntoa_r((const
> ip4_addr_t*)(src),(dst),(size)) : NULL))
> ++/** @ingroup socket */
> ++#define inet_pton(af,src,dst) \
> ++ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \
> ++ : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0))
> ++#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
> ++#define inet_ntop(af,src,dst,size) \
> ++ (((af) == AF_INET) ? ip4addr_ntoa_r((const
> ip4_addr_t*)(src),(dst),(size)) : NULL)
> ++#define inet_pton(af,src,dst) \
> ++ (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)
> ++#else /* LWIP_IPV4 && LWIP_IPV6 */
> ++#define inet_ntop(af,src,dst,size) \
> ++ (((af) == AF_INET6) ? ip6addr_ntoa_r((const
> ip6_addr_t*)(src),(dst),(size)) : NULL)
> ++#define inet_pton(af,src,dst) \
> ++ (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0)
> ++#endif /* LWIP_IPV4 && LWIP_IPV6 */
> ++
> ++#endif /* LWIP_COMPAT_SOCKETS */
> ++
> ++#ifdef __cplusplus
> ++}
> ++#endif
> ++
> ++#endif /* LWIP_SOCKET */
> ++
> ++#endif /* LWIP_HDR_PRIV_SOCKETS_H */
> --- a/src/include/lwip/opt.h
> +++ b/src/include/lwip/opt.h
> @@ -1760,6 +1760,15 @@
> @@ -1497,7 +1497,7 @@ Won't get to upstream
> int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
> int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen);
> int lwip_shutdown(int s, int how);
> -@@ -506,88 +78,16 @@ int lwip_select(int maxfdp1, fd_set *rea
> +@@ -506,88 +78,16 @@
> int lwip_ioctl(int s, long cmd, void *argp);
> int lwip_fcntl(int s, int cmd, int val);
>
> @@ -1596,35 +1596,20 @@ Won't get to upstream
> --- a/port/include/lwipopts.h
> +++ b/port/include/lwipopts.h
> @@ -26,6 +26,11 @@
> - /* Don't rename Sockets API functions */
> - #define LWIP_COMPAT_SOCKETS 0
> -
> -+/* Use Glibc's sockets headers */
> -+#define LWIP_STD_SOCKETS 1
> -+#define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
> -+#define LWIP_INCLUDE_STD_INET "posix/inet.h"
> -+
> - /* Use Glibc malloc()/free() */
> - #define MEM_LIBC_MALLOC 1
> - #define MEMP_MEM_MALLOC 1
> ---- a/port/include/arch/cc.h
> -+++ b/port/include/arch/cc.h
> -@@ -40,6 +40,12 @@
> - /* Use our own ioctls */
> - #include <sys/ioctl.h>
> -
> -+/* Use our own <sys/socket.h> */
> -+#include <sys/socket.h>
> -+#include <netinet/in.h>
> -+#include <netinet/tcp.h>
> -+#include <netinet/udp.h>
> -+
> - /* Use our own htons() and pals */
> - #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS 1
> -
> + /* Don't rename Sockets API functions */
> + #define LWIP_COMPAT_SOCKETS 0
> +
> ++/* Use Glibc's sockets headers */
> ++#define LWIP_STD_SOCKETS 1
> ++#define LWIP_INCLUDE_STD_SOCKETS "posix/socket.h"
> ++#define LWIP_INCLUDE_STD_INET "posix/inet.h"
> ++
> + /* Use Glibc malloc()/free() */
> + #define MEM_LIBC_MALLOC 1
> + #define MEMP_MEM_MALLOC 1
> --- a/src/api/netdb.c
> +++ b/src/api/netdb.c
> -@@ -374,7 +374,9 @@ lwip_getaddrinfo(const char *nodename, c
> +@@ -374,7 +374,9 @@
> /* set up sockaddr */
> inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr));
> sa6->sin6_family = AF_INET6;
> @@ -1634,7 +1619,7 @@ Won't get to upstream
> sa6->sin6_port = lwip_htons((u16_t)port_nr);
> ai->ai_family = AF_INET6;
> #endif /* LWIP_IPV6 */
> -@@ -384,7 +386,9 @@ lwip_getaddrinfo(const char *nodename, c
> +@@ -384,7 +386,9 @@
> /* set up sockaddr */
> inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr));
> sa4->sin_family = AF_INET;
> @@ -1676,7 +1661,7 @@ Won't get to upstream
> (sin6)->sin6_family = AF_INET6; \
> (sin6)->sin6_port = lwip_htons((port)); \
> (sin6)->sin6_flowinfo = 0; \
> -@@ -537,9 +547,11 @@ lwip_accept(int s, struct sockaddr *addr
> +@@ -537,9 +547,11 @@
> LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL);
>
> IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port);
> @@ -1688,7 +1673,7 @@ Won't get to upstream
> MEMCPY(addr, &tempaddr, *addrlen);
>
> LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d
> addr=", s, newsock));
> -@@ -878,9 +890,11 @@ lwip_recvfrom(int s, void *mem, size_t l
> +@@ -878,9 +890,11 @@
> if (from && fromlen)
> #endif /* SOCKETS_DEBUG */
> {
> @@ -1700,7 +1685,7 @@ Won't get to upstream
> MEMCPY(from, &saddr, *fromlen);
> }
> }
> -@@ -1764,9 +1778,11 @@ lwip_getaddrname(int s, struct sockaddr
> +@@ -1764,9 +1778,11 @@
> ip_addr_debug_print_val(SOCKETS_DEBUG, naddr);
> LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port));
>
> --
> 2.11.0
>
>
>
>
--
Samuel
void *memmem (const void *meule_de_foin, size_t lg_meule,
const void *aiguille, size_t lg_aiguille);
(extrait de la page de man de memmem -- Manuel du programmeur Linux)