-LRN: fix pipe writing and progress write
authorChristian Grothoff <christian@grothoff.org>
Sat, 14 Jan 2012 18:31:25 +0000 (18:31 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sat, 14 Jan 2012 18:31:25 +0000 (18:31 +0000)
src/fs/fs_dirmetascan.c
src/util/disk.c

index 372579ccb64b3bef928f765ab882a066d7cb7d59..880710356d64c17f7711991f8cb0d7a9ec5f9666 100644 (file)
@@ -346,61 +346,61 @@ write_progress (struct AddDirContext *adc, const char *filename,
     char is_directory, enum GNUNET_DirScannerProgressUpdateReason reason)\r
 {\r
   size_t filename_len;\r
-  size_t wr;\r
+  ssize_t wr;\r
   size_t total_write;\r
   if ((adc->do_stop || should_stop (adc)) && reason != GNUNET_DIR_SCANNER_ASKED_TO_STOP\r
       && reason != GNUNET_DIR_SCANNER_FINISHED)\r
     return 1;\r
-  total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
-      &reason, sizeof (reason));\r
-  while (wr > 0 && total_write < sizeof (reason))\r
+  total_write = 0;\r
+  wr = 1;\r
+  while ((wr > 0 || errno == EAGAIN) && total_write < sizeof (reason))\r
   {\r
-    total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
+    wr = GNUNET_DISK_file_write (adc->progress_write,\r
       &((char *)&reason)[total_write], sizeof (reason) - total_write);\r
     if (wr > 0)\r
       total_write += wr;\r
   }\r
-  if (sizeof (reason) != wr)\r
-    return 1;\r
+  if (sizeof (reason) != total_write)\r
+    return adc->do_stop = 1;\r
   if (filename)\r
     filename_len = strlen (filename) + 1;\r
   else\r
     filename_len = 0;\r
-  total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
-      &filename_len, sizeof (size_t));\r
-  while (wr > 0 && total_write < sizeof (size_t))\r
+  total_write = 0;\r
+  wr = 1;\r
+  while ((wr > 0 || errno == EAGAIN) && total_write < sizeof (size_t))\r
   {\r
-    total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
+    wr = GNUNET_DISK_file_write (adc->progress_write,\r
       &((char *)&filename_len)[total_write], sizeof (size_t) - total_write);\r
     if (wr > 0)\r
       total_write += wr;\r
   }\r
-  if (sizeof (size_t) != wr)\r
-    return 1;\r
+  if (sizeof (size_t) != total_write)\r
+    return adc->do_stop = 1;\r
   if (filename)\r
   {\r
-    total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
-        filename, filename_len);\r
-    while (wr > 0 && total_write < filename_len)\r
+    total_write = 0;\r
+    wr = 1;\r
+    while ((wr > 0 || errno == EAGAIN) && total_write < filename_len)\r
     {\r
-      total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
+      wr = GNUNET_DISK_file_write (adc->progress_write,\r
         &((char *)filename)[total_write], filename_len - total_write);\r
       if (wr > 0)\r
         total_write += wr;\r
     }\r
-    if (filename_len != wr)\r
-      return 1;\r
-    total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
-      &is_directory, sizeof (char));\r
-    while (wr > 0 && total_write < sizeof (char))\r
+    if (filename_len != total_write)\r
+      return adc->do_stop = 1;\r
+    total_write = 0;\r
+    wr = 1;\r
+    while ((wr > 0 || errno == EAGAIN) && total_write < sizeof (char))\r
     {\r
-      total_write = wr = GNUNET_DISK_file_write (adc->progress_write,\r
+      wr = GNUNET_DISK_file_write (adc->progress_write,\r
         &((char *)&is_directory)[total_write], sizeof (char) - total_write);\r
       if (wr > 0)\r
         total_write += wr;\r
     }\r
-    if (sizeof (char) != wr)\r
-      return 1;\r
+    if (sizeof (char) != total_write)\r
+      return adc->do_stop = 1;\r
   }\r
   return 0;\r
 }\r
index 8d1fe3c12f5eaa292df2f4dbff453a735d78542f..eb707fd62fdf8e08e5bd2d0a111a6231c477ab2a 100644 (file)
@@ -718,15 +718,27 @@ GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle * h, void *result,
   }
   else
   {
-    if (!ReadFile (h->h, result, len, NULL, h->oOverlapRead))
+#if DEBUG_PIPE
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to read\n");
+#endif
+    if (!ReadFile (h->h, result, len, &bytesRead, h->oOverlapRead))
     {
       if (GetLastError () != ERROR_IO_PENDING)
       {
+#if DEBUG_PIPE
+        LOG (GNUNET_ERROR_TYPE_DEBUG, "Error reading from pipe: %u\n", GetLastError ());
+#endif
         SetErrnoFromWinError (GetLastError ());
         return GNUNET_SYSERR;
       }
+#if DEBUG_PIPE
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
+#endif
+      GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE);
     }
-    GetOverlappedResult (h->h, h->oOverlapRead, &bytesRead, TRUE);
+#if DEBUG_PIPE
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Read %u bytes\n", bytesRead);
+#endif
   }
   return bytesRead;
 #else
@@ -790,23 +802,67 @@ GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle * h,
   else
   {
 #if DEBUG_PIPE
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write\n");
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "It is a pipe trying to write %u bytes\n", n);
 #endif
-    if (!WriteFile (h->h, buffer, n, NULL, h->oOverlapWrite))
+    if (!WriteFile (h->h, buffer, n, &bytesWritten, h->oOverlapWrite))
     {
       if (GetLastError () != ERROR_IO_PENDING)
       {
         SetErrnoFromWinError (GetLastError ());
 #if DEBUG_PIPE
-        LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe\n");
+        LOG (GNUNET_ERROR_TYPE_DEBUG, "Error writing to pipe: %u\n",
+            GetLastError ());
+#endif
+        return GNUNET_SYSERR;
+      }
+#if DEBUG_PIPE
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
+#endif
+      if (!GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE))
+      {
+        SetErrnoFromWinError (GetLastError ());
+#if DEBUG_PIPE
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+            "Error getting overlapped result while writing to pipe: %u\n",
+            GetLastError ());
+#endif
+        return GNUNET_SYSERR;
+      }
+    }
+    else
+    {
+      DWORD ovr;
+      if (!GetOverlappedResult (h->h, h->oOverlapWrite, &ovr, TRUE))
+      {
+#if DEBUG_PIPE
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+            "Error getting control overlapped result while writing to pipe: %u\n",
+            GetLastError ());
+#endif
+      }
+      else
+      {
+#if DEBUG_PIPE
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+            "Wrote %u bytes (ovr says %u), picking the greatest\n",
+            bytesWritten, ovr);
+#endif
+      }
+    }
+    if (bytesWritten == 0)
+    {
+      if (n > 0)
+      {
+#if DEBUG_PIPE
+        LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes, returning -1 with EAGAIN\n", bytesWritten);
 #endif
+        errno = EAGAIN;
         return GNUNET_SYSERR;
       }
     }
 #if DEBUG_PIPE
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Will get overlapped result\n");
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Wrote %u bytes\n", bytesWritten);
 #endif
-    GetOverlappedResult (h->h, h->oOverlapWrite, &bytesWritten, TRUE);
   }
   return bytesWritten;
 #else