about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/file.lua45
-rw-r--r--src/lua.c2
2 files changed, 47 insertions, 0 deletions
diff --git a/src/file.lua b/src/file.lua
new file mode 100644
index 0000000..faac0c3
--- /dev/null
+++ b/src/file.lua
@@ -0,0 +1,45 @@
+-- primitive for reading files from a file system (or, later, network)
+-- returns a channel or nil on error
+-- read lines from the channel using :recv()
+-- recv() on the channel will indicate end of file.
+function start_reading(fs, filename)
+  local result = task.Channel:new()
+  local infile = io.open(filename)
+  if infile == nil then return nil end
+  task.spawn(reading_task, infile, result)
+  return result
+end
+
+local function reading_task(infile, chanout)
+  for line in infile:lines() do
+    chanout:send(line)
+  end
+  chanout:send(nil)  -- eof
+end
+
+-- primitive for writing files to a file system (or, later, network)
+-- returns a channel or nil on error
+-- write to the channel using :send()
+-- indicate you're done writing by calling :close()
+-- file will not be externally visible until :close()
+function start_writing(fs, filename)
+  local result = task.Channel:new()
+  local initial_filename = os.tmpname()
+  local outfile = io.open(initial_filename, 'w')
+  if outfile == nil then return nil end
+  result.close = function()
+    result:send(nil)  -- end of file
+    outfile:close()
+    os.rename(initial_filename, filename)
+  end
+  task.spawn(writing_task, outfile, result)
+  return result
+end
+
+local function writing_task(outfile, chanin)
+  while true do
+    local line = chanin:recv()
+    if line == nil then break end  -- end of file
+    outfile:write(line)
+  end
+end
diff --git a/src/lua.c b/src/lua.c
index 11a1221..a553315 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -236,6 +236,8 @@ static int pmain (lua_State *L) {
   if (status != 0) return 0;
   status = dorequire(L, "src/task.lua", "task");
   if (status != 0) return 0;
+  status = dorequire(L, "src/file.lua", "file");
+  if (status != 0) return 0;
   lua_gc(L, LUA_GCRESTART, 0);
   s->status = handle_luainit(L);
   if (s->status != 0) return 0;