Message ID | 20171103123009.18705-4-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: > 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 --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
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(+)