diff mbox series

[06/11] Lua: introduce method to chain-call C handlers

Message ID 20171103123009.18705-6-christian.storm@siemens.com
State Accepted
Headers show
Series [01/11] Lua: expose get_tmpdir() to Lua | expand

Commit Message

Storm, Christian Nov. 3, 2017, 12:30 p.m. UTC
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(+)

Comments

Stefano Babic Nov. 7, 2017, 4:18 p.m. UTC | #1
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 mbox series

Patch

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