diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/file.lua | 45 | ||||
-rw-r--r-- | src/lua.c | 2 |
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; |