@@ -21,8 +21,8 @@ struct installer_handler supported_types[MAX_INSTALLER_HANDLER];
static unsigned long nr_installers = 0;
static unsigned long handler_index = ULONG_MAX;
-int register_handler(const char *desc,
- handler installer, HANDLER_MASK mask, void *data)
+static int __register_handler(const char *desc,
+ handler installer, HANDLER_MASK mask, void *data, handler_type_t lifetime)
{
int i;
@@ -43,11 +43,61 @@ int register_handler(const char *desc,
supported_types[nr_installers].installer = installer;
supported_types[nr_installers].data = data;
supported_types[nr_installers].mask = mask;
+ supported_types[nr_installers].noglobal = (lifetime == SESSION_HANDLER);
nr_installers++;
return 0;
}
+int register_handler(const char *desc,
+ handler installer, HANDLER_MASK mask, void *data)
+{
+ return __register_handler(desc, installer, mask, data, GLOBAL_HANDLER);
+}
+
+int register_session_handler(const char *desc,
+ handler installer, HANDLER_MASK mask, void *data)
+{
+ return __register_handler(desc, installer, mask, data, SESSION_HANDLER);
+}
+
+int unregister_handler(const char *desc)
+{
+ int i;
+
+ for (i = 0; i < nr_installers; i++) {
+ if ((strlen(desc) == strlen(supported_types[i].desc)) &&
+ IS_STR_EQUAL(desc, supported_types[i].desc)) {
+ break;
+ }
+ }
+
+ /* Not found */
+ if (i == nr_installers)
+ return -1;
+ for (int j = i + 1; j < nr_installers; j++) {
+ strlcpy(supported_types[j - 1].desc, supported_types[j].desc,
+ sizeof(supported_types[j -1].desc));
+ supported_types[j - 1].installer = supported_types[j].installer;
+ supported_types[j - 1].data = supported_types[j].data;
+ supported_types[j - 1].mask = supported_types[j].mask;
+ }
+ nr_installers--;
+
+ return 0;
+}
+
+void unregister_session_handlers(void)
+{
+ int i;
+
+ for (i = nr_installers - 1; i >= 0; i--) {
+ if (supported_types[i].noglobal) {
+ unregister_handler(supported_types[i].desc);
+ }
+ }
+}
+
void print_registered_handlers(void)
{
unsigned int i;
@@ -8,6 +8,8 @@
#pragma once
+#include <stdbool.h>
+
struct img_type;
/*
@@ -36,16 +38,29 @@ typedef enum {
NO_DATA_HANDLER = 32
} HANDLER_MASK;
+/*
+ * Life-cycle for the handler:
+ * GLOBAL : handler is instantiated at startup and available for all updates
+ * SESSION : handler is part of the SWU and available only for the current update
+ */
+
+typedef enum {
+ GLOBAL_HANDLER,
+ SESSION_HANDLER
+} handler_type_t;
+
#define ANY_HANDLER (IMAGE_HANDLER | FILE_HANDLER | SCRIPT_HANDLER | \
BOOTLOADER_HANDLER | PARTITION_HANDLER | \
NO_DATA_HANDLER)
typedef int (*handler)(struct img_type *img, void *data);
struct installer_handler{
- char desc[64];
- handler installer;
- void *data;
- unsigned int mask;
+ char desc[64]; /* Name that identifies the handler */
+ handler installer; /* Handler function */
+ void *data; /* Private data for the handler */
+ unsigned int mask; /* Mask (see HANDLER_MASK) */
+ bool noglobal; /* true if handler is not global and
+ should be removed after install */
};
struct script_handler_data {
@@ -59,6 +74,10 @@ struct script_handler_data {
int register_handler(const char *desc,
handler installer, HANDLER_MASK mask, void *data);
+int register_session_handler(const char *desc,
+ handler installer, HANDLER_MASK mask, void *data);
+int unregister_handler(const char *desc);
+void unregister_session_handlers(void);
struct installer_handler *find_handler(struct img_type *img);
void print_registered_handlers(void);
Up now, handlers are instantiated when SWUpdate starts. Add a function to unregister a handler that was set as temporary (noglobal flag) and was instantiated during an install transaction. This is to provide in future a way to add new handlers that are transferred together with the SWU. Signed-off-by: Stefano Babic <stefano.babic@swupdate.org> --- core/handler.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-- include/handler.h | 27 ++++++++++++++++++++---- 2 files changed, 75 insertions(+), 6 deletions(-) -- 2.34.1