summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2002-09-10 21:10:49 +0000
committerJeffrey Stedfast <fejj@src.gnome.org>2002-09-10 21:10:49 +0000
commitde283a8980d92db44d667631026c16a420bfd56e (patch)
tree35a59eb3723bcc760175af350df4b84033ea3be2
parentfc16c458b0218afab9231eace5f026e6312c8072 (diff)
downloadevolution-data-server-de283a8980d92db44d667631026c16a420bfd56e.tar.gz
Do proper error checking and return -1 on fail.
2002-09-10 Jeffrey Stedfast <fejj@ximian.com> * camel-folder-summary.c (perform_content_info_save): Do proper error checking and return -1 on fail. (camel_folder_summary_save): Check the return of perform_content_info_save and a few other output calls within the message_info_save loop. If any of them fail, save errno, close the file, and return -1. If we finish the loop without fail, fflush the stream and then fsync (fflush only flushes user-space buffers, you still need to fsync afterward to flush the data to disk). If either fail, treat it as an exception by saving errno, closing the stream, and returning -1. I suspect that this also fixes bug #30150 because the old code would fclose if fflush or fclose failed in the check after the loop (man fclose(3) states that any further calls using the stream (even another call to fclose) will have undefined behaviour no matter what the first fclose call returned). * providers/local/camel-local-summary.c (camel_local_summary_init): Don't malloc a private struct of 0 size.
-rw-r--r--camel/ChangeLog20
-rw-r--r--camel/camel-folder-summary.c71
-rw-r--r--camel/providers/local/camel-local-summary.c8
-rw-r--r--camel/providers/local/camel-local-summary.h6
4 files changed, 63 insertions, 42 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index cf810f855..198d07193 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,25 @@
2002-09-10 Jeffrey Stedfast <fejj@ximian.com>
+ * camel-folder-summary.c (perform_content_info_save): Do proper
+ error checking and return -1 on fail.
+ (camel_folder_summary_save): Check the return of
+ perform_content_info_save and a few other output calls within the
+ message_info_save loop. If any of them fail, save errno, close the
+ file, and return -1. If we finish the loop without fail, fflush
+ the stream and then fsync (fflush only flushes user-space buffers,
+ you still need to fsync afterward to flush the data to disk). If
+ either fail, treat it as an exception by saving errno, closing the
+ stream, and returning -1. I suspect that this also fixes bug
+ #30150 because the old code would fclose if fflush or fclose
+ failed in the check after the loop (man fclose(3) states that any
+ further calls using the stream (even another call to fclose) will
+ have undefined behaviour no matter what the first fclose call
+ returned).
+
+ * providers/local/camel-local-summary.c
+ (camel_local_summary_init): Don't malloc a private struct of 0
+ size.
+
* providers/imap/camel-imap-folder.c
(camel_imap_folder_fetch_data): Clear the exception even if we
failed to get the message (part) from the imap-message-cache if we
diff --git a/camel/camel-folder-summary.c b/camel/camel-folder-summary.c
index ebef730c7..3ec6c9310 100644
--- a/camel/camel-folder-summary.c
+++ b/camel/camel-folder-summary.c
@@ -602,13 +602,19 @@ perform_content_info_save(CamelFolderSummary *s, FILE *out, CamelMessageContentI
{
CamelMessageContentInfo *part;
- ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->content_info_save(s, out, ci);
- camel_file_util_encode_uint32(out, my_list_size((struct _node **)&ci->childs));
+ if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->content_info_save (s, out, ci) == -1)
+ return -1;
+
+ if (camel_file_util_encode_uint32 (out, my_list_size ((struct _node **)&ci->childs)) == -1)
+ return -1;
+
part = ci->childs;
while (part) {
- perform_content_info_save(s, out, part);
+ if (perform_content_info_save (s, out, part) == -1)
+ return -1;
part = part->next;
}
+
return 0;
}
@@ -625,8 +631,7 @@ int
camel_folder_summary_save(CamelFolderSummary *s)
{
FILE *out;
- int fd;
- int i;
+ int fd, i;
guint32 count;
CamelMessageInfo *mi;
char *path;
@@ -641,7 +646,7 @@ camel_folder_summary_save(CamelFolderSummary *s)
if (fd == -1)
return -1;
out = fdopen(fd, "w");
- if ( out == NULL ) {
+ if (out == NULL) {
i = errno;
unlink(path);
close(fd);
@@ -653,46 +658,52 @@ camel_folder_summary_save(CamelFolderSummary *s)
CAMEL_SUMMARY_LOCK(s, io_lock);
- if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1) {
- i = errno;
- fclose(out);
- CAMEL_SUMMARY_UNLOCK(s, io_lock);
- unlink(path);
- errno = i;
- return -1;
- }
-
+ if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_save(s, out) == -1)
+ goto exception;
+
/* now write out each message ... */
/* we check ferorr when done for i/o errors */
-
count = s->messages->len;
- for (i=0;i<count;i++) {
+ for (i = 0; i < count; i++) {
mi = s->messages->pdata[i];
- ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->message_info_save(s, out, mi);
-
+ if (((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS (s)))->message_info_save (s, out, mi) == -1)
+ goto exception;
+
if (s->build_content) {
- perform_content_info_save(s, out, mi->content);
+ if (perform_content_info_save (s, out, mi->content) == -1)
+ goto exception;
}
}
-
+
+ if (fflush (out) != 0 || fsync (fileno (out)) == -1)
+ goto exception;
+
+ fclose (out);
+
CAMEL_SUMMARY_UNLOCK(s, io_lock);
-
- if (ferror(out) != 0 || fclose(out) != 0) {
- i = errno;
- unlink(path);
- errno = i;
- return -1;
- }
-
+
if (rename(path, s->summary_path) == -1) {
i = errno;
unlink(path);
errno = i;
return -1;
}
-
+
s->flags &= ~CAMEL_SUMMARY_DIRTY;
return 0;
+
+ exception:
+
+ i = errno;
+
+ fclose (out);
+
+ CAMEL_SUMMARY_UNLOCK(s, io_lock);
+
+ unlink (path);
+ errno = i;
+
+ return -1;
}
/**
diff --git a/camel/providers/local/camel-local-summary.c b/camel/providers/local/camel-local-summary.c
index e1007223a..18c0b80ce 100644
--- a/camel/providers/local/camel-local-summary.c
+++ b/camel/providers/local/camel-local-summary.c
@@ -41,11 +41,6 @@
#define CAMEL_LOCAL_SUMMARY_VERSION (0x200)
-struct _CamelLocalSummaryPrivate {
-};
-
-#define _PRIVATE(o) (((CamelLocalSummary *)(o))->priv)
-
static CamelMessageInfo * message_info_new (CamelFolderSummary *, struct _header_raw *);
static int local_summary_decode_x_evolution(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *mi);
@@ -100,11 +95,8 @@ camel_local_summary_class_init(CamelLocalSummaryClass *klass)
static void
camel_local_summary_init(CamelLocalSummary *obj)
{
- struct _CamelLocalSummaryPrivate *p;
struct _CamelFolderSummary *s = (CamelFolderSummary *)obj;
- p = _PRIVATE(obj) = g_malloc0(sizeof(*p));
-
/* subclasses need to set the right instance data sizes */
s->message_info_size = sizeof(CamelMessageInfo);
s->content_info_size = sizeof(CamelMessageContentInfo);
diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h
index fafa99216..0995331ab 100644
--- a/camel/providers/local/camel-local-summary.h
+++ b/camel/providers/local/camel-local-summary.h
@@ -42,11 +42,9 @@ enum {
struct _CamelLocalSummary {
CamelFolderSummary parent;
-
- struct _CamelLocalSummaryPrivate *priv;
-
+
char *folder_path; /* name of matching folder */
-
+
CamelIndex *index;
unsigned int index_force:1; /* do we force index during creation? */
unsigned int check_force:1; /* does a check force a full check? */