fixing issue with gnunet-publish not closing files early enough when publishing direc...
authorChristian Grothoff <christian@grothoff.org>
Sat, 24 Mar 2012 19:13:25 +0000 (19:13 +0000)
committerChristian Grothoff <christian@grothoff.org>
Sat, 24 Mar 2012 19:13:25 +0000 (19:13 +0000)
src/fs/fs_api.c
src/fs/fs_publish.c
src/fs/fs_tree.c

index 42bfaed3cc4f21aadff188572062d3484cb84d8e..e2a3b6019ffe362d585a5c58774af86798072748 100644 (file)
@@ -291,7 +291,11 @@ struct FileInfo
  * @param cls closure (points to the file information)
  * @param offset offset to read from; it is possible
  *            that the caller might need to go backwards
- *            a bit at times
+ *            a bit at times; set to UINT64_MAX to tell
+ *            the reader that we won't be reading for a while
+ *            (used to close the file descriptor but NOT fully
+ *             clean up the reader's state); in this case,
+ *            a value of '0' for max should be ignored
  * @param max maximum number of bytes that should be
  *            copied to buf; readers are not allowed
  *            to provide less data unless there is an error;
@@ -308,20 +312,29 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf,
   struct FileInfo *fi = cls;
   ssize_t ret;
 
-  if (max == 0)
+  if (UINT64_MAX == offset)
+  {
+    if (NULL != fi->fd)
+    {
+      GNUNET_DISK_file_close (fi->fd);
+      fi->fd = NULL;
+    }
+    return 0;
+  }
+  if (0 == max)
   {
-    if (fi->fd != NULL)
+    if (NULL != fi->fd)
       GNUNET_DISK_file_close (fi->fd);
     GNUNET_free (fi->filename);
     GNUNET_free (fi);
     return 0;
   }
-  if (fi->fd == NULL)
+  if (NULL == fi->fd)
   {
     fi->fd =
         GNUNET_DISK_file_open (fi->filename, GNUNET_DISK_OPEN_READ,
                                GNUNET_DISK_PERM_NONE);
-    if (fi->fd == NULL)
+    if (NULL == fi->fd)
     {
       GNUNET_asprintf (emsg, _("Could not open file `%s': %s"), fi->filename,
                        STRERROR (errno));
@@ -330,7 +343,7 @@ GNUNET_FS_data_reader_file_ (void *cls, uint64_t offset, size_t max, void *buf,
   }
   GNUNET_DISK_file_seek (fi->fd, offset, GNUNET_DISK_SEEK_SET);
   ret = GNUNET_DISK_file_read (fi->fd, buf, max);
-  if (ret == -1)
+  if (-1 == ret)
   {
     GNUNET_asprintf (emsg, _("Could not read file `%s': %s"), fi->filename,
                      STRERROR (errno));
@@ -374,7 +387,11 @@ GNUNET_FS_make_file_reader_context_ (const char *filename)
  * @param cls closure (points to the buffer)
  * @param offset offset to read from; it is possible
  *            that the caller might need to go backwards
- *            a bit at times
+ *            a bit at times; set to UINT64_MAX to tell
+ *            the reader that we won't be reading for a while
+ *            (used to close the file descriptor but NOT fully
+ *             clean up the reader's state); in this case,
+ *            a value of '0' for max should be ignored
  * @param max maximum number of bytes that should be
  *            copied to buf; readers are not allowed
  *            to provide less data unless there is an error;
@@ -390,6 +407,8 @@ GNUNET_FS_data_reader_copy_ (void *cls, uint64_t offset, size_t max, void *buf,
 {
   char *data = cls;
 
+  if (UINT64_MAX == offset)
+    return 0;
   if (max == 0)
   {
     GNUNET_free_non_null (data);
index b3f6415c8e3c5fdf392183fe4ee92a37b0d8c008..e0a6f046a3837d3f04e17f11f25a2eebec6ebfff 100644 (file)
@@ -355,6 +355,8 @@ block_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
   }
   else
   {
+    if (UINT64_MAX == offset)
+      return p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL);
     pt_size = GNUNET_MIN (max, p->data.file.file_size - offset);
     if (pt_size == 0)
       return 0;                 /* calling reader with pt_size==0
index 2bdf8a062fddd9a23130d4369b08aa008da0fa45..30cdded677d6e06a84bda4867ee53f43fa6bc6c8 100644 (file)
@@ -429,6 +429,7 @@ void
 GNUNET_FS_tree_encoder_finish (struct GNUNET_FS_TreeEncoder *te,
                                struct GNUNET_FS_Uri **uri, char **emsg)
 {
+  (void) te->reader (te->cls, UINT64_MAX, 0, 0, NULL);
   GNUNET_assert (GNUNET_NO == te->in_next);
   if (uri != NULL)
     *uri = te->uri;