These new method signatures return and take handle objects to operate on so we can move away from the idea of one global handle in the API. There is also another important change and that deals with the setting of root and dbpaths. These are now done at initialization time instead of using setter methods. This allows the library to operate more safely knowing that paths won't change underneath it. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/alpm.c | 72 ++++++++++++++++++++++++++++++++++-------------- lib/libalpm/alpm.h | 36 ++++++++---------------- lib/libalpm/be_local.c | 2 +- lib/libalpm/db.c | 2 +- lib/libalpm/db.h | 4 +-- lib/libalpm/handle.c | 44 ++-------------------------- lib/libalpm/handle.h | 3 +- 7 files changed, 72 insertions(+), 91 deletions(-) diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 55f6ecd..d516870 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -45,21 +45,37 @@ extern pmhandle_t *handle; /** Initializes the library. This must be called before any other * functions are called. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * @param root the root path for all filesystem operations + * @param dbpath the absolute path to the libalpm database + * @param err an optional variable to hold any error return codes + * @return a context handle on success, NULL on error, err will be set if provided */ -int SYMEXPORT alpm_initialize(void) +pmhandle_t SYMEXPORT *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err) { - ASSERT(handle == NULL, RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1)); - - handle = _alpm_handle_new(); - if(handle == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); + enum _pmerrno_t myerr; + const char *lf = "db.lck"; + size_t lockfilelen; + pmhandle_t *myhandle = _alpm_handle_new(); + + if(myhandle == NULL) { + myerr = PM_ERR_MEMORY; + goto cleanup; } - if(_alpm_db_register_local(handle) == NULL) { - /* error code should be set */ - _alpm_handle_free(handle); - handle = NULL; - return -1; + if((myerr = _alpm_set_directory_option(root, &(myhandle->root), 1))) { + goto cleanup; + } + if((myerr = _alpm_set_directory_option(dbpath, &(myhandle->dbpath), 1))) { + goto cleanup; + } + + lockfilelen = strlen(myhandle->dbpath) + strlen(lf) + 1; + myhandle->lockfile = calloc(lockfilelen, sizeof(char)); + snprintf(myhandle->lockfile, lockfilelen, "%s%s", myhandle->dbpath, lf); + + if(_alpm_db_register_local(myhandle) == NULL) { + myerr = PM_ERR_DB_CREATE; + goto cleanup; } #ifdef ENABLE_NLS @@ -68,33 +84,47 @@ int SYMEXPORT alpm_initialize(void) #ifdef HAVE_LIBCURL curl_global_init(CURL_GLOBAL_SSL); - handle->curl = curl_easy_init(); + myhandle->curl = curl_easy_init(); #endif - return 0; + /* TODO temporary until global var removed */ + handle = myhandle; + return myhandle; + +cleanup: + _alpm_handle_free(myhandle); + if(err && myerr) { + *err = myerr; + } + return NULL; } /** Release the library. This should be the last alpm call you make. - * @return 0 on success, -1 on error (pm_errno is set accordingly) + * After this returns, handle should be considered invalid and cannot be reused + * in any way. + * @param handle the context handle + * @return 0 on success, -1 on error */ -int SYMEXPORT alpm_release(void) +int SYMEXPORT alpm_release(pmhandle_t *myhandle) { pmdb_t *db; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + ASSERT(myhandle != NULL, return -1); /* close local database */ - db = handle->db_local; + db = myhandle->db_local; if(db) { db->ops->unregister(db); - handle->db_local = NULL; + myhandle->db_local = NULL; } - if(alpm_db_unregister_all() == -1) { + if(alpm_db_unregister_all(myhandle) == -1) { return -1; } - _alpm_handle_free(handle); + _alpm_handle_free(myhandle); + myhandle = NULL; + /* TODO temporary until global var removed */ handle = NULL; #ifdef HAVE_LIBCURL diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index bc06cc0..ee55d0b 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -86,14 +86,6 @@ typedef struct __pmconflict_t pmconflict_t; typedef struct __pmfileconflict_t pmfileconflict_t; /* - * Library - */ - -int alpm_initialize(void); -int alpm_release(void); -const char *alpm_version(void); - -/* * Logging facilities */ @@ -165,15 +157,14 @@ alpm_cb_totaldl alpm_option_get_totaldlcb(void); /** Sets the callback used to report total download size. */ int alpm_option_set_totaldlcb(alpm_cb_totaldl cb); -/** Returns the root of the destination filesystem. */ +/** Returns the root of the destination filesystem. Read-only. */ const char *alpm_option_get_root(void); -/** Sets the root of the destination filesystem. */ -int alpm_option_set_root(const char *root); -/** Returns the path to the database directory. */ +/** Returns the path to the database directory. Read-only. */ const char *alpm_option_get_dbpath(void); -/** Sets the path to the database directory. */ -int alpm_option_set_dbpath(const char *dbpath); + +/** Get the name of the database lock file. Read-only. */ +const char *alpm_option_get_lockfile(void); /** @name Accessors to the list of package cache directories. * @{ @@ -189,15 +180,6 @@ const char *alpm_option_get_logfile(void); /** Sets the logfile name. */ int alpm_option_set_logfile(const char *logfile); -/** Get the name of the database lock file. - * - * This properly is read-only, and determined from - * the database path. - * - * @sa alpm_option_set_dbpath(const char*) - */ -const char *alpm_option_get_lockfile(void); - /** Returns the signature directory path. */ const char *alpm_option_get_signaturedir(void); /** Sets the signature directory path. */ @@ -302,9 +284,10 @@ pmdb_t *alpm_db_register_sync(const char *treename); int alpm_db_unregister(pmdb_t *db); /** Unregister all package databases. + * @param handle the context handle * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_db_unregister_all(void); +int alpm_db_unregister_all(pmhandle_t *handle); /** Get the name of a package database. * @param db pointer to the package database @@ -1054,6 +1037,11 @@ const char *alpm_strerrorlast(void); /* End of alpm_api_errors */ /** @} */ +pmhandle_t *alpm_initialize(const char *root, const char *dbpath, + enum _pmerrno_t *err); +int alpm_release(pmhandle_t *handle); +const char *alpm_version(void); + /* End of alpm_api */ /** @} */ diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c index 64af4b9..3a0887d 100644 --- a/lib/libalpm/be_local.c +++ b/lib/libalpm/be_local.c @@ -936,7 +936,7 @@ pmdb_t *_alpm_db_register_local(pmhandle_t *handle) db = _alpm_db_new("local", 1); if(db == NULL) { - RET_ERR(PM_ERR_DB_CREATE, NULL); + return NULL; } db->ops = &local_db_ops; db->handle = handle; diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c index 9b1f4fb..fda8428 100644 --- a/lib/libalpm/db.c +++ b/lib/libalpm/db.c @@ -71,7 +71,7 @@ void _alpm_db_unregister(pmdb_t *db) } /** Unregister all package databases. */ -int SYMEXPORT alpm_db_unregister_all(void) +int SYMEXPORT alpm_db_unregister_all(pmhandle_t *handle) { alpm_list_t *i; pmdb_t *db; diff --git a/lib/libalpm/db.h b/lib/libalpm/db.h index 3a7ab72..9ecf31f 100644 --- a/lib/libalpm/db.h +++ b/lib/libalpm/db.h @@ -22,9 +22,6 @@ #ifndef _ALPM_DB_H #define _ALPM_DB_H -#include "alpm.h" -#include "pkghash.h" - #include <time.h> /* libarchive */ @@ -32,6 +29,7 @@ #include <archive_entry.h> #include "alpm.h" +#include "pkghash.h" #include "signing.h" /* Database entries */ diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index d794992..48ab3a3 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -313,7 +313,7 @@ static char *canonicalize_path(const char *path) { return new_path; } -int _alpm_set_directory_option(const char *value, +enum _pmerrno_t _alpm_set_directory_option(const char *value, char **storage, int must_exist) { struct stat st; @@ -322,19 +322,16 @@ int _alpm_set_directory_option(const char *value, path = value; if(!path) { - pm_errno = PM_ERR_WRONG_ARGS; - return -1; + return PM_ERR_WRONG_ARGS; } if(must_exist) { if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) { - pm_errno = PM_ERR_NOT_A_DIR; - return -1; + return PM_ERR_NOT_A_DIR; } real = calloc(PATH_MAX + 1, sizeof(char)); if(!realpath(path, real)) { free(real); - pm_errno = PM_ERR_NOT_A_DIR; - return -1; + return PM_ERR_NOT_A_DIR; } path = real; } @@ -347,39 +344,6 @@ int _alpm_set_directory_option(const char *value, return 0; } -int SYMEXPORT alpm_option_set_root(const char *root) -{ - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - if(_alpm_set_directory_option(root, &(handle->root), 1)) { - return -1; - } - _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); - return 0; -} - -int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) -{ - const char *lf = "db.lck"; - size_t lockfilelen; - - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); - - if(_alpm_set_directory_option(dbpath, &(handle->dbpath), 1)) { - return -1; - } - _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); - - if(handle->lockfile) { - FREE(handle->lockfile); - } - lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1; - handle->lockfile = calloc(lockfilelen, sizeof(char)); - snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); - _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); - return 0; -} - int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) { char *newcachedir; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index b72c9b0..ecfefcc 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -75,7 +75,8 @@ struct __pmhandle_t { pmhandle_t *_alpm_handle_new(void); void _alpm_handle_free(pmhandle_t *handle); -int _alpm_set_directory_option(const char *value, char **storage, int must_exist); +enum _pmerrno_t _alpm_set_directory_option(const char *value, + char **storage, int must_exist); #endif /* _ALPM_HANDLE_H */ -- 1.7.5.2