fix
[oweals/gnunet.git] / src / util / disk.c
index 60288bc5d6960d6ed847cf283702bbd98651b061..65509166e1bac25da8bcb4928d0996f9d273669a 100644 (file)
@@ -248,7 +248,7 @@ GNUNET_DISK_file_size (const char *filename,
  */
 int
 GNUNET_DISK_file_get_identifiers (const char *filename,
-                                  uint32_t * dev, uint64_t * ino)
+                                  uint64_t * dev, uint64_t * ino)
 {
 #if LINUX
   struct stat sbuf;
@@ -256,10 +256,21 @@ GNUNET_DISK_file_get_identifiers (const char *filename,
 
   if ((0 == stat (filename, &sbuf)) && (0 == statvfs (filename, &fbuf)))
     {
-      *dev = (uint32_t) fbuf.f_fsid;
+      *dev = (uint64_t) fbuf.f_fsid;
       *ino = (uint64_t) sbuf.st_ino;
       return GNUNET_OK;
     }
+#elif SOMEBSD
+  struct stat sbuf;
+  struct statfs fbuf;
+
+  if ( (0 == stat (filename, &sbuf)) &&
+       (0 == statfs (filename, &fbuf) ) )
+    {
+      *dev = ((uint64_t) fbuf.f_fsid.val[0]) << 32 || ((uint64_t) fbuf.f_fsid.val[1]);
+      *ino = (uint64_t) sbuf.st_ino;
+      return GNUNET_OK;
+    }  
 #elif WINDOWS
   // FIXME NILS: test this
   struct GNUNET_DISK_FileHandle *fh;
@@ -1635,10 +1646,13 @@ GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)
  * Creates an interprocess channel
  *
  * @param blocking creates an asynchronous pipe if set to GNUNET_NO
+ * @param inherit_read inherit the parent processes stdin (only for windows)
+ * @param inherit_write inherit the parent processes stdout (only for windows)
+ *
  * @return handle to the new pipe, NULL on error
  */
 struct GNUNET_DISK_PipeHandle *
-GNUNET_DISK_pipe (int blocking)
+GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write)
 {
   struct GNUNET_DISK_PipeHandle *p;
   struct GNUNET_DISK_FileHandle *fds;
@@ -1663,30 +1677,32 @@ GNUNET_DISK_pipe (int blocking)
     }
   p->fd[0]->fd = fd[0];
   p->fd[1]->fd = fd[1];
+  ret = 0;
+  flags = fcntl (fd[0], F_GETFL);
+  flags |= FD_CLOEXEC;
+  if (!blocking)
+    flags |= O_NONBLOCK;
+  if (0 > fcntl (fd[0], F_SETFL, flags))
+    ret = -1;
+  flags = fcntl (fd[1], F_GETFL);
+  flags |= FD_CLOEXEC;
   if (!blocking)
+    flags |= O_NONBLOCK;
+  if (0 > fcntl (fd[1], F_SETFL, flags))
+    ret = -1;
+  if (ret == -1)
     {
-      flags = fcntl (fd[0], F_GETFL);
-      flags |= O_NONBLOCK;
-      ret = fcntl (fd[0], F_SETFL, flags);
-      if (ret != -1)
-        {
-          flags = fcntl (fd[1], F_GETFL);
-          flags |= O_NONBLOCK;
-          ret = fcntl (fd[1], F_SETFL, flags);
-        }
-      if (ret == -1)
-        {
-          eno = errno;
-          GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fcntl");
-          GNUNET_break (0 == close (p->fd[0]->fd));
-          GNUNET_break (0 == close (p->fd[1]->fd));
-          GNUNET_free (p);
-          errno = eno;
-          return NULL;
-        }
+      eno = errno;
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fcntl");
+      GNUNET_break (0 == close (p->fd[0]->fd));
+      GNUNET_break (0 == close (p->fd[1]->fd));
+      GNUNET_free (p);
+      errno = eno;
+      return NULL;    
     }
 #else
   BOOL ret;
+  HANDLE tmp_handle;
 
   ret = CreatePipe (&p->fd[0]->h, &p->fd[1]->h, NULL, 0);
   if (!ret)
@@ -1695,6 +1711,31 @@ GNUNET_DISK_pipe (int blocking)
       SetErrnoFromWinError (GetLastError ());
       return NULL;
     }
+  if (!DuplicateHandle (GetCurrentProcess (), p->fd[0]->h,
+               GetCurrentProcess (), &tmp_handle, 0, inherit_read == GNUNET_YES ? TRUE : FALSE,
+                       DUPLICATE_SAME_ACCESS))
+       {
+         SetErrnoFromWinError (GetLastError ());
+         CloseHandle (p->fd[0]->h);
+         CloseHandle (p->fd[1]->h);
+         GNUNET_free (p);
+         return NULL;
+       }
+       CloseHandle (p->fd[0]->h);
+       p->fd[0]->h = tmp_handle;
+
+       if (!DuplicateHandle (GetCurrentProcess (), p->fd[1]->h,
+                       GetCurrentProcess (), &tmp_handle, 0, inherit_write == GNUNET_YES ? TRUE : FALSE,
+                       DUPLICATE_SAME_ACCESS))
+       {
+         SetErrnoFromWinError (GetLastError ());
+         CloseHandle (p->fd[0]->h);
+         CloseHandle (p->fd[1]->h);
+         GNUNET_free (p);
+         return NULL;
+       }
+  CloseHandle (p->fd[1]->h);
+  p->fd[1]->h = tmp_handle;
   if (!blocking)
     {
       DWORD mode;