mirror of https://github.com/rusefi/lua.git
'popen' is back
This commit is contained in:
parent
d987cf1f81
commit
86add535d8
95
liolib.c
95
liolib.c
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
** $Id: liolib.c,v 2.60 2005/05/16 21:19:00 roberto Exp roberto $
|
** $Id: liolib.c,v 2.61 2005/05/25 13:21:26 roberto Exp roberto $
|
||||||
** Standard I/O (and system) library
|
** Standard I/O (and system) library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -91,29 +91,45 @@ static FILE **newfile (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** this function has a separated environment, which defines the
|
||||||
|
** correct __close for 'popen' files
|
||||||
|
*/
|
||||||
|
static int io_pclose (lua_State *L) {
|
||||||
|
FILE **p = topfile(L);
|
||||||
|
int ok = lua_pclose(L, *p);
|
||||||
|
if (ok) *p = NULL;
|
||||||
|
return pushresult(L, ok, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int io_fclose (lua_State *L) {
|
||||||
|
FILE **p = topfile(L);
|
||||||
|
int ok = (fclose(*p) == 0);
|
||||||
|
if (ok) *p = NULL;
|
||||||
|
return pushresult(L, ok, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int aux_close (lua_State *L) {
|
static int aux_close (lua_State *L) {
|
||||||
FILE *f = tofile(L);
|
lua_getfenv(L, 1);
|
||||||
if (f == stdin || f == stdout || f == stderr)
|
lua_getfield(L, -1, "__close");
|
||||||
return 0; /* file cannot be closed */
|
return (lua_tocfunction(L, -1))(L);
|
||||||
else {
|
|
||||||
int ok = (fclose(f) == 0);
|
|
||||||
if (ok)
|
|
||||||
*(FILE **)lua_touserdata(L, 1) = NULL; /* mark file as closed */
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int io_close (lua_State *L) {
|
static int io_close (lua_State *L) {
|
||||||
if (lua_isnone(L, 1))
|
if (lua_isnone(L, 1))
|
||||||
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
|
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
|
||||||
return pushresult(L, aux_close(L), NULL);
|
tofile(L); /* make sure argument is a file */
|
||||||
|
return aux_close(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int io_gc (lua_State *L) {
|
static int io_gc (lua_State *L) {
|
||||||
FILE **f = topfile(L);
|
FILE *f = *topfile(L);
|
||||||
if (*f != NULL) /* ignore closed files */
|
/* ignore closed files and standard files */
|
||||||
|
if (f != NULL && f != stdin && f != stdout && f != stderr)
|
||||||
aux_close(L);
|
aux_close(L);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -138,6 +154,15 @@ static int io_open (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int io_popen (lua_State *L) {
|
||||||
|
const char *filename = luaL_checkstring(L, 1);
|
||||||
|
const char *mode = luaL_optstring(L, 2, "r");
|
||||||
|
FILE **pf = newfile(L);
|
||||||
|
*pf = lua_popen(L, filename, mode);
|
||||||
|
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int io_tmpfile (lua_State *L) {
|
static int io_tmpfile (lua_State *L) {
|
||||||
FILE **pf = newfile(L);
|
FILE **pf = newfile(L);
|
||||||
*pf = tmpfile();
|
*pf = tmpfile();
|
||||||
|
@ -352,7 +377,7 @@ static int io_readline (lua_State *L) {
|
||||||
luaL_error(L, "file is already closed");
|
luaL_error(L, "file is already closed");
|
||||||
sucess = read_line(L, f);
|
sucess = read_line(L, f);
|
||||||
if (ferror(f))
|
if (ferror(f))
|
||||||
luaL_error(L, "%s", strerror(errno));
|
return luaL_error(L, "%s", strerror(errno));
|
||||||
if (sucess) return 1;
|
if (sucess) return 1;
|
||||||
else { /* EOF */
|
else { /* EOF */
|
||||||
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
|
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
|
||||||
|
@ -439,6 +464,7 @@ static const luaL_reg iolib[] = {
|
||||||
{"close", io_close},
|
{"close", io_close},
|
||||||
{"flush", io_flush},
|
{"flush", io_flush},
|
||||||
{"open", io_open},
|
{"open", io_open},
|
||||||
|
{"popen", io_popen},
|
||||||
{"read", io_read},
|
{"read", io_read},
|
||||||
{"tmpfile", io_tmpfile},
|
{"tmpfile", io_tmpfile},
|
||||||
{"type", io_type},
|
{"type", io_type},
|
||||||
|
@ -469,30 +495,37 @@ static void createmeta (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void createupval (lua_State *L) {
|
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
|
||||||
lua_newtable(L);
|
*newfile(L) = f;
|
||||||
/* create (and set) default files */
|
if (k > 0) {
|
||||||
*newfile(L) = stdin;
|
lua_pushvalue(L, -1);
|
||||||
lua_rawseti(L, -2, IO_INPUT);
|
lua_rawseti(L, LUA_ENVIRONINDEX, k);
|
||||||
*newfile(L) = stdout;
|
}
|
||||||
lua_rawseti(L, -2, IO_OUTPUT);
|
lua_setfield(L, -2, fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LUALIB_API int luaopen_io (lua_State *L) {
|
LUALIB_API int luaopen_io (lua_State *L) {
|
||||||
createmeta(L);
|
createmeta(L);
|
||||||
createupval(L);
|
/* create new (private) environment */
|
||||||
lua_pushvalue(L, -1);
|
lua_newtable(L);
|
||||||
lua_replace(L, LUA_ENVIRONINDEX);
|
lua_replace(L, LUA_ENVIRONINDEX);
|
||||||
|
/* open library */
|
||||||
luaL_openlib(L, LUA_IOLIBNAME, iolib, 0);
|
luaL_openlib(L, LUA_IOLIBNAME, iolib, 0);
|
||||||
/* put predefined file handles into `io' table */
|
/* create (and set) default files */
|
||||||
lua_rawgeti(L, -2, IO_INPUT); /* get current input from upval */
|
createstdfile(L, stdin, IO_INPUT, "stdin");
|
||||||
lua_setfield(L, -2, "stdin"); /* io.stdin = upval[IO_INPUT] */
|
createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
||||||
lua_rawgeti(L, -2, IO_OUTPUT); /* get current output from upval */
|
createstdfile(L, stderr, 0, "stderr");
|
||||||
lua_setfield(L, -2, "stdout"); /* io.stdout = upval[IO_OUTPUT] */
|
/* create environment for 'popen' */
|
||||||
*newfile(L) = stderr;
|
lua_getfield(L, -1, "popen");
|
||||||
lua_setfield(L, -2, "stderr"); /* io.stderr = newfile(stderr) */
|
lua_newtable(L);
|
||||||
|
lua_pushcfunction(L, io_pclose);
|
||||||
|
lua_setfield(L, -2, "__close");
|
||||||
|
lua_setfenv(L, -2);
|
||||||
|
lua_pop(L, 1); /* pop 'popen' */
|
||||||
|
/* set default close function */
|
||||||
|
lua_pushcfunction(L, io_fclose);
|
||||||
|
lua_setfield(L, LUA_ENVIRONINDEX, "__close");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue