webmcp

annotate libraries/extos/pfilter.lua @ 482:87c87be92154

Improved memory efficiency of alternative extos.pfilter(...) implementation
author jbe
date Fri Jun 09 18:19:15 2017 +0200 (2017-06-09)
parents f704f35923e2
children
rev   line source
jbe@435 1 --[[
jbe@435 2
jbe@435 3 This file contains an alternative pfilter(...) implementation in pure Lua (utilizing moonbridge_io). This implementation is currently not used since extos already comes with a C implementation (extos.pfilter), which is independent of moonbridge_io and thus preferred to the implementation below.
jbe@435 4
jbe@435 5 data_out, -- string containing stdout data, or nil in case of error
jbe@435 6 data_err, -- string containing error or stderr data
jbe@435 7 status = -- exit code, or negative code in case of abnormal termination
jbe@435 8 pfilter(
jbe@435 9 data_in, -- string containing stdin data
jbe@435 10 filename, -- executable
jbe@435 11 arg1, -- first (non-zero) argument to executable
jbe@435 12 arg2, -- second argument to executable
jbe@435 13 ...
jbe@435 14 )
jbe@435 15
jbe@435 16 Executes the executable given by "filename", passing optional arguments. A given string may be fed into the program as stdin. On success 3 values are returned: A string containing all stdout data of the sub-process, a string containing all stderr data of the sub-process, and a status code. The status code is negative, if the program didn't terminate normally. By convention a status code of zero indicates success, while positive status codes indicate error conditions. If program execution was not possible at all, then nil is returned as first value and an error string as second value.
jbe@435 17
jbe@435 18 --]]
jbe@435 19
jbe@435 20 return function(data_in, ...)
jbe@435 21 local process, errmsg = moonbridge_io.exec(...)
jbe@435 22 if not process then return nil, errmsg end
jbe@435 23 local read_fds = {[process.stdout] = true, [process.stderr] = true}
jbe@435 24 local write_fds = {[process.stdin] = true}
jbe@435 25 local function read(socket, chunks)
jbe@435 26 if read_fds[socket] then
jbe@435 27 local chunk, status = socket:read_nb()
jbe@435 28 if not chunk then
jbe@435 29 socket:close()
jbe@435 30 read_fds[socket] = nil
jbe@435 31 else
jbe@482 32 if chunk ~= "" then
jbe@482 33 chunks[#chunks+1] = chunk
jbe@482 34 end
jbe@435 35 if status == "eof" then
jbe@435 36 socket:close()
jbe@435 37 read_fds[socket] = nil
jbe@435 38 end
jbe@435 39 end
jbe@435 40 end
jbe@435 41 end
jbe@435 42 local function write(...)
jbe@435 43 if write_fds[process.stdin] then
jbe@435 44 local buffered = process.stdin:flush_nb(...)
jbe@435 45 if not buffered or buffered == 0 then
jbe@435 46 process.stdin:close()
jbe@435 47 write_fds[process.stdin] = nil
jbe@435 48 end
jbe@435 49 end
jbe@435 50 end
jbe@435 51 write(data_in or "")
jbe@435 52 local stdout_chunks, stderr_chunks = {}, {}
jbe@435 53 while next(read_fds) or next(write_fds) do
jbe@435 54 moonbridge_io.poll(read_fds, write_fds)
jbe@435 55 read(process.stdout, stdout_chunks)
jbe@435 56 read(process.stderr, stderr_chunks)
jbe@435 57 write()
jbe@435 58 end
jbe@435 59 return
jbe@435 60 table.concat(stdout_chunks),
jbe@435 61 table.concat(stderr_chunks),
jbe@435 62 process:wait()
jbe@435 63 end
jbe@435 64

Impressum / About Us