named pipes
authorNils Durner <durner@gnunet.org>
Mon, 22 Nov 2010 20:15:29 +0000 (20:15 +0000)
committerNils Durner <durner@gnunet.org>
Mon, 22 Nov 2010 20:15:29 +0000 (20:15 +0000)
src/include/gnunet_disk_lib.h
src/util/disk.c
src/util/disk.h
src/util/network.c

index 6eb666049a3d60f0a6a76ee14e5a8cfd5c983919..a59d10ed000148ffd82d9eba33e41f14e93bb74f 100644 (file)
@@ -642,6 +642,23 @@ int GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h);
  */
 int GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h);
 
+/**
+ * Creates a named pipe/FIFO
+ * @param fn name of the named pipe
+ * @param flags open flags
+ * @param perm access permissions
+ * @return pipe handle on success, NULL on error
+ */
+struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_open (const char *fn,
+    enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm);
+
+/**
+ * Closes a named pipe/FIFO
+ * @param pipe named pipe
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe);
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif
index 307c4535bf2478576c257d7234816ec374bf0873..c25782a42113f1c4d2e265e88bbb542355270e19 100644 (file)
@@ -101,6 +101,34 @@ struct GetFileSizeData
 };
 
 
+int translate_unix_perms(enum GNUNET_DISK_AccessPermissions perm)
+{
+  int mode;
+
+  mode = 0;
+  if (perm & GNUNET_DISK_PERM_USER_READ)
+    mode |= S_IRUSR;
+  if (perm & GNUNET_DISK_PERM_USER_WRITE)
+    mode |= S_IWUSR;
+  if (perm & GNUNET_DISK_PERM_USER_EXEC)
+    mode |= S_IXUSR;
+  if (perm & GNUNET_DISK_PERM_GROUP_READ)
+    mode |= S_IRGRP;
+  if (perm & GNUNET_DISK_PERM_GROUP_WRITE)
+    mode |= S_IWGRP;
+  if (perm & GNUNET_DISK_PERM_GROUP_EXEC)
+    mode |= S_IXGRP;
+  if (perm & GNUNET_DISK_PERM_OTHER_READ)
+    mode |= S_IROTH;
+  if (perm & GNUNET_DISK_PERM_OTHER_WRITE)
+    mode |= S_IWOTH;
+  if (perm & GNUNET_DISK_PERM_OTHER_EXEC)
+    mode |= S_IXOTH;
+
+  return mode;
+}
+
+
 /**
  * Iterate over all files in the given directory and 
  * accumulate their size.
@@ -1259,24 +1287,7 @@ GNUNET_DISK_file_open (const char *fn,
     {
       (void) GNUNET_DISK_directory_create_for_file (expfn);
       oflags |= O_CREAT;
-      if (perm & GNUNET_DISK_PERM_USER_READ)
-        mode |= S_IRUSR;
-      if (perm & GNUNET_DISK_PERM_USER_WRITE)
-        mode |= S_IWUSR;
-      if (perm & GNUNET_DISK_PERM_USER_EXEC)
-        mode |= S_IXUSR;
-      if (perm & GNUNET_DISK_PERM_GROUP_READ)
-        mode |= S_IRGRP;
-      if (perm & GNUNET_DISK_PERM_GROUP_WRITE)
-        mode |= S_IWGRP;
-      if (perm & GNUNET_DISK_PERM_GROUP_EXEC)
-        mode |= S_IXGRP;
-      if (perm & GNUNET_DISK_PERM_OTHER_READ)
-        mode |= S_IROTH;
-      if (perm & GNUNET_DISK_PERM_OTHER_WRITE)
-        mode |= S_IWOTH;
-      if (perm & GNUNET_DISK_PERM_OTHER_EXEC)
-        mode |= S_IXOTH;
+      mode = translate_unix_perms(perm);
     }
 
   fd = open (expfn, oflags | O_LARGEFILE, mode);
@@ -1347,6 +1358,7 @@ GNUNET_DISK_file_open (const char *fn,
   ret = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
 #ifdef MINGW
   ret->h = h;
+  ret->type = GNUNET_DISK_FILE;
 #else
   ret->fd = fd;
 #endif
@@ -1748,6 +1760,8 @@ GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
       SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL);
       /* this always fails on Windows 95, so we don't care about error handling */
     }
+  p->fd[0]->type = GNUNET_PIPE;
+  p->fd[1]->type = GNUNET_PIPE;
 #endif
   return p;
 }
@@ -1862,6 +1876,89 @@ GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
 }
 
 
+/**
+ * Creates a named pipe/FIFO
+ * @param fn name of the named pipe
+ * @param flags open flags
+ * @param perm access permissions
+ * @return pipe handle on success, NULL on error
+ */
+struct GNUNET_DISK_FileHandle *
+GNUNET_DISK_npipe_open (const char *fn,
+                       enum GNUNET_DISK_OpenFlags flags,
+                       enum GNUNET_DISK_AccessPermissions perm)
+{
+  struct GNUNET_DISK_FileHandle *ret;
+
+#ifdef MINGW
+  HANDLE h;
+  DWORD openMode;
+  char *name;
+
+  openMode = 0;
+  if (flags & GNUNET_DISK_OPEN_READWRITE)
+    openMode = PIPE_ACCESS_DUPLEX;
+  else if (flags & GNUNET_DISK_OPEN_READ)
+    openMode = PIPE_ACCESS_INBOUND;
+  else if (flags & GNUNET_DISK_OPEN_WRITE)
+    openMode = PIPE_ACCESS_OUTBOUND;
+
+  if (flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
+    openMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
+
+  GNUNET_asprintf(&name, "\\\\.\\pipe\\pipename\\%s", fn);
+  h = CreateNamedPipe (fn, openMode | FILE_FLAG_OVERLAPPED,
+      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 2, 1, 1, 0, NULL);
+  GNUNET_free(name);
+  if (h == NULL)
+    {
+      SetErrnoFromWinError(GetLastError());
+      return NULL;
+    }
+
+  ret = GNUNET_malloc(sizeof(*ret));
+  ret->h = h;
+
+  return ret;
+#else
+  int fd;
+
+  if (mkfifo(fn, translate_unix_perms(perm)) == -1)
+    {
+      if (errno == EEXISTS && flags & GNUNET_DISK_OPEN_FAILIFEXISTS)
+        return NULL;
+    }
+
+  flags ~= GNUNET_DISK_OPEN_FAILIFEXISTS;
+  return GNUNET_DISK_file_open(fn, flags, perm);
+#endif
+}
+
+/**
+ * Closes a named pipe/FIFO
+ * @param pipe named pipe
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe)
+{
+#ifndef MINGW
+  return close(pipe->fd) == 0 ? GNUNET_OK : GNUNET_SYSERR;
+#else
+  BOOL ret;
+
+  ret = CloseHandle(pipe->h);
+  if (!ret)
+    {
+      SetErrnoFromWinError(GetLastError());
+      return GNUNET_SYSERR;
+    }
+  else
+    return GNUNET_OK;
+#endif
+}
+
+
 /**
  * Get the handle to a particular pipe end
  *
index 3d52b9ec8390dda8463b414ae93420ed1aa3425c..093d7049266346b2f947a2c4a392bf9f3c260946 100644 (file)
@@ -40,8 +40,13 @@ struct GNUNET_DISK_FileHandle
    * File handle under W32.\r
    */ \r
   HANDLE h;
-  \r
-#else                           /* \r */
+\r
+  /**\r
+   * Type
+   */\r
+  enum {GNUNET_DISK_FILE, GNUNET_PIPE} type;\r
+#else\r
+
   /**\r
    * File handle on other OSes.\r
    */ \r
index 58d67ed19fd36ba8933e4f666d30e91e47e5d419..452f2870619337805528d50d080e439ced1afd16 100644 (file)
@@ -1137,28 +1137,38 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
                GNUNET_CONTAINER_slist_next (i))
 
             {
-              HANDLE h;
+              struct GNUNET_DISK_FileHandle *fh;
               DWORD dwBytes;
-              h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);
-              if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))
+              fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL);
+              if (fh->type == GNUNET_PIPE)
                 {
-                  retcode = -1;
-                  SetErrnoFromWinError (GetLastError ());
+                  if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
+                    {
+                      retcode = -1;
+                      SetErrnoFromWinError (GetLastError ());
 
-#if DEBUG_NETWORK
-                  GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
-                                       "PeekNamedPipe");
+    #if DEBUG_NETWORK
+                      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                                           "PeekNamedPipe");
 
-#endif
-                  goto select_loop_end;
-                }
-              else if (dwBytes)
+    #endif
+                      goto select_loop_end;
+                    }
+                  else if (dwBytes)
 
+                    {
+                      GNUNET_CONTAINER_slist_add (handles_read,
+                                                  GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
+                                                  fh, sizeof (struct GNUNET_DISK_FileHandle));
+                      retcode++;
+                    }
+                }
+              else
                 {
+                  /* Should we wait for more bytes to read here (in case of previous EOF)? */
                   GNUNET_CONTAINER_slist_add (handles_read,
                                               GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
-                                              &h, sizeof (HANDLE));
-                  retcode++;
+                                              fh, sizeof (struct GNUNET_DISK_FileHandle));
                 }
             }
           GNUNET_CONTAINER_slist_iter_destroy (i);
@@ -1174,16 +1184,20 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
                GNUNET_CONTAINER_slist_next (i))
 
             {
-              HANDLE h;
+              struct GNUNET_DISK_FileHandle *fh;
               DWORD dwBytes;
-              h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);
-              if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))
 
+              fh = (struct GNUNET_DISK_FileHandle *) GNUNET_CONTAINER_slist_get (i, NULL);
+              if (fh->type == GNUNET_PIPE)
                 {
-                  GNUNET_CONTAINER_slist_add (handles_except,
-                                              GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
-                                              &h, sizeof (HANDLE));
-                  retcode++;
+                  if (!PeekNamedPipe (fh->h, NULL, 0, NULL, &dwBytes, NULL))
+
+                    {
+                      GNUNET_CONTAINER_slist_add (handles_except,
+                                                  GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
+                                                  fh, sizeof (struct GNUNET_DISK_FileHandle));
+                      retcode++;
+                    }
                 }
             }
           GNUNET_CONTAINER_slist_iter_destroy (i);