From e8a3316b8b361bff25b1fd09509e57abef1ef549 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 24 Mar 2012 19:13:25 +0000 Subject: [PATCH] fixing issue with gnunet-publish not closing files early enough when publishing directories with more than FD_MAX files (#2239) --- src/fs/fs_api.c | 33 ++++++++++++++++++++++++++------- src/fs/fs_publish.c | 2 ++ src/fs/fs_tree.c | 1 + 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/fs/fs_api.c b/src/fs/fs_api.c index 42bfaed3c..e2a3b6019 100644 --- a/src/fs/fs_api.c +++ b/src/fs/fs_api.c @@ -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); diff --git a/src/fs/fs_publish.c b/src/fs/fs_publish.c index b3f6415c8..e0a6f046a 100644 --- a/src/fs/fs_publish.c +++ b/src/fs/fs_publish.c @@ -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 diff --git a/src/fs/fs_tree.c b/src/fs/fs_tree.c index 2bdf8a062..30cdded67 100644 --- a/src/fs/fs_tree.c +++ b/src/fs/fs_tree.c @@ -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; -- 2.25.1