Skip to content

Commit

Permalink
red: use non blocking read
Browse files Browse the repository at this point in the history
  • Loading branch information
hugeping committed Apr 25, 2024
1 parent 45085d8 commit 15c9154
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
9 changes: 8 additions & 1 deletion data/lib/red/posix.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
local posix = { sighup = function() end }
local posix = { sighup = function() end, nonblock = function() end, poll = function() return true, true end }

if PLATFORM == 'Windows' or type(jit) ~= 'table' then
return posix
end

posix.have_poll = true

local ffi = require "ffi"
ffi.cdef[[
unsigned long signal(int signum, unsigned long);
Expand All @@ -14,12 +16,17 @@ ffi.cdef[[
};
int fileno(struct FILE* stream);
int poll(struct pollfd *fds, unsigned long nfds, int timeout);
int fcntl(int fd, int cmd, int arg);
]]

function posix.sighup(on)
ffi.C.signal(13, on and 0 or 1) -- SIGPIPE, SIG_IGN
end

function posix.nonblock(f, on)
ffi.C.fcntl(ffi.C.fileno(f), 4, on and 2048 or 0)
end

function posix.poll(f)
local fds = ffi.new("struct pollfd[1]")
fds[0].fd = ffi.C.fileno(f)
Expand Down
11 changes: 8 additions & 3 deletions data/lib/red/shell.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ local shell = {}
local function pipe_shell()
local posix = require("red/posix")
local poll, sighup = posix.poll, posix.sighup
local poll_mode = not not poll
poll = poll or function() return true end
local poll_mode = posix.have_poll
local function read_sym(f)
local t = {}
while true do
Expand Down Expand Up @@ -46,7 +45,9 @@ end

local function pipe_proc()
require "std"
local sighup = require("red/posix").sighup
local posix = require("red/posix")
local sighup, nonblock = posix.sighup, posix.nonblock

local prog, cwd = thread:read()
if cwd and PLATFORM ~= 'Windows' then
prog = string.format("cd %q && %s", cwd, prog)
Expand All @@ -58,7 +59,10 @@ local function pipe_proc()
if not f then return end
f:setvbuf 'no'
local pre
nonblock(f, true)
while true do
local _, ok = posix.poll(f)
if not ok then break end
local chunk = f:read(512)
if not chunk then
if pre then
Expand All @@ -76,6 +80,7 @@ local function pipe_proc()
thread:write(l)
end
end
nonblock(f, false)
f:close()
thread:write '\1eof'
end
Expand Down

0 comments on commit 15c9154

Please sign in to comment.