about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-12-25 11:35:50 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-12-25 11:35:50 -0800
commit1e63a579d72a76baf56239e76528ddd4d08d797c (patch)
tree9c4765c0bd15449fce03c135ce232f523074752d
parent5c1bf1aaff9d7a74e836f4c96532fa4908cc72a7 (diff)
downloadteliva-1e63a579d72a76baf56239e76528ddd4d08d797c.tar.gz
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.
-rw-r--r--README.md5
-rw-r--r--src/liolib.c128
2 files changed, 18 insertions, 115 deletions
diff --git a/README.md b/README.md
index 26581d3..1773ac1 100644
--- a/README.md
+++ b/README.md
@@ -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).
 
diff --git a/src/liolib.c b/src/liolib.c
index 04f102b..6092cac 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -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) {
@@ -93,16 +86,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
 */
 static int io_fclose (lua_State *L) {
@@ -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;
 }