diff options
-rw-r--r-- | src/file.lua | 24 | ||||
-rw-r--r-- | src/liolib.c | 3 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/file.lua b/src/file.lua index cd71f50..17e543c 100644 --- a/src/file.lua +++ b/src/file.lua @@ -23,8 +23,11 @@ end -- indicate you're done writing by calling :close() -- file will not be externally visible until :close() function start_writing(fs, filename) + if filename == nil then + error('start_writing requires two arguments: a file-system (nil for real disk) and a filename') + end local result = task.Channel:new() - local initial_filename = os.tmpname() + local initial_filename = temporary_filename_in_same_volume(filename) local outfile = io.open(initial_filename, 'w') if outfile == nil then return nil end result.close = function() @@ -36,6 +39,25 @@ function start_writing(fs, filename) return result end +function temporary_filename_in_same_volume(filename) + -- opening in same directory will hopefully keep it on the same volume, + -- so that a future rename works + local i = 1 + while true do + temporary_filename = 'teliva_temp_'..filename..'_'..i + if io.open(temporary_filename) == nil then + -- file doesn't exist yet; create a placeholder and return it + local handle = io.open(temporary_filename, 'w') + if handle == nil then + error("this is unexpected; I can't create temporary files..") + end + handle:close() + return temporary_filename + end + i = i+1 + end +end + function writing_task(outfile, chanin) while true do local line = chanin:recv() diff --git a/src/liolib.c b/src/liolib.c index a1a5b35..a53d8e6 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -9,6 +9,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ncurses.h> #define liolib_c #define LUA_LIB @@ -139,6 +140,8 @@ static int io_open (lua_State *L) { const char *caller = get_caller(L); if (file_operation_permitted(caller, filename, mode)) *pf = fopen(filename, mode); + else if (is_equal(caller, "temporary_filename_in_same_volume")) + *pf = fopen(filename, mode); else if (is_equal(caller, "start_writing") || is_equal(caller, "start_reading")) { caller = get_caller_of_caller(L); if (file_operation_permitted(caller, filename, mode)) |