diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-11-28 09:50:00 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-11-28 10:44:40 -0800 |
commit | 6388bc08c46c096b3df91a5deddd2ac740cd6d38 (patch) | |
tree | 0d062e5b0c00fc6fa645ed3c5621564778c9947c | |
parent | 13bfb7308a28d854c9a4685e99bf9d7ea2b2e20d (diff) | |
download | teliva-6388bc08c46c096b3df91a5deddd2ac740cd6d38.tar.gz |
save a snapshot of editor state across restarts
We're not using this yet. I agonized over this decision for several weeks. Is Teliva's need to restart with execve an utter hack or a good thing? I'm leaning towards the latter. Constantly exercising the initial flow makes Teliva more crash-only. We can build Steve Yegge's idea of immortality (http://steve-yegge.blogspot.com/2007/01/pinocchio-problem.html) out of crash-only primitives, just by making reboots instantaneous. But focusing directly on immortality tends to compromise crash-only by exercising it more rarely. One other issue this brings up: loading these Lua tables from disk is a vector for arbitrary code execution. I need to fix these when I get to sandboxing.
-rw-r--r-- | src/kilo.c | 2 | ||||
-rw-r--r-- | src/lua.c | 13 |
2 files changed, 14 insertions, 1 deletions
diff --git a/src/kilo.c b/src/kilo.c index b2f9a18..45d10c4 100644 --- a/src/kilo.c +++ b/src/kilo.c @@ -1033,6 +1033,7 @@ static void editorGo(lua_State* L) { * is typing stuff on the terminal. */ static int Quit = 0; static int Back_to_big_picture = 0; +extern void save_snapshot(int rowoff, int coloff, int cy, int cx); static void editorProcessKeypress(lua_State* L) { int c = getch(); switch(c) { @@ -1046,6 +1047,7 @@ static void editorProcessKeypress(lua_State* L) { case CTRL_E: /* Save and quit. */ editorSaveToDisk(); + save_snapshot(E.rowoff, E.coloff, E.cy, E.cx); Quit = 1; break; case CTRL_G: diff --git a/src/lua.c b/src/lua.c index 87a41fa..6035a62 100644 --- a/src/lua.c +++ b/src/lua.c @@ -398,6 +398,17 @@ static int handle_image (lua_State *L, char **argv, int n) { #define CURRENT_DEFINITION_LEN 256 char Current_definition[CURRENT_DEFINITION_LEN+1] = {0}; + +void save_snapshot (int rowoff, int coloff, int cy, int cx) { + FILE *out = fopen("teliva_snapshot", "w"); + fprintf(out, "__teliva_snapshot = {\n"); + fprintf(out, " image = \"%s\", definition = \"%s\",\n", Image_name, Current_definition); + fprintf(out, " rowoff = %d, coloff = %d,\n", rowoff, coloff); + fprintf(out, " cy = %d, cx = %d,\n", cy, cx); + fprintf(out, "}\n"); + fclose(out); +} + void save_to_current_definition_and_editor_buffer (lua_State *L, const char *definition) { strncpy(Current_definition, definition, CURRENT_DEFINITION_LEN); const char *contents = look_up_definition(L, Current_definition); @@ -444,7 +455,7 @@ static void save_image (lua_State *L) { lua_getglobal(L, "teliva_program"); int history_array = lua_gettop(L); int history_array_size = luaL_getn(L, history_array); - FILE* out = fopen(Image_name, "w"); + FILE *out = fopen(Image_name, "w"); fprintf(out, "teliva_program = {\n"); for (int i = 1; i <= history_array_size; ++i) { lua_rawgeti(L, history_array, i); |