diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2021-04-25 20:03:54 +0200 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2021-05-01 04:08:14 +0200 |
commit | e7fa35baa22bf6710a904815456d3ff679005fc7 (patch) | |
tree | c988537bbc720da5fce7de30c39e73f6e67a16a0 /lib/libalpm | |
parent | 523c393e9e6175e632d355c9440abb0be164a362 (diff) | |
download | pacman-e7fa35baa22bf6710a904815456d3ff679005fc7.tar.gz pacman-e7fa35baa22bf6710a904815456d3ff679005fc7.tar.xz |
add front-end provided context to callbacks
Our callbacks require front-ends to maintain state in order to provide
reasonable output. The new download callback in particular requires
much more complex state information to be saved. Without the ability to
provide context, state must be saved globally, which may not be possible
for all front-ends. Scripting language bindings in particular have no
way to register per-handle callbacks without some form of context.
Implements: FS#12721
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/alpm.h | 73 | ||||
-rw-r--r-- | lib/libalpm/dload.c | 11 | ||||
-rw-r--r-- | lib/libalpm/handle.c | 54 | ||||
-rw-r--r-- | lib/libalpm/handle.h | 12 | ||||
-rw-r--r-- | lib/libalpm/log.c | 2 |
5 files changed, 124 insertions, 28 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 2e99d4d8..65b8e2fb 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -971,8 +971,9 @@ typedef union _alpm_event_t { /** Event callback. * * Called when an event occurs + * @param ctx user-provided context * @param event the event that occurred */ -typedef void (*alpm_cb_event)(alpm_event_t *); +typedef void (*alpm_cb_event)(void *ctx, alpm_event_t *); /** * Type of question. @@ -1114,9 +1115,10 @@ typedef union _alpm_question_t { /** Question callback. * * This callback allows user to give input and decide what to do during certain events + * @param ctx user-provided context * @param question the question being asked. */ -typedef void (*alpm_cb_question)(alpm_question_t *); +typedef void (*alpm_cb_question)(void *ctx, alpm_question_t *); /** An enum over different kinds of progress alerts. */ typedef enum _alpm_progress_t { @@ -1147,6 +1149,7 @@ typedef enum _alpm_progress_t { * Alert the front end about the progress of certain events. * Allows the implementation of loading bars for events that * make take a while to complete. + * @param ctx user-provided context * @param progress the kind of event that is progressing * @param pkg for package operations, the name of the package being operated on * @param percent the percent completion of the action @@ -1154,7 +1157,7 @@ typedef enum _alpm_progress_t { * @param current the current amount of items completed */ /** Progress callback */ -typedef void (*alpm_cb_progress)(alpm_progress_t progress, const char *pkg, +typedef void (*alpm_cb_progress)(void *ctx, alpm_progress_t progress, const char *pkg, int percent, size_t howmany, size_t current); /* @@ -1201,22 +1204,24 @@ typedef struct _alpm_download_event_completed_t { } alpm_download_event_completed_t; /** Type of download progress callbacks. + * @param ctx user-provided context * @param filename the name of the file being downloaded * @param event the event type * @param data the event data of type alpm_download_event_*_t */ -typedef void (*alpm_cb_download)(const char *filename, +typedef void (*alpm_cb_download)(void *ctx, const char *filename, alpm_download_event_type_t event, void *data); /** A callback for downloading files + * @param ctx user-provided context * @param url the URL of the file to be downloaded * @param localpath the directory to which the file should be downloaded * @param force whether to force an update, even if the file is the same * @return 0 on success, 1 if the file exists and is identical, -1 on * error. */ -typedef int (*alpm_cb_fetch)(const char *url, const char *localpath, +typedef int (*alpm_cb_fetch)(void *ctx, const char *url, const char *localpath, int force); /* End of libalpm_cb */ @@ -1464,11 +1469,12 @@ typedef enum _alpm_loglevel_t { * libalpm will call this function whenever something is to be logged. * many libalpm will produce log output. Additionally any calls to \link alpm_logaction * \endlink will also call this callback. + * @param ctx user-provided context * @param level the currently set loglevel * @param fmt the printf like format string * @param args printf like arguments */ -typedef void (*alpm_cb_log)(alpm_loglevel_t level, const char *fmt, va_list args); +typedef void (*alpm_cb_log)(void *ctx, alpm_loglevel_t level, const char *fmt, va_list args); /** A printf-like function for logging. * @param handle the context handle @@ -1498,12 +1504,19 @@ int alpm_logaction(alpm_handle_t *handle, const char *prefix, */ alpm_cb_log alpm_option_get_logcb(alpm_handle_t *handle); +/** Returns the callback used for logging. + * @param handle the context handle + * @return the currently set log callback context + */ +void *alpm_option_get_logcb_ctx(alpm_handle_t *handle); + /** Sets the callback used for logging. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb); +int alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb, void *ctx); /** Returns the callback used to report download progress. * @param handle the context handle @@ -1511,12 +1524,19 @@ int alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb); */ alpm_cb_download alpm_option_get_dlcb(alpm_handle_t *handle); +/** Returns the callback used to report download progress. + * @param handle the context handle + * @return the currently set download callback context + */ +void *alpm_option_get_dlcb_ctx(alpm_handle_t *handle); + /** Sets the callback used to report download progress. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb); +int alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb, void *ctx); /** Returns the downloading callback. * @param handle the context handle @@ -1524,12 +1544,19 @@ int alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb); */ alpm_cb_fetch alpm_option_get_fetchcb(alpm_handle_t *handle); +/** Returns the downloading callback. + * @param handle the context handle + * @return the currently set fetch callback context + */ +void *alpm_option_get_fetchcb_ctx(alpm_handle_t *handle); + /** Sets the downloading callback. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb); +int alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb, void *ctx); /** Returns the callback used for events. * @param handle the context handle @@ -1537,12 +1564,19 @@ int alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb); */ alpm_cb_event alpm_option_get_eventcb(alpm_handle_t *handle); +/** Returns the callback used for events. + * @param handle the context handle + * @return the currently set event callback context + */ +void *alpm_option_get_eventcb_ctx(alpm_handle_t *handle); + /** Sets the callback used for events. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb); +int alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb, void *ctx); /** Returns the callback used for questions. * @param handle the context handle @@ -1550,13 +1584,19 @@ int alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb); */ alpm_cb_question alpm_option_get_questioncb(alpm_handle_t *handle); +/** Returns the callback used for questions. + * @param handle the context handle + * @return the currently set question callback context + */ +void *alpm_option_get_questioncb_ctx(alpm_handle_t *handle); + /** Sets the callback used for questions. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb); - +int alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb, void *ctx); /**Returns the callback used for operation progress. * @param handle the context handle @@ -1564,12 +1604,19 @@ int alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb); */ alpm_cb_progress alpm_option_get_progresscb(alpm_handle_t *handle); +/**Returns the callback used for operation progress. + * @param handle the context handle + * @return the currently set progress callback context + */ +void *alpm_option_get_progresscb_ctx(alpm_handle_t *handle); + /** Sets the callback used for operation progress. * @param handle the context handle * @param cb the cb to use + * @param ctx user-provided context to pass to cb * @return 0 on success, -1 on error (pm_errno is set accordingly) */ -int alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress cb); +int alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress cb, void *ctx); /* End of callback accessors */ /** @} */ diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index a4c42f8d..70ec318a 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -209,7 +209,8 @@ static int dload_progress_cb(void *file, curl_off_t dltotal, curl_off_t dlnow, * download_size (nor included in the total download size callback) */ cb_data.total = dltotal; cb_data.downloaded = dlnow; - payload->handle->dlcb(payload->remote_name, ALPM_DOWNLOAD_PROGRESS, &cb_data); + payload->handle->dlcb(payload->handle->dlcb_ctx, + payload->remote_name, ALPM_DOWNLOAD_PROGRESS, &cb_data); payload->prevprogress = current_size; return 0; @@ -672,7 +673,7 @@ cleanup: alpm_download_event_completed_t cb_data = {0}; cb_data.total = bytes_dl; cb_data.result = ret; - handle->dlcb(payload->remote_name, ALPM_DOWNLOAD_COMPLETED, &cb_data); + handle->dlcb(handle->dlcb_ctx, payload->remote_name, ALPM_DOWNLOAD_COMPLETED, &cb_data); } curl_multi_remove_handle(curlm, curl); @@ -806,7 +807,7 @@ static int curl_download_internal(alpm_handle_t *handle, if(curl_add_payload(handle, curlm, payload, localpath) == 0) { if(handle->dlcb && !payload->signature) { alpm_download_event_init_t cb_data = {.optional = payload->errors_ok}; - handle->dlcb(payload->remote_name, ALPM_DOWNLOAD_INIT, &cb_data); + handle->dlcb(handle->dlcb_ctx, payload->remote_name, ALPM_DOWNLOAD_INIT, &cb_data); } payloads = payloads->next; @@ -877,7 +878,7 @@ int _alpm_download(alpm_handle_t *handle, int success = 0; if(payload->fileurl) { - if (handle->fetchcb(payload->fileurl, localpath, payload->force) != -1) { + if (handle->fetchcb(handle->fetchcb_ctx, payload->fileurl, localpath, payload->force) != -1) { success = 1; break; } @@ -891,7 +892,7 @@ int _alpm_download(alpm_handle_t *handle, MALLOC(fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(fileurl, len, "%s/%s", server, payload->filepath); - ret = handle->fetchcb(fileurl, localpath, payload->force); + ret = handle->fetchcb(handle->fetchcb_ctx, fileurl, localpath, payload->force); free(fileurl); if (ret != -1) { diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index 46224a25..e6b683cb 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -162,36 +162,72 @@ alpm_cb_log SYMEXPORT alpm_option_get_logcb(alpm_handle_t *handle) return handle->logcb; } +void SYMEXPORT *alpm_option_get_logcb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->logcb_ctx; +} + alpm_cb_download SYMEXPORT alpm_option_get_dlcb(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); return handle->dlcb; } +void SYMEXPORT *alpm_option_get_dlcb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->dlcb_ctx; +} + alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); return handle->fetchcb; } +void SYMEXPORT *alpm_option_get_fetchcb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->fetchcb_ctx; +} + alpm_cb_event SYMEXPORT alpm_option_get_eventcb(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); return handle->eventcb; } +void SYMEXPORT *alpm_option_get_eventcb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->eventcb_ctx; +} + alpm_cb_question SYMEXPORT alpm_option_get_questioncb(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); return handle->questioncb; } +void SYMEXPORT *alpm_option_get_questioncb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->questioncb_ctx; +} + alpm_cb_progress SYMEXPORT alpm_option_get_progresscb(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); return handle->progresscb; } +void SYMEXPORT *alpm_option_get_progresscb_ctx(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->progresscb_ctx; +} + const char SYMEXPORT *alpm_option_get_root(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); @@ -300,45 +336,51 @@ int SYMEXPORT alpm_option_get_parallel_downloads(alpm_handle_t *handle) return handle->parallel_downloads; } -int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb) +int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->logcb = cb; + handle->logcb_ctx = ctx; return 0; } -int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb) +int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->dlcb = cb; + handle->dlcb_ctx = ctx; return 0; } -int SYMEXPORT alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb) +int SYMEXPORT alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->fetchcb = cb; + handle->fetchcb_ctx = ctx; return 0; } -int SYMEXPORT alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb) +int SYMEXPORT alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->eventcb = cb; + handle->eventcb_ctx = ctx; return 0; } -int SYMEXPORT alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb) +int SYMEXPORT alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->questioncb = cb; + handle->questioncb_ctx = ctx; return 0; } -int SYMEXPORT alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress cb) +int SYMEXPORT alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress cb, void *ctx) { CHECK_HANDLE(handle, return -1); handle->progresscb = cb; + handle->progresscb_ctx = ctx; return 0; } diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 52dc2125..b1526c67 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -34,19 +34,19 @@ #define EVENT(h, e) \ do { \ if((h)->eventcb) { \ - (h)->eventcb((alpm_event_t *) (e)); \ + (h)->eventcb((h)->eventcb_ctx, (alpm_event_t *) (e)); \ } \ } while(0) #define QUESTION(h, q) \ do { \ if((h)->questioncb) { \ - (h)->questioncb((alpm_question_t *) (q)); \ + (h)->questioncb((h)->questioncb_ctx, (alpm_question_t *) (q)); \ } \ } while(0) #define PROGRESS(h, e, p, per, n, r) \ do { \ if((h)->progresscb) { \ - (h)->progresscb(e, p, per, n, r); \ + (h)->progresscb((h)->progresscb_ctx, e, p, per, n, r); \ } \ } while(0) @@ -72,11 +72,17 @@ struct __alpm_handle_t { /* callback functions */ alpm_cb_log logcb; /* Log callback function */ + void *logcb_ctx; alpm_cb_download dlcb; /* Download callback function */ + void *dlcb_ctx; alpm_cb_fetch fetchcb; /* Download file callback function */ + void *fetchcb_ctx; alpm_cb_event eventcb; + void *eventcb_ctx; alpm_cb_question questioncb; + void *questioncb_ctx; alpm_cb_progress progresscb; + void *progresscb_ctx; /* filesystem paths */ char *root; /* Root path, default '/' */ diff --git a/lib/libalpm/log.c b/lib/libalpm/log.c index 4c781ea2..c4d291cb 100644 --- a/lib/libalpm/log.c +++ b/lib/libalpm/log.c @@ -107,6 +107,6 @@ void _alpm_log(alpm_handle_t *handle, alpm_loglevel_t flag, const char *fmt, ... } va_start(args, fmt); - handle->logcb(flag, fmt, args); + handle->logcb(handle->logcb_ctx, flag, fmt, args); va_end(args); } |