about summary refs log tree commit diff stats
path: root/src/file.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/file.lua')
-rw-r--r--src/file.lua24
1 files changed, 23 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()