diff mbox series

[04/11] Lua: expose img_type's fdin file handle to Lua

Message ID 20171103123009.18705-4-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
The SWUpdate-internal img_type's attribute fdin has to be
exposed to the Lua realm in order to be able to call, e.g.,
copyfile() from within a Lua handler or when chaining handlers,
i.e., calling C handlers from within a Lua handler.

As it's an SWUpdate-internal attribute, put it into the "hidden"
Lua table as image["_private"]["istream"].

Signed-off-by: Christian Storm <christian.storm@siemens.com>
---
 corelib/lua_interface.c | 38 ++++++++++++++++++++++++++++++++++++++
 include/lua_util.h      |  9 +++++++++
 2 files changed, 47 insertions(+)

Comments

Stefano Babic Nov. 7, 2017, 4:18 p.m. UTC | #1
On 03/11/2017 13:30, Christian Storm wrote:
> The SWUpdate-internal img_type's attribute fdin has to be
> exposed to the Lua realm in order to be able to call, e.g.,
> copyfile() from within a Lua handler or when chaining handlers,
> i.e., calling C handlers from within a Lua handler.
> 
> As it's an SWUpdate-internal attribute, put it into the "hidden"
> Lua table as image["_private"]["istream"].
> 
> Signed-off-by: Christian Storm <christian.storm@siemens.com>
> ---
>  corelib/lua_interface.c | 38 ++++++++++++++++++++++++++++++++++++++
>  include/lua_util.h      |  9 +++++++++
>  2 files changed, 47 insertions(+)
> 
> diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
> index 216e44a..21c361f 100644
> --- a/corelib/lua_interface.c
> +++ b/corelib/lua_interface.c
> @@ -303,6 +303,17 @@ static void update_table(lua_State* L, struct img_type *img)
>  	}
>  }
>  
> +#ifdef CONFIG_HANDLER_IN_LUA
> +#if LUA_VERSION_NUM > 501
> +static int l_istream_fclose(lua_State *L)
> +{
> +	/* closing istream is not allowed, ignore it. */
> +	lua_pushboolean(L, true);
> +	return 1;
> +}
> +#endif
> +#endif
> +
>  static void image2table(lua_State* L, struct img_type *img)
>  {
>  	if (L && img) {
> @@ -328,6 +339,23 @@ static void image2table(lua_State* L, struct img_type *img)
>  		lua_setmetatable(L, -2);
>  
>  		update_table(L, img);
> +
> +#ifdef CONFIG_HANDLER_IN_LUA
> +		lua_getfield(L, -1, "_private");
> +		lua_pushstring(L, "istream");
> +		luaL_Stream *lstream = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
> +		luaL_getmetatable(L, LUA_FILEHANDLE);
> +		lua_setmetatable(L, -2);
> +#if LUA_VERSION_NUM > 501
> +		lstream->closef = l_istream_fclose;
> +#endif
> +		lstream->f = fdopen(img->fdin, "r");
> +		if (lstream->f == NULL) {
> +			WARN("Cannot fdopen file descriptor %d: %s", img->fdin, strerror(errno));
> +		}
> +		lua_settable(L, -3);
> +		lua_pop(L, 1);
> +#endif
>  	}
>  }
>  
> @@ -353,6 +381,16 @@ static void table2image(lua_State* L, struct img_type *img) {
>  		lua_getfield(L, -1, "_private");
>  		lua_getfield(L, -1, "offset");
>  		img->offset = (off_t)luaL_checknumber(L, -1);
> +#ifdef CONFIG_HANDLER_IN_LUA
> +		lua_pop(L, 1);
> +		lua_getfield(L, -1, "istream");
> +		luaL_Stream *lstream = ((luaL_Stream *)luaL_checkudata(L, -1, LUA_FILEHANDLE));
> +		if (lstream->f == NULL) {
> +			img->fdin = -1;
> +		} else {
> +			img->fdin = fileno(lstream->f);
> +		}
> +#endif
>  		lua_pop(L,2);
>  	}
>  }
> diff --git a/include/lua_util.h b/include/lua_util.h
> index 684eddf..03ef8d9 100644
> --- a/include/lua_util.h
> +++ b/include/lua_util.h
> @@ -41,6 +41,15 @@ int lua_handlers_init(void);
>  #define luaL_newlib(L, l) (lua_newtable((L)),luaL_setfuncs((L), (l), 0))
>  void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
>  void luaL_requiref(lua_State *L, char const* modname, lua_CFunction openf, int glb);
> +
> +/*
> + * See https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Stream
> + * on the reason for the absence of luaL_Stream's closef member and
> + * compatibility with LuaJIT / Lua 5.1.
> + */
> +typedef struct luaL_Stream {
> +  FILE *f;
> +} luaL_Stream;
>  #endif
>  
>  #else
> 

Applied to -master, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
index 216e44a..21c361f 100644
--- a/corelib/lua_interface.c
+++ b/corelib/lua_interface.c
@@ -303,6 +303,17 @@  static void update_table(lua_State* L, struct img_type *img)
 	}
 }
 
+#ifdef CONFIG_HANDLER_IN_LUA
+#if LUA_VERSION_NUM > 501
+static int l_istream_fclose(lua_State *L)
+{
+	/* closing istream is not allowed, ignore it. */
+	lua_pushboolean(L, true);
+	return 1;
+}
+#endif
+#endif
+
 static void image2table(lua_State* L, struct img_type *img)
 {
 	if (L && img) {
@@ -328,6 +339,23 @@  static void image2table(lua_State* L, struct img_type *img)
 		lua_setmetatable(L, -2);
 
 		update_table(L, img);
+
+#ifdef CONFIG_HANDLER_IN_LUA
+		lua_getfield(L, -1, "_private");
+		lua_pushstring(L, "istream");
+		luaL_Stream *lstream = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
+		luaL_getmetatable(L, LUA_FILEHANDLE);
+		lua_setmetatable(L, -2);
+#if LUA_VERSION_NUM > 501
+		lstream->closef = l_istream_fclose;
+#endif
+		lstream->f = fdopen(img->fdin, "r");
+		if (lstream->f == NULL) {
+			WARN("Cannot fdopen file descriptor %d: %s", img->fdin, strerror(errno));
+		}
+		lua_settable(L, -3);
+		lua_pop(L, 1);
+#endif
 	}
 }
 
@@ -353,6 +381,16 @@  static void table2image(lua_State* L, struct img_type *img) {
 		lua_getfield(L, -1, "_private");
 		lua_getfield(L, -1, "offset");
 		img->offset = (off_t)luaL_checknumber(L, -1);
+#ifdef CONFIG_HANDLER_IN_LUA
+		lua_pop(L, 1);
+		lua_getfield(L, -1, "istream");
+		luaL_Stream *lstream = ((luaL_Stream *)luaL_checkudata(L, -1, LUA_FILEHANDLE));
+		if (lstream->f == NULL) {
+			img->fdin = -1;
+		} else {
+			img->fdin = fileno(lstream->f);
+		}
+#endif
 		lua_pop(L,2);
 	}
 }
diff --git a/include/lua_util.h b/include/lua_util.h
index 684eddf..03ef8d9 100644
--- a/include/lua_util.h
+++ b/include/lua_util.h
@@ -41,6 +41,15 @@  int lua_handlers_init(void);
 #define luaL_newlib(L, l) (lua_newtable((L)),luaL_setfuncs((L), (l), 0))
 void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup);
 void luaL_requiref(lua_State *L, char const* modname, lua_CFunction openf, int glb);
+
+/*
+ * See https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Stream
+ * on the reason for the absence of luaL_Stream's closef member and
+ * compatibility with LuaJIT / Lua 5.1.
+ */
+typedef struct luaL_Stream {
+  FILE *f;
+} luaL_Stream;
 #endif
 
 #else