[rtems-net-legacy PATCH 4/4] net: Update socketpair to the lwip code

chrisj at rtems.org chrisj at rtems.org
Sat Apr 22 23:02:30 UTC 2023


From: Chris Johns <chrisj at rtems.org>

---
 rtems/rtems_socketpair.c | 133 ++++++++++++++++++++++++++++++---------
 1 file changed, 105 insertions(+), 28 deletions(-)

diff --git a/rtems/rtems_socketpair.c b/rtems/rtems_socketpair.c
index 1dcaf6e..5b8bac3 100644
--- a/rtems/rtems_socketpair.c
+++ b/rtems/rtems_socketpair.c
@@ -1,53 +1,130 @@
 #include <machine/rtems-bsd-kernel-space.h>
 
 /*
- *  socketpair() for RTEMS
  *
- *  This file exists primarily to document what is required to provide
- *  a functional implementation of socketpair() for RTEMS.
+ * RTEMS Project (https://www.rtems.org/)
  *
- *  The socketpair() service requires that the "local domain" sockets
- *  be functional.  This is denoted by the domain constants AF_LOCAL
- *  and AF_UNIX and the protocol constants PF_LOCAL and PF_UNIX.  The
- *  local domain functionality is implemented in the file kern/uipc_usrreq.c
- *  which was not part of the initial port of the FreeBSD stack to
- *  RTEMS.
+ * Copyright (c) 2021 Vijay Kumar Banerjee <vijay at rtems.org>.
+ * All rights reserved.
  *
- *  The FreeBSD socketpair implementation appears to be dependent on
- *  file system features which are not available currently in RTEMS.
+ *  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.
  *
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "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 COPYRIGHT
+ *  OWNER OR CONTRIBUTORS 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.
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+
+#include <rtems/rtems_bsdnet_internal.h>
+
 #include <unistd.h>
+#include <netinet/in.h>
 #include <sys/socket.h>
 #include <errno.h>
 
 #include "rtems_syscall.h"
 
-int socketpair (int domain, int type, int protocol, int *rsv)
+static int setup_socketpair(int listener, int *socket_vector)
+{
+  union {
+    struct sockaddr addr;
+    struct sockaddr_in inaddr;
+  } a;
+  int reuse = 1;
+  socklen_t addrlen = sizeof(a.inaddr);
+
+  memset(&a, 0, sizeof(a));
+  a.inaddr.sin_family = AF_INET;
+  a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  a.inaddr.sin_port = 0;
+
+  if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR,
+       (char*) &reuse, (socklen_t) sizeof(reuse)) == -1) {
+    return 1;
+  }
+
+  if  (bind(listener, &a.addr, sizeof(a.inaddr)) == -1) {
+    return 1;
+  }
+
+  memset(&a, 0, sizeof(a));
+  if  (getsockname(listener, &a.addr, &addrlen) == -1) {
+    return 1;
+  }
+
+  a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  a.inaddr.sin_family = AF_INET;
+
+  if (listen(listener, 1) == -1) {
+    return 1;
+  }
+
+  socket_vector[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (socket_vector[0] == -1) {
+    return 1;
+  }
+
+  if (connect(socket_vector[0], &a.addr, sizeof(a.inaddr)) == -1) {
+    return 1;
+  }
+
+  socket_vector[1] = accept(listener, NULL, NULL);
+  if (socket_vector[1] == -1) {
+    return 1;
+  }
+
+  close(listener);
+  return 0;
+}
+
+/* Fake socketpair() support with a loopback TCP socket */
+int
+socketpair(int domain, int type, int protocol, int *socket_vector)
 {
-  if ( !rsv ) {
-    errno = EFAULT;
+  int listener;
+  int saved_errno;
+
+  if (socket_vector == NULL) {
+    errno = EINVAL;
     return -1;
   }
+  socket_vector[0] = socket_vector[1] = -1;
+
+  listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (listener == -1)
+    return -1;
+
+  if (setup_socketpair(listener, socket_vector) == 0) {
+    return 0;
+  }
 
-  /*
-   *  Yes, we do not support socketpair() so this is really paranoid.
-   *  But it ensures that someone calling this routine and ignoring
-   *  the return status will get errors from subsequent socket calls.
-   */
-  rsv[ 0 ] = -1;
-  rsv[ 1 ] = -1;
-  errno = ENOSYS;
+  saved_errno = errno;
+  close(listener);
+  close(socket_vector[0]);
+  close(socket_vector[1]);
+  errno = saved_errno;
+  socket_vector[0] = socket_vector[1] = -1;
   return -1;
 }
-- 
2.37.1



More information about the devel mailing list