Message ID | 20171103123009.18705-6-christian.storm@siemens.com |
---|---|
State | Accepted |
Headers | show |
Series | [01/11] Lua: expose get_tmpdir() to Lua | expand |
On 03/11/2017 13:30, Christian Storm wrote: > As the artifact's data is not unconditionally extracted and > img_type's fdin is available to Lua, a Lua handler may chain-call > a C handler to process the artifact while having the ability to > do work in Lua prior to and/or after having called the C handler. > > Available C handlers are exposed to Lua in the swupdate.handlers > table (as keys). The new Lua function swupdate.call_handler() can > then be used to chain-call a C handler by providing the > C handler's name and the image parameter to it. > > Signed-off-by: Christian Storm <christian.storm@siemens.com> > --- > core/handler.c | 15 +++++++++++++ > corelib/lua_interface.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ > include/handler.h | 1 + > 3 files changed, 76 insertions(+) > > diff --git a/core/handler.c b/core/handler.c > index 7e9f3ed..4793288 100644 > --- a/core/handler.c > +++ b/core/handler.c > @@ -23,6 +23,7 @@ > #include <stdio.h> > #include <unistd.h> > #include <string.h> > +#include <limits.h> > > #include "swupdate.h" > #include "handler.h" > @@ -31,6 +32,7 @@ > #define MAX_INSTALLER_HANDLER 64 > 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) > @@ -76,3 +78,16 @@ struct installer_handler *find_handler(struct img_type *img) > return NULL; > return &supported_types[i]; > } > + > +struct installer_handler *get_next_handler(void) > +{ > + if (handler_index == ULONG_MAX) { > + handler_index = 0; > + } > + if (handler_index >= nr_installers) { > + handler_index = ULONG_MAX; > + return NULL; > + } > + return &supported_types[handler_index++]; > +} > + > diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c > index 85a1d36..9694480 100644 > --- a/corelib/lua_interface.c > +++ b/corelib/lua_interface.c > @@ -53,6 +53,7 @@ extern const char EMBEDDED_LUA_SRC[]; > > #ifdef CONFIG_HANDLER_IN_LUA > static int l_register_handler( lua_State *L ); > +static int l_call_handler(lua_State *L); > #endif > > void LUAstackDump(lua_State *L) > @@ -460,6 +461,7 @@ static int l_get_tmpdir(lua_State *L) > static const luaL_Reg l_swupdate[] = { > #ifdef CONFIG_HANDLER_IN_LUA > { "register_handler", l_register_handler }, > + { "call_handler", l_call_handler }, > { "tmpdir", l_get_tmpdir }, > #endif > { "notify", l_notify }, > @@ -509,6 +511,15 @@ static int luaopen_swupdate(lua_State *L) { > lua_push_enum(L, "PARTITION_HANDLER", PARTITION_HANDLER); > lua_push_enum(L, "ANY_HANDLER", ANY_HANDLER); > lua_settable(L, -3); > + > + lua_pushstring(L, "handler"); > + lua_newtable (L); > + struct installer_handler *hnd; > + while ((hnd = get_next_handler()) != NULL) { > + lua_pushinteger(L, 1); > + lua_setfield(L, -2, hnd->desc); > + } > + lua_settable(L, -3); > #endif > > return 1; > @@ -596,6 +607,55 @@ static int l_register_handler( lua_State *L ) { > } > } > > +static int l_call_handler(lua_State *L) > +{ > + struct installer_handler *hnd; > + struct img_type img = {}; > + char *orighndtype = NULL; > + char *msg = NULL; > + int ret = 0; > + > + luaL_checktype(L, 1, LUA_TSTRING); > + luaL_checktype(L, 2, LUA_TTABLE); > + > + table2image(L, &img); > + if ((orighndtype = strndupa(img.type, sizeof(img.type))) == NULL) { > + lua_pop(L, 2); > + lua_pushnumber(L, 1); > + lua_pushstring(L, "Error allocating memory"); > + return 2; > + } > + strncpy(img.type, lua_tostring(L, 1), sizeof(img.type)); > + > + if ((hnd = find_handler(&img)) == NULL) { > + if (asprintf(&msg, "Image type %s not supported!", img.type) == -1) { > + msg = NULL; > + } > + ret = 1; > + goto call_handler_exit; > + } > + if ((hnd->installer(&img, hnd->data)) != 0) { > + if (asprintf(&msg, "Executing handler %s failed!", hnd->desc) == -1) { > + msg = NULL; > + } > + ret = 1; > + goto call_handler_exit; > + } > + > +call_handler_exit: > + strncpy(img.type, orighndtype, sizeof(img.type)); > + update_table(L, &img); > + lua_pop(L, 2); > + lua_pushnumber(L, ret); > + if (msg != NULL) { > + lua_pushstring(L, msg); > + free(msg); > + } else { > + lua_pushnil(L); > + } > + return 2; > +} > + > int lua_handlers_init(void) > { > int ret = -1; > diff --git a/include/handler.h b/include/handler.h > index 04165c9..f2896ab 100644 > --- a/include/handler.h > +++ b/include/handler.h > @@ -57,4 +57,5 @@ int register_handler(const char *desc, > > struct installer_handler *find_handler(struct img_type *img); > void print_registered_handlers(void); > +struct installer_handler *get_next_handler(void); > #endif > Applied to -master, thanks ! Best regards, Stefano Babic
diff --git a/core/handler.c b/core/handler.c index 7e9f3ed..4793288 100644 --- a/core/handler.c +++ b/core/handler.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <unistd.h> #include <string.h> +#include <limits.h> #include "swupdate.h" #include "handler.h" @@ -31,6 +32,7 @@ #define MAX_INSTALLER_HANDLER 64 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) @@ -76,3 +78,16 @@ struct installer_handler *find_handler(struct img_type *img) return NULL; return &supported_types[i]; } + +struct installer_handler *get_next_handler(void) +{ + if (handler_index == ULONG_MAX) { + handler_index = 0; + } + if (handler_index >= nr_installers) { + handler_index = ULONG_MAX; + return NULL; + } + return &supported_types[handler_index++]; +} + diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c index 85a1d36..9694480 100644 --- a/corelib/lua_interface.c +++ b/corelib/lua_interface.c @@ -53,6 +53,7 @@ extern const char EMBEDDED_LUA_SRC[]; #ifdef CONFIG_HANDLER_IN_LUA static int l_register_handler( lua_State *L ); +static int l_call_handler(lua_State *L); #endif void LUAstackDump(lua_State *L) @@ -460,6 +461,7 @@ static int l_get_tmpdir(lua_State *L) static const luaL_Reg l_swupdate[] = { #ifdef CONFIG_HANDLER_IN_LUA { "register_handler", l_register_handler }, + { "call_handler", l_call_handler }, { "tmpdir", l_get_tmpdir }, #endif { "notify", l_notify }, @@ -509,6 +511,15 @@ static int luaopen_swupdate(lua_State *L) { lua_push_enum(L, "PARTITION_HANDLER", PARTITION_HANDLER); lua_push_enum(L, "ANY_HANDLER", ANY_HANDLER); lua_settable(L, -3); + + lua_pushstring(L, "handler"); + lua_newtable (L); + struct installer_handler *hnd; + while ((hnd = get_next_handler()) != NULL) { + lua_pushinteger(L, 1); + lua_setfield(L, -2, hnd->desc); + } + lua_settable(L, -3); #endif return 1; @@ -596,6 +607,55 @@ static int l_register_handler( lua_State *L ) { } } +static int l_call_handler(lua_State *L) +{ + struct installer_handler *hnd; + struct img_type img = {}; + char *orighndtype = NULL; + char *msg = NULL; + int ret = 0; + + luaL_checktype(L, 1, LUA_TSTRING); + luaL_checktype(L, 2, LUA_TTABLE); + + table2image(L, &img); + if ((orighndtype = strndupa(img.type, sizeof(img.type))) == NULL) { + lua_pop(L, 2); + lua_pushnumber(L, 1); + lua_pushstring(L, "Error allocating memory"); + return 2; + } + strncpy(img.type, lua_tostring(L, 1), sizeof(img.type)); + + if ((hnd = find_handler(&img)) == NULL) { + if (asprintf(&msg, "Image type %s not supported!", img.type) == -1) { + msg = NULL; + } + ret = 1; + goto call_handler_exit; + } + if ((hnd->installer(&img, hnd->data)) != 0) { + if (asprintf(&msg, "Executing handler %s failed!", hnd->desc) == -1) { + msg = NULL; + } + ret = 1; + goto call_handler_exit; + } + +call_handler_exit: + strncpy(img.type, orighndtype, sizeof(img.type)); + update_table(L, &img); + lua_pop(L, 2); + lua_pushnumber(L, ret); + if (msg != NULL) { + lua_pushstring(L, msg); + free(msg); + } else { + lua_pushnil(L); + } + return 2; +} + int lua_handlers_init(void) { int ret = -1; diff --git a/include/handler.h b/include/handler.h index 04165c9..f2896ab 100644 --- a/include/handler.h +++ b/include/handler.h @@ -57,4 +57,5 @@ int register_handler(const char *desc, struct installer_handler *find_handler(struct img_type *img); void print_registered_handlers(void); +struct installer_handler *get_next_handler(void); #endif
As the artifact's data is not unconditionally extracted and img_type's fdin is available to Lua, a Lua handler may chain-call a C handler to process the artifact while having the ability to do work in Lua prior to and/or after having called the C handler. Available C handlers are exposed to Lua in the swupdate.handlers table (as keys). The new Lua function swupdate.call_handler() can then be used to chain-call a C handler by providing the C handler's name and the image parameter to it. Signed-off-by: Christian Storm <christian.storm@siemens.com> --- core/handler.c | 15 +++++++++++++ corelib/lua_interface.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ include/handler.h | 1 + 3 files changed, 76 insertions(+)