gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r19133 - in gnunet/src: include util


From: gnunet
Subject: [GNUnet-SVN] r19133 - in gnunet/src: include util
Date: Sat, 14 Jan 2012 16:20:06 +0100

Author: grothoff
Date: 2012-01-14 16:20:06 +0100 (Sat, 14 Jan 2012)
New Revision: 19133

Modified:
   gnunet/src/include/gnunet_disk_lib.h
   gnunet/src/util/disk.c
Log:
LRN: new pipe creation function GNUNET_DISK_pipe_from_fd   to wrap existing 
file descriptor pair

Modified: gnunet/src/include/gnunet_disk_lib.h
===================================================================
--- gnunet/src/include/gnunet_disk_lib.h        2012-01-14 15:17:48 UTC (rev 
19132)
+++ gnunet/src/include/gnunet_disk_lib.h        2012-01-14 15:20:06 UTC (rev 
19133)
@@ -399,6 +399,18 @@
 
 
 /**
+ * Creates a pipe object from a couple of file descriptors.
+ * Useful for wrapping existing pipe FDs.
+ *
+ * @param blocking creates an asynchronous pipe if set to GNUNET_NO
+ * @param fd an array of two fd values. One of them may be -1 for read-only or 
write-only pipes
+ *
+ * @return handle to the new pipe, NULL on error
+ */
+struct GNUNET_DISK_PipeHandle *
+GNUNET_DISK_pipe_from_fd (int blocking, int fd[2]);
+
+/**
  * Closes an interprocess channel
  * @param p pipe
  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise

Modified: gnunet/src/util/disk.c
===================================================================
--- gnunet/src/util/disk.c      2012-01-14 15:17:48 UTC (rev 19132)
+++ gnunet/src/util/disk.c      2012-01-14 15:20:06 UTC (rev 19133)
@@ -2037,7 +2037,117 @@
   return p;
 }
 
+/**
+ * Creates a pipe object from a couple of file descriptors.
+ * Useful for wrapping existing pipe FDs.
+ *
+ * @param blocking creates an asynchronous pipe if set to GNUNET_NO
+ * @param fd an array of two fd values. One of them may be -1 for read-only or 
write-only pipes
+ *
+ * @return handle to the new pipe, NULL on error
+ */
+struct GNUNET_DISK_PipeHandle *
+GNUNET_DISK_pipe_from_fd (int blocking, int fd[2])
+{
+  struct GNUNET_DISK_PipeHandle *p;
+  struct GNUNET_DISK_FileHandle *fds;
 
+  p = GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle) +
+                     2 * sizeof (struct GNUNET_DISK_FileHandle));
+  fds = (struct GNUNET_DISK_FileHandle *) &p[1];
+  p->fd[0] = &fds[0];
+  p->fd[1] = &fds[1];
+#ifndef MINGW
+  int ret;
+  int flags;
+  int eno;
+
+  p->fd[0]->fd = fd[0];
+  p->fd[1]->fd = fd[1];
+  ret = 0;
+  if (fd[0] >= 0)
+  {
+    flags = fcntl (fd[0], F_GETFL);
+    if (!blocking)
+      flags |= O_NONBLOCK;
+    if (0 > fcntl (fd[0], F_SETFL, flags))
+      ret = -1;
+    flags = fcntl (fd[0], F_GETFD);
+    flags |= FD_CLOEXEC;
+    if (0 > fcntl (fd[0], F_SETFD, flags))
+      ret = -1;
+  }
+
+  if (fd[1] >= 0)
+  {
+    flags = fcntl (fd[1], F_GETFL);
+    if (!blocking)
+      flags |= O_NONBLOCK;
+    if (0 > fcntl (fd[1], F_SETFL, flags))
+      ret = -1;
+    flags = fcntl (fd[1], F_GETFD);
+    flags |= FD_CLOEXEC;
+    if (0 > fcntl (fd[1], F_SETFD, flags))
+      ret = -1;
+  }
+  if (ret == -1)
+  {
+    eno = errno;
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fcntl");
+    if (p->fd[0]->fd >= 0)
+      GNUNET_break (0 == close (p->fd[0]->fd));
+    if (p->fd[1]->fd >= 0)
+      GNUNET_break (0 == close (p->fd[1]->fd));
+    GNUNET_free (p);
+    errno = eno;
+    return NULL;
+  }
+#else
+  BOOL ret;
+
+  if (fd[0] >= 0)
+    p->fd[0]->h = _get_osfhandle (fd[0]);
+  else
+    p->fd[0]->h = INVALID_HANDLE_VALUE;
+  if (fd[1] >= 0)
+    p->fd[1]->h = _get_osfhandle (fd[1]);
+  else
+    p->fd[1]->h = INVALID_HANDLE_VALUE;
+
+  if (!blocking)
+  {
+    DWORD mode;
+
+    mode = PIPE_NOWAIT;
+    if (p->fd[0]->h != INVALID_HANDLE_VALUE)
+      SetNamedPipeHandleState (p->fd[0]->h, &mode, NULL, NULL);
+    if (p->fd[1]->h != INVALID_HANDLE_VALUE)
+      SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL);
+    /* this always fails on Windows 95, so we don't care about error handling 
*/
+  }
+
+  if (p->fd[0]->h != INVALID_HANDLE_VALUE)
+  {
+    p->fd[0]->type = GNUNET_PIPE;
+    p->fd[0]->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
+    p->fd[0]->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
+    p->fd[0]->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+    p->fd[0]->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+  }
+
+  if (p->fd[1]->h != INVALID_HANDLE_VALUE)
+  {
+    p->fd[1]->type = GNUNET_PIPE;
+    p->fd[1]->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
+    p->fd[1]->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
+    p->fd[1]->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+    p->fd[1]->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+  }
+#endif
+  return p;
+}
+
+
 /**
  * Closes an interprocess channel
  *
@@ -2055,21 +2165,31 @@
 #ifdef MINGW
   if (end == GNUNET_DISK_PIPE_END_READ)
   {
-    if (!CloseHandle (p->fd[0]->h))
+    if (p->fd[0]->h != INVALID_HANDLE_VALUE)
     {
-      SetErrnoFromWinError (GetLastError ());
-      ret = GNUNET_SYSERR;
+      if (!CloseHandle (p->fd[0]->h))
+      {
+        SetErrnoFromWinError (GetLastError ());
+        ret = GNUNET_SYSERR;
+      }
+      GNUNET_free (p->fd[0]->oOverlapRead);
+      GNUNET_free (p->fd[0]->oOverlapWrite);
+      p->fd[0]->h = INVALID_HANDLE_VALUE;
     }
-    p->fd[0]->h = INVALID_HANDLE_VALUE;
   }
   else if (end == GNUNET_DISK_PIPE_END_WRITE)
   {
-    if (!CloseHandle (p->fd[1]->h))
+    if (p->fd[0]->h != INVALID_HANDLE_VALUE)
     {
-      SetErrnoFromWinError (GetLastError ());
-      ret = GNUNET_SYSERR;
+      if (!CloseHandle (p->fd[1]->h))
+      {
+        SetErrnoFromWinError (GetLastError ());
+        ret = GNUNET_SYSERR;
+      }
+      GNUNET_free (p->fd[1]->oOverlapRead);
+      GNUNET_free (p->fd[1]->oOverlapWrite);
+      p->fd[1]->h = INVALID_HANDLE_VALUE;
     }
-    p->fd[1]->h = INVALID_HANDLE_VALUE;
   }
   save = errno;
 #else
@@ -2110,15 +2230,25 @@
   int save;
 
 #ifdef MINGW
-  if (!CloseHandle (p->fd[0]->h))
+  if (p->fd[0]->h != INVALID_HANDLE_VALUE)
   {
-    SetErrnoFromWinError (GetLastError ());
-    ret = GNUNET_SYSERR;
+    if (!CloseHandle (p->fd[0]->h))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      ret = GNUNET_SYSERR;
+    }
+    GNUNET_free (p->fd[0]->oOverlapRead);
+    GNUNET_free (p->fd[0]->oOverlapWrite);
   }
-  if (!CloseHandle (p->fd[1]->h))
+  if (p->fd[1]->h != INVALID_HANDLE_VALUE)
   {
-    SetErrnoFromWinError (GetLastError ());
-    ret = GNUNET_SYSERR;
+    if (!CloseHandle (p->fd[1]->h))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      ret = GNUNET_SYSERR;
+    }
+    GNUNET_free (p->fd[1]->oOverlapRead);
+    GNUNET_free (p->fd[1]->oOverlapWrite);
   }
   save = errno;
 #else




reply via email to

[Prev in Thread] Current Thread [Next in Thread]