drop stdin/stdout/stderr and Lua default files

This isn't necessarily for sandboxing, but they don't really work right
now in the presence of ncurses, and it seems better to not include
broken stuff. Maybe we can get them to coexist with ncurses down the
road.
This commit is contained in:
Kartik K. Agaram 2021-12-25 11:35:50 -08:00
parent 5c1bf1aaff
commit 1e63a579d7
2 changed files with 18 additions and 115 deletions

View File

@ -132,6 +132,11 @@ libraries. However, a few things are different from conventional Lua:
effectively:
- `os.execute`
- `io.popen`
* Some functions are disabled because they don't seem to make sense in an
ncurses environment. This includes the Lua notions of default files, which
start out as stdin/stdout.
- `io.input`, `io.read`
- `io.output`, `io.write`, `io.flush`
* Some functions in lcurses have [additional smarts](https://github.com/lcurses/lcurses/blob/master/lib/curses.lua).
Teliva is [consistent with the underlying ncurses](https://github.com/akkartik/teliva/blob/main/src/lcurses/curses.lua).

View File

@ -20,13 +20,6 @@
#define IO_INPUT 1
#define IO_OUTPUT 2
static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
@ -92,16 +85,6 @@ static FILE **newfile (lua_State *L) {
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
/*
** function to close regular files
*/
@ -121,8 +104,6 @@ static int aux_close (lua_State *L) {
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}
@ -163,47 +144,6 @@ static int io_tmpfile (lua_State *L) {
}
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
}
static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename) {
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
if (*pf == NULL)
fileerror(L, 1, filename);
}
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, "w");
}
static int io_readline (lua_State *L);
@ -222,20 +162,13 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
else {
const char *filename = luaL_checkstring(L, 1);
FILE **pf = newfile(L);
*pf = fopen(filename, "r");
if (*pf == NULL)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
return 1;
}
const char *filename = luaL_checkstring(L, 1);
FILE **pf = newfile(L);
*pf = fopen(filename, "r");
if (*pf == NULL)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
return 1;
}
@ -354,11 +287,6 @@ static int g_read (lua_State *L, FILE *f, int first) {
}
static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
@ -405,11 +333,6 @@ static int g_write (lua_State *L, FILE *f, int arg) {
}
static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}
@ -442,12 +365,6 @@ static int f_setvbuf (lua_State *L) {
}
static int io_flush (lua_State *L) {
return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
@ -455,16 +372,16 @@ static int f_flush (lua_State *L) {
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
/* no 'flush' since Teliva is ncurses-based */
/* no 'input' since Teliva is ncurses-based */
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
/* no popen without sandboxing it */
{"read", io_read},
/* no 'output' since Teliva is ncurses-based */
/* no 'popen' without sandboxing it */
/* no 'read' since Teliva is ncurses-based */
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
/* no 'write' since Teliva is ncurses-based */
{NULL, NULL}
};
@ -491,18 +408,6 @@ static void createmeta (lua_State *L) {
}
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
}
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
@ -512,17 +417,10 @@ static void newfenv (lua_State *L, lua_CFunction cls) {
LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
lua_pop(L, 1); /* pop environment for default files */
return 1;
}