trying to port statvfs call to BSD
[oweals/gnunet.git] / src / util / network.c
index e7a276422a0554e513dc0dc934b987ba6f35fbcd..101e794d07c892827182455620e7d30dec5f2b88 100644 (file)
@@ -40,9 +40,11 @@ struct GNUNET_NETWORK_Handle
 {
 #ifndef MINGW
   int fd;
+
 #else
   SOCKET fd;
 #endif
+
 };
 
 
@@ -132,11 +134,16 @@ static int
 socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
 {
   int i;
-  i = fcntl (h->fd, F_GETFD);
+
+  i = fcntl (h->fd, F_GETFD);  
+  if (i < 0)
+    return GNUNET_SYSERR;
   if (i == (i | FD_CLOEXEC))
     return GNUNET_OK;
-  return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)
-    ? GNUNET_OK : GNUNET_SYSERR;
+  i |= FD_CLOEXEC;
+  if (fcntl (h->fd, F_SETFD, i) < 0)
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 #endif
 
@@ -189,6 +196,7 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
                               socklen_t * address_len)
 {
   struct GNUNET_NETWORK_Handle *ret;
+
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
   ret->fd = accept (desc->fd, address, address_len);
   if (ret->fd == INVALID_SOCKET)
@@ -226,7 +234,10 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
 #ifdef DARWIN
   socket_set_nosigpipe (ret);
 #endif
-  socket_set_nodelay (ret);
+#ifdef AF_UNIX
+  if (address->sa_family != AF_UNIX)
+#endif
+    socket_set_nodelay (ret);
   return ret;
 }
 
@@ -249,6 +260,17 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
 #ifdef MINGW
   if (SOCKET_ERROR == ret)
     SetErrnoFromWinsockError (WSAGetLastError ());
+#else
+#ifndef LINUX
+  if ( (ret == 0) && (address->sa_family == AF_UNIX))
+    {
+      const struct sockaddr_un *un = (const struct sockaddr_un*) address;
+      if (0 != unlink (un->sun_path))
+       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+                                 "unlink",
+                                 un->sun_path);
+    }
+#endif
 #endif
   return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;
 }
@@ -263,7 +285,6 @@ int
 GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
 {
   int ret;
-  int eno;
 
 #ifdef MINGW
   ret = closesocket (desc->fd);
@@ -271,13 +292,34 @@ GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Handle *desc)
 #else
   ret = close (desc->fd);
 #endif
-  eno = errno;
   GNUNET_free (desc);
-  errno = eno;
   return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
 }
 
 
+/**
+ * Box a native socket (and check that it is a socket).
+ *
+ * @param fd socket to box
+ * @return NULL on error (including not supported on target platform)
+ */
+struct GNUNET_NETWORK_Handle *
+GNUNET_NETWORK_socket_box_native (int fd)
+{
+#if MINGW
+  return NULL;
+#else
+  struct GNUNET_NETWORK_Handle *ret;
+
+  if (fcntl (fd, F_GETFD) < 0)
+    return NULL; /* invalid FD */
+  ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); 
+  ret->fd = fd;
+  return ret;
+#endif
+}
+
+
 /**
  * Connect a socket
  * @param desc socket
@@ -406,14 +448,12 @@ GNUNET_NETWORK_socket_recvfrom (const struct GNUNET_NETWORK_Handle * desc,
 #ifdef MSG_DONTWAIT
   flags |= MSG_DONTWAIT;
 
-#endif /*  */
+#endif
   ret = recvfrom (desc->fd, buffer, length, flags, src_addr, addrlen);
-
 #ifdef MINGW
   if (SOCKET_ERROR == ret)
     SetErrnoFromWinsockError (WSAGetLastError ());
-
-#endif /*  */
+#endif 
   return ret;
 }
 
@@ -434,15 +474,12 @@ GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,
 
 #ifdef MSG_DONTWAIT
   flags |= MSG_DONTWAIT;
-
-#endif /*  */
+#endif
   ret = recv (desc->fd, buffer, length, flags);
-
 #ifdef MINGW
   if (SOCKET_ERROR == ret)
     SetErrnoFromWinsockError (WSAGetLastError ());
-
-#endif /*  */
+#endif
   return ret;
 }
 
@@ -595,7 +632,11 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
 #ifdef DARWIN
   socket_set_nosigpipe (ret);
 #endif
-  if (type == SOCK_STREAM)
+  if ( (type == SOCK_STREAM) 
+#ifdef AF_UNIX
+       && (domain != AF_UNIX) 
+#endif
+       )
     socket_set_nodelay (ret);
   return ret;
 }
@@ -728,6 +769,38 @@ GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,
   to->nsds = nfds;
 }
 
+
+/**
+ * Set a native fd in a set
+ *
+ * @param to destination
+ * @param nfd native FD to set
+ */
+void GNUNET_NETWORK_fdset_set_native (struct GNUNET_NETWORK_FDSet *to,
+                                     int nfd)
+{
+  FD_SET (nfd, &to->sds);
+  to->nsds = GNUNET_MAX (nfd + 1, to->nsds);
+}
+
+
+/**
+ * Test native fd in a set
+ *
+ * @param to set to test, NULL for empty set
+ * @param nfd native FD to test, or -1 for none
+ * @return GNUNET_YES if FD is set in the set
+ */
+int 
+GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
+                                 int nfd)
+{
+  if ( (nfd == -1) || (to == NULL) )
+    return GNUNET_NO;
+  return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
+}
+
+
 /**
  * Add a file handle to the fd set
  * @param fds fd set
@@ -1103,19 +1176,15 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
   while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit));
 
   if (retcode != -1)
-
     {
       if (rfds)
-
         {
           GNUNET_NETWORK_fdset_zero (rfds);
           GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
           GNUNET_CONTAINER_slist_clear (rfds->handles);
           GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
-
         }
       if (wfds)
-
         {
           GNUNET_NETWORK_fdset_zero (wfds);
           GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
@@ -1123,7 +1192,6 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
           GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
         }
       if (efds)
-
         {
           GNUNET_NETWORK_fdset_zero (efds);
           GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);