Hello Lua, I was looking for a way to be able to redirect standard input/output to a file. As I couldn't find a way to do this from Lua, nor too much information on this list, I thought I'd give it a shot at writing my first module. The result is attached, and I can't figure out what I did wrong (because an obvious lack of experience and maybe not reading enough documentation, I must admit). test.lua should load the module, redirect stdout to 'test.txt' then output some text. But the actual behavior is far from expected: 'text.txt' is indeed created and output no longer goes to the screen, but it doesn't go to text.txt either. And upon closing the interpreter, it crashes because of an access violation (output is unbuffered, so this should not be the reason for text.txt being empty in the end). If anyone could give me a hint on this one, it would be highly appreciated. -- Theodor-Iulian Ciobanu Virus Researcher e-mail: tciobanu@bitdefender.com ----------------------------------------- Secure your every bit -----------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
//** See Copyright Notice in lua.h
static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, "%s: %s", filename, strerror(en));
else
lua_pushfstring(L, "%s", strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
//** See Copyright Notice in lua.h
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}
static int lredirectstd(lua_State *L, FILE *stdfile, char *defmode)
{
const char *path = luaL_checklstring(L,1,NULL);
const char *mode = luaL_optstring(L,2,defmode);
FILE **pf;
if (!path||!mode)
lua_pushnil(L);
**pf=newfile(L);
*pf=freopen(path,mode,stdfile);
if (*pf==NULL)
return pushresult(L,0,path);
else if (setvbuf(*pf,NULL,_IONBF,0)!=0)
return pushresult(L,0,path);
return 1;
}
static int lredirectin(lua_State *L)
{
return lredirectstd(L,stdin,"r");
}
static int lredirectout(lua_State *L)
{
return lredirectstd(L,stdout,"w");
}
static int lredirecterr(lua_State *L)
{
return lredirectstd(L,stderr,"w");
}
static void set_info(lua_State *L)
{
lua_pushliteral(L,"_VERSION");
lua_pushliteral(L,"0.1");
lua_settable(L,-3);
}
static struct luaL_reg stdredirlib[] = {
{"in", lredirectin},
{"out", lredirectout},
{"err", lredirecterr},
{NULL, NULL}
};
LUALIB_API int luaopen_stdredir(lua_State *L)
{
luaL_register(L,"stdredir",stdredirlib);
set_info(L);
return 1;
}
Attachment:
test.lua
Description: Binary data