- fix 2699
[oweals/gnunet.git] / src / util / disk.c
index 4b9e5fd6566de7d49835f1d68285e3f12be2c8fd..f06311f88648561a4cb5e58b862c217e857a71c8 100644 (file)
@@ -1866,58 +1866,106 @@ GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h)
   return ret;
 }
 
-
+#ifdef WINDOWS
 /**
- * Get a handle from a native FD.
+ * Get a GNUnet file handle from a W32 handle.
  *
- * @param fd native file descriptor
- * @return file handle corresponding to the descriptor
+ * @param handle native handle
+ * @return GNUnet file handle corresponding to the W32 handle
  */
 struct GNUNET_DISK_FileHandle *
-GNUNET_DISK_get_handle_from_native (FILE *fd)
+GNUNET_DISK_get_handle_from_w32_handle (HANDLE osfh)
 {
   struct GNUNET_DISK_FileHandle *fh;
-  int fno;
-#if MINGW
-  intptr_t osfh;
-#endif
 
-  fno = fileno (fd);
-  if (-1 == fno)
-    return NULL;
+  DWORD dwret;
+  enum GNUNET_FILE_Type ftype;
 
-#if MINGW
-  osfh = _get_osfhandle (fno);
-  if (INVALID_HANDLE_VALUE == (HANDLE) osfh)
+  dwret = GetFileType (osfh);
+  switch (dwret)
+  {
+  case FILE_TYPE_DISK:
+    ftype = GNUNET_DISK_HANLDE_TYPE_FILE;
+    break;
+  case FILE_TYPE_PIPE:
+    ftype = GNUNET_DISK_HANLDE_TYPE_PIPE;
+    break;
+  default:
     return NULL;
+  }
+
+  fh = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
+
+  fh->h = osfh;
+  fh->type = ftype;
+  if (ftype == GNUNET_DISK_HANLDE_TYPE_PIPE)
+  {
+    /**
+     * Note that we can't make it overlapped if it isn't already.
+     * (ReOpenFile() is only available in 2003/Vista).
+     * The process that opened this file in the first place (usually a parent
+     * process, if this is stdin/stdout/stderr) must make it overlapped,
+     * otherwise we're screwed, as selecting on non-overlapped handle
+     * will block.
+     */
+    fh->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
+    fh->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
+    fh->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+    fh->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+  }
+
+  return fh;
+}
 #endif
 
+/**
+ * Get a handle from a native integer FD.
+ *
+ * @param fd native integer file descriptor
+ * @return file handle corresponding to the descriptor
+ */
+struct GNUNET_DISK_FileHandle *
+GNUNET_DISK_get_handle_from_int_fd (int fno)
+{
+  struct GNUNET_DISK_FileHandle *fh;
+
+#ifndef WINDOWS
   fh = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileHandle));
 
-#if MINGW
-  fh->h = (HANDLE) osfh;
-  /* Assume it to be a pipe. TODO: use some kind of detection
-   * function to figure out handle type.
-   * Note that we can't make it overlapped if it isn't already.
-   * (ReOpenFile() is only available in 2003/Vista).
-   * The process that opened this file in the first place (usually a parent
-   * process, if this is stdin/stdout/stderr) must make it overlapped,
-   * otherwise we're screwed, as selecting on non-overlapped handle
-   * will block.
-   */
-  fh->type = GNUNET_DISK_HANLDE_TYPE_PIPE;
-  fh->oOverlapRead = GNUNET_malloc (sizeof (OVERLAPPED));
-  fh->oOverlapWrite = GNUNET_malloc (sizeof (OVERLAPPED));
-  fh->oOverlapRead->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
-  fh->oOverlapWrite->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
-#else
   fh->fd = fno;
+#else
+  intptr_t osfh;
+
+  osfh = _get_osfhandle (fno);
+  if (INVALID_HANDLE_VALUE == (HANDLE) osfh)
+    return NULL;
+
+  fh = GNUNET_DISK_get_handle_from_w32_handle ((HANDLE) osfh);
 #endif
 
   return fh;
 }
 
 
+/**
+ * Get a handle from a native streaming FD.
+ *
+ * @param fd native streaming file descriptor
+ * @return file handle corresponding to the descriptor
+ */
+struct GNUNET_DISK_FileHandle *
+GNUNET_DISK_get_handle_from_native (FILE *fd)
+{
+  int fno;
+
+  fno = fileno (fd);
+  if (-1 == fno)
+    return NULL;
+
+  return GNUNET_DISK_get_handle_from_int_fd (fno);
+}
+
+
 /**
  * Construct full path to a file inside of the private
  * directory used by GNUnet.  Also creates the corresponding
@@ -2210,9 +2258,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
      * a waste, since only a single direction is actually used.
      * It's important to only allow a single instance, to ensure that
      * the pipe was not created earlier by some other process, even if
-     * the pid has been reused.  We avoid FILE_FLAG_FIRST_PIPE_INSTANCE
-     * because that is only available for Win2k SP2 and WinXP.  */
-    read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | dwReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1,   /* max instances */
+     * the pid has been reused.  */
+    read_pipe = CreateNamedPipeA (pipename, PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | dwReadMode, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 1,   /* max instances */
                                   psize,        /* output buffer size */
                                   psize,        /* input buffer size */
                                   NMPWAIT_USE_DEFAULT_WAIT, sa_ptr);