Merge commit '5b7632331e7551ac202bbaba37c572b96a791c6e'
[bpt/guile.git] / libguile / socket.c
index 5119ce3..2a9be54 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
- *   2006, 2007, 2009, 2011, 2012 Free Software Foundation, Inc.
+ *   2006, 2007, 2009, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public License
 #endif
 
 #include <errno.h>
-#include <gmp.h>
 #include <verify.h>
 
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_UNIX_DOMAIN_SOCKETS
+#include <sys/un.h>
+#endif
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include <gmp.h>
+
 #include "libguile/_scm.h"
 #include "libguile/arrays.h"
 #include "libguile/feature.h"
 # include "libguile/deprecation.h"
 #endif
 
-#ifdef __MINGW32__
-#include "win32-socket.h"
-#include <netdb.h>
-#endif
 
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#else
-#include <sys/socket.h>
-#ifdef HAVE_UNIX_DOMAIN_SOCKETS
-#include <sys/un.h>
-#endif
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#endif
 
 #if defined (HAVE_UNIX_DOMAIN_SOCKETS) && !defined (SUN_LEN)
-#define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
+#define SUN_LEN(ptr) (offsetof (struct sockaddr_un, sun_path) \
                      + strlen ((ptr)->sun_path))
 #endif
 
@@ -98,50 +90,6 @@ typedef union
 
 \f
 
-SCM_DEFINE (scm_htons, "htons", 1, 0, 0, 
-            (SCM value),
-           "Convert a 16 bit quantity from host to network byte ordering.\n"
-           "@var{value} is packed into 2 bytes, which are then converted\n"
-           "and returned as a new integer.")
-#define FUNC_NAME s_scm_htons
-{
-  return scm_from_ushort (htons (scm_to_ushort (value)));
-}
-#undef FUNC_NAME
-
-SCM_DEFINE (scm_ntohs, "ntohs", 1, 0, 0, 
-            (SCM value),
-           "Convert a 16 bit quantity from network to host byte ordering.\n"
-           "@var{value} is packed into 2 bytes, which are then converted\n"
-           "and returned as a new integer.")
-#define FUNC_NAME s_scm_ntohs
-{
-  return scm_from_ushort (ntohs (scm_to_ushort (value)));
-}
-#undef FUNC_NAME
-
-SCM_DEFINE (scm_htonl, "htonl", 1, 0, 0, 
-            (SCM value),
-           "Convert a 32 bit quantity from host to network byte ordering.\n"
-           "@var{value} is packed into 4 bytes, which are then converted\n"
-           "and returned as a new integer.")
-#define FUNC_NAME s_scm_htonl
-{
-  return scm_from_ulong (htonl (scm_to_uint32 (value)));
-}
-#undef FUNC_NAME
-
-SCM_DEFINE (scm_ntohl, "ntohl", 1, 0, 0, 
-            (SCM value),
-           "Convert a 32 bit quantity from network to host byte ordering.\n"
-           "@var{value} is packed into 4 bytes, which are then converted\n"
-           "and returned as a new integer.")
-#define FUNC_NAME s_scm_ntohl
-{
-  return scm_from_ulong (ntohl (scm_to_uint32 (value)));
-}
-#undef FUNC_NAME
-
 #ifdef HAVE_INET_NETOF
 SCM_DEFINE (scm_inet_netof, "inet-netof", 1, 0, 0, 
             (SCM address),
@@ -516,6 +464,7 @@ SCM_DEFINE (scm_getsockopt, "getsockopt", 3, 0, 0,
            "@defvarx SO_OOBINLINE\n"
            "@defvarx SO_NO_CHECK\n"
            "@defvarx SO_PRIORITY\n"
+           "@defvarx SO_REUSEPORT\n"
            "The value returned is an integer.\n"
            "@end defvar\n"
            "\n"
@@ -614,6 +563,7 @@ SCM_DEFINE (scm_setsockopt, "setsockopt", 4, 0, 0,
            "@defvarx SO_OOBINLINE\n"
            "@defvarx SO_NO_CHECK\n"
            "@defvarx SO_PRIORITY\n"
+           "@defvarx SO_REUSEPORT\n"
            "@var{value} is an integer.\n"
            "@end defvar\n"
            "\n"
@@ -1335,7 +1285,7 @@ SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
   sock = SCM_COERCE_OUTPORT (sock);
   SCM_VALIDATE_OPFPORT (1, sock);
   fd = SCM_FPORT_FDES (sock);
-  newfd = accept (fd, (struct sockaddr *) &addr, &addr_size);
+  SCM_SYSCALL (newfd = accept (fd, (struct sockaddr *) &addr, &addr_size));
   if (newfd == -1)
     SCM_SYSERROR;
   newsock = SCM_SOCK_FD_TO_PORT (newfd);
@@ -1420,33 +1370,12 @@ SCM_DEFINE (scm_recv, "recv!", 2, 1, 0,
     flg = scm_to_int (flags);
   fd = SCM_FPORT_FDES (sock);
 
-#if SCM_ENABLE_DEPRECATED == 1
-  if (SCM_UNLIKELY (scm_is_string (buf)))
-    {
-      SCM msg;
-      char *dest;
-      size_t len;
-
-      scm_c_issue_deprecation_warning
-       ("Passing a string to `recv!' is deprecated, "
-        "use a bytevector instead.");
-
-      len = scm_i_string_length (buf);
-      msg = scm_i_make_string (len, &dest, 0);
-      SCM_SYSCALL (rv = recv (fd, dest, len, flg));
-      scm_string_copy_x (buf, scm_from_int (0),
-                        msg, scm_from_int (0), scm_from_size_t (len));
-    }
-  else
-#endif
-    {
-      SCM_VALIDATE_BYTEVECTOR (1, buf);
+  SCM_VALIDATE_BYTEVECTOR (1, buf);
 
-      SCM_SYSCALL (rv = recv (fd,
-                             SCM_BYTEVECTOR_CONTENTS (buf),
-                             SCM_BYTEVECTOR_LENGTH (buf),
-                             flg));
-    }
+  SCM_SYSCALL (rv = recv (fd,
+                          SCM_BYTEVECTOR_CONTENTS (buf),
+                          SCM_BYTEVECTOR_LENGTH (buf),
+                          flg));
 
   if (SCM_UNLIKELY (rv == -1))
     SCM_SYSERROR;
@@ -1486,35 +1415,12 @@ SCM_DEFINE (scm_send, "send", 2, 1, 0,
 
   fd = SCM_FPORT_FDES (sock);
 
-#if SCM_ENABLE_DEPRECATED == 1
-  if (SCM_UNLIKELY (scm_is_string (message)))
-    {
-      scm_c_issue_deprecation_warning
-       ("Passing a string to `send' is deprecated, "
-        "use a bytevector instead.");
-
-      /* If the string is wide, see if it can be coerced into a narrow
-        string.  */
-      if (!scm_i_is_narrow_string (message)
-         || !scm_i_try_narrow_string (message))
-       SCM_MISC_ERROR ("the message string is not 8-bit: ~s",
-                        scm_list_1 (message));
-
-      SCM_SYSCALL (rv = send (fd,
-                             scm_i_string_chars (message),
-                             scm_i_string_length (message),
-                             flg));
-    }
-  else
-#endif
-    {
-      SCM_VALIDATE_BYTEVECTOR (1, message);
+  SCM_VALIDATE_BYTEVECTOR (1, message);
 
-      SCM_SYSCALL (rv = send (fd,
-                             SCM_BYTEVECTOR_CONTENTS (message),
-                             SCM_BYTEVECTOR_LENGTH (message),
-                             flg));
-    }
+  SCM_SYSCALL (rv = send (fd,
+                          SCM_BYTEVECTOR_CONTENTS (message),
+                          SCM_BYTEVECTOR_LENGTH (message),
+                          flg));
 
   if (rv == -1)
     SCM_SYSERROR;
@@ -1572,52 +1478,28 @@ SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
 
   ((struct sockaddr *) &addr)->sa_family = AF_UNSPEC;
 
-#if SCM_ENABLE_DEPRECATED == 1
-  if (SCM_UNLIKELY (scm_is_string (buf)))
-    {
-      char *cbuf;
+  SCM_VALIDATE_BYTEVECTOR (1, buf);
 
-      scm_c_issue_deprecation_warning
-       ("Passing a string to `recvfrom!' is deprecated, "
-        "use a bytevector instead.");
-
-      scm_i_get_substring_spec (scm_i_string_length (buf),
-                               start, &offset, end, &cend);
-
-      buf = scm_i_string_start_writing (buf);
-      cbuf = scm_i_string_writable_chars (buf);
+  if (SCM_UNBNDP (start))
+    offset = 0;
+  else
+    offset = scm_to_size_t (start);
 
-      SCM_SYSCALL (rv = recvfrom (fd, cbuf + offset,
-                                 cend - offset, flg,
-                                 (struct sockaddr *) &addr, &addr_size));
-      scm_i_string_stop_writing ();
-    }
+  if (SCM_UNBNDP (end))
+    cend = SCM_BYTEVECTOR_LENGTH (buf);
   else
-#endif
     {
-      SCM_VALIDATE_BYTEVECTOR (1, buf);
-
-      if (SCM_UNBNDP (start))
-       offset = 0;
-      else
-       offset = scm_to_size_t (start);
-
-      if (SCM_UNBNDP (end))
-       cend = SCM_BYTEVECTOR_LENGTH (buf);
-      else
-       {
-         cend = scm_to_size_t (end);
-         if (SCM_UNLIKELY (cend >= SCM_BYTEVECTOR_LENGTH (buf)
-                           || cend < offset))
-           scm_out_of_range (FUNC_NAME, end);
-       }
-
-      SCM_SYSCALL (rv = recvfrom (fd,
-                                 SCM_BYTEVECTOR_CONTENTS (buf) + offset,
-                                 cend - offset, flg,
-                                 (struct sockaddr *) &addr, &addr_size));
+      cend = scm_to_size_t (end);
+      if (SCM_UNLIKELY (cend >= SCM_BYTEVECTOR_LENGTH (buf)
+                        || cend < offset))
+        scm_out_of_range (FUNC_NAME, end);
     }
 
+  SCM_SYSCALL (rv = recvfrom (fd,
+                              SCM_BYTEVECTOR_CONTENTS (buf) + offset,
+                              cend - offset, flg,
+                              (struct sockaddr *) &addr, &addr_size));
+
   if (rv == -1)
     SCM_SYSERROR;
 
@@ -1687,35 +1569,12 @@ SCM_DEFINE (scm_sendto, "sendto", 3, 1, 1,
       flg = SCM_NUM2ULONG (5, SCM_CAR (args_and_flags));
     }
 
-#if SCM_ENABLE_DEPRECATED == 1
-  if (SCM_UNLIKELY (scm_is_string (message)))
-    {
-      scm_c_issue_deprecation_warning
-       ("Passing a string to `sendto' is deprecated, "
-        "use a bytevector instead.");
-
-      /* If the string is wide, see if it can be coerced into a narrow
-        string.  */
-      if (!scm_i_is_narrow_string (message)
-         || !scm_i_try_narrow_string (message))
-       SCM_MISC_ERROR ("the message string is not 8-bit: ~s",
-                        scm_list_1 (message));
-
-      SCM_SYSCALL (rv = sendto (fd,
-                               scm_i_string_chars (message),
-                               scm_i_string_length (message),
-                               flg, soka, size));
-    }
-  else
-#endif
-    {
-      SCM_VALIDATE_BYTEVECTOR (1, message);
+  SCM_VALIDATE_BYTEVECTOR (1, message);
 
-      SCM_SYSCALL (rv = sendto (fd,
-                               SCM_BYTEVECTOR_CONTENTS (message),
-                               SCM_BYTEVECTOR_LENGTH (message),
-                               flg, soka, size));
-    }
+  SCM_SYSCALL (rv = sendto (fd,
+                            SCM_BYTEVECTOR_CONTENTS (message),
+                            SCM_BYTEVECTOR_LENGTH (message),
+                            flg, soka, size));
 
   if (rv == -1)
     {
@@ -1740,7 +1599,7 @@ scm_init_socket ()
 #ifdef AF_UNSPEC
   scm_c_define ("AF_UNSPEC", scm_from_int (AF_UNSPEC));
 #endif
-#ifdef AF_UNIX
+#if defined HAVE_UNIX_DOMAIN_SOCKETS && defined AF_UNIX
   scm_c_define ("AF_UNIX", scm_from_int (AF_UNIX));
 #endif
 #ifdef AF_INET
@@ -1862,6 +1721,9 @@ scm_init_socket ()
 #ifdef SO_LINGER
   scm_c_define ("SO_LINGER", scm_from_int (SO_LINGER));
 #endif
+#ifdef SO_REUSEPORT                              /* new in Linux 3.9 */
+  scm_c_define ("SO_REUSEPORT", scm_from_int (SO_REUSEPORT));
+#endif
 
   /* recv/send options.  */
 #ifdef MSG_DONTWAIT
@@ -1877,10 +1739,6 @@ scm_init_socket ()
   scm_c_define ("MSG_DONTROUTE", scm_from_int (MSG_DONTROUTE));
 #endif
 
-#ifdef __MINGW32__
-  scm_i_init_socket_Win32 ();
-#endif
-
 #ifdef IP_ADD_MEMBERSHIP
   scm_c_define ("IP_ADD_MEMBERSHIP", scm_from_int (IP_ADD_MEMBERSHIP));
   scm_c_define ("IP_DROP_MEMBERSHIP", scm_from_int (IP_DROP_MEMBERSHIP));