hokey primitive to create temporary file
The trouble with os.tmpname() is that it always creates in /tmp. If /tmp is in a different volume from our real filename, os.rename() will fail. This new primitive doesn't support primitive paths yet. I'm also again nervous about the security implications of my whole approach. What if we create an inner function called start_writing? Would we be able to do anything inside it? I'm starting to suspect this whole approach of going by caller name is broken. An app could also create inner functions called 'main'..
This commit is contained in:
parent
88827db20d
commit
a0674f7b85
24
src/file.lua
24
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()
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue