X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=lib%2Fdatabase.cc;h=1e66599292855138a91db954d21affc11a7ac7ad;hb=5fddc07dc31481453c1af186bf7da241c00cdbf1;hp=8103bd96ef88c0e30f256753145f17f5583118a2;hpb=442d405ad301bd0bc9dc1d385c21f943ba743308;p=notmuch diff --git a/lib/database.cc b/lib/database.cc index 8103bd96..1e665992 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -556,8 +556,9 @@ notmuch_database_create (const char *path) goto DONE; } - notmuch = notmuch_database_open (path, - NOTMUCH_DATABASE_MODE_READ_WRITE); + notmuch_database_open (path, + NOTMUCH_DATABASE_MODE_READ_WRITE, + ¬much); notmuch_database_upgrade (notmuch, NULL, NULL); DONE: @@ -578,20 +579,29 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch) return NOTMUCH_STATUS_SUCCESS; } -notmuch_database_t * +notmuch_status_t notmuch_database_open (const char *path, - notmuch_database_mode_t mode) + notmuch_database_mode_t mode, + notmuch_database_t **database) { + notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; + void *local = talloc_new (NULL); notmuch_database_t *notmuch = NULL; - char *notmuch_path = NULL, *xapian_path = NULL; + char *notmuch_path, *xapian_path; struct stat st; int err; unsigned int i, version; static int initialized = 0; - if (asprintf (¬much_path, "%s/%s", path, ".notmuch") == -1) { - notmuch_path = NULL; + if (path == NULL) { + fprintf (stderr, "Error: Cannot open a database for a NULL path.\n"); + status = NOTMUCH_STATUS_NULL_POINTER; + goto DONE; + } + + if (! (notmuch_path = talloc_asprintf (local, "%s/%s", path, ".notmuch"))) { fprintf (stderr, "Out of memory\n"); + status = NOTMUCH_STATUS_OUT_OF_MEMORY; goto DONE; } @@ -599,12 +609,13 @@ notmuch_database_open (const char *path, if (err) { fprintf (stderr, "Error opening database at %s: %s\n", notmuch_path, strerror (errno)); + status = NOTMUCH_STATUS_FILE_ERROR; goto DONE; } - if (asprintf (&xapian_path, "%s/%s", notmuch_path, "xapian") == -1) { - xapian_path = NULL; + if (! (xapian_path = talloc_asprintf (local, "%s/%s", notmuch_path, "xapian"))) { fprintf (stderr, "Out of memory\n"); + status = NOTMUCH_STATUS_OUT_OF_MEMORY; goto DONE; } @@ -617,7 +628,7 @@ notmuch_database_open (const char *path, initialized = 1; } - notmuch = talloc (NULL, notmuch_database_t); + notmuch = talloc_zero (NULL, notmuch_database_t); notmuch->exception_reported = FALSE; notmuch->path = talloc_strdup (notmuch, path); @@ -643,8 +654,9 @@ notmuch_database_open (const char *path, " read-write mode.\n", notmuch_path, version, NOTMUCH_DATABASE_VERSION); notmuch->mode = NOTMUCH_DATABASE_MODE_READ_ONLY; - notmuch_database_close (notmuch); + notmuch_database_destroy (notmuch); notmuch = NULL; + status = NOTMUCH_STATUS_FILE_ERROR; goto DONE; } @@ -703,23 +715,27 @@ notmuch_database_open (const char *path, } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred opening database: %s\n", error.get_msg().c_str()); + notmuch_database_destroy (notmuch); notmuch = NULL; + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; } DONE: - if (notmuch_path) - free (notmuch_path); - if (xapian_path) - free (xapian_path); + talloc_free (local); - return notmuch; + if (database) + *database = notmuch; + else + talloc_free (notmuch); + return status; } void notmuch_database_close (notmuch_database_t *notmuch) { try { - if (notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) + if (notmuch->xapian_db != NULL && + notmuch->mode == NOTMUCH_DATABASE_MODE_READ_WRITE) (static_cast (notmuch->xapian_db))->flush (); } catch (const Xapian::Error &error) { if (! notmuch->exception_reported) { @@ -728,10 +744,31 @@ notmuch_database_close (notmuch_database_t *notmuch) } } + /* Many Xapian objects (and thus notmuch objects) hold references to + * the database, so merely deleting the database may not suffice to + * close it. Thus, we explicitly close it here. */ + if (notmuch->xapian_db != NULL) { + try { + notmuch->xapian_db->close(); + } catch (const Xapian::Error &error) { + /* do nothing */ + } + } + delete notmuch->term_gen; + notmuch->term_gen = NULL; delete notmuch->query_parser; + notmuch->query_parser = NULL; delete notmuch->xapian_db; + notmuch->xapian_db = NULL; delete notmuch->value_range_processor; + notmuch->value_range_processor = NULL; +} + +void +notmuch_database_destroy (notmuch_database_t *notmuch) +{ + notmuch_database_close (notmuch); talloc_free (notmuch); } @@ -1816,6 +1853,9 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch, if (message_ret == NULL) return NOTMUCH_STATUS_NULL_POINTER; + /* return NULL on any failure */ + *message_ret = NULL; + local = talloc_new (notmuch); try {