Skip to content

Commit

Permalink
lib: move non-raw processing into lua
Browse files Browse the repository at this point in the history
This fixes logging so that we actually log the control characters used, and
we can distinguish between a control character that was actually sent and
one that was escaped.

Signed-off-by: Kyle Evans <[email protected]>
  • Loading branch information
kevans91 committed Feb 10, 2024
1 parent 25400a9 commit 9a0fe10
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 73 deletions.
74 changes: 2 additions & 72 deletions lib/core/orch_lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ orchlua_spawn(lua_State *L)
proc->term = NULL;
proc->status = 0;
proc->pid = 0;
proc->buffered = proc->eof = proc->raw = proc->released = false;
proc->buffered = proc->eof = proc->released = false;
proc->error = false;

luaL_setmetatable(L, ORCHLUA_PROCESSHANDLE);
Expand Down Expand Up @@ -583,7 +583,7 @@ orchlua_process_write(lua_State *L)
struct orch_process *self;
const char *buf;
char *processed;
size_t bufsz, procsz, totalsz;
size_t bufsz, totalsz;
ssize_t writesz;
int fd;
bool quoted;
Expand All @@ -593,67 +593,13 @@ orchlua_process_write(lua_State *L)
processed = NULL;
quoted = false;

if (self->raw)
goto sendit;

processed = malloc(bufsz);
if (processed == NULL) {
luaL_pushfail(L);
lua_pushstring(L, strerror(ENOMEM));
return (2);
}

procsz = 0;

/*
* If we're not in raw mode, we process some sequences that would not
* normally be processed.
*/
for (size_t i = 0; i < bufsz; i++) {
char c, esc;

c = buf[i];
if (quoted) {
quoted = false;
processed[procsz++] = c;
continue;
}

switch (c) {
case '^':
if (i == bufsz - 1) {
free(processed);
luaL_pushfail(L);
lua_pushstring(L,
"Incomplete CNTRL character at end of buffer");
return (2);
}

esc = buf[i + 1];
if (esc < 0x40 /* @ */ || esc > 0x5f /* _ */) {
free(processed);
luaL_pushfail(L);
lua_pushfstring(L, "Invalid escape of '%c'", esc);
return (2);
}

processed[procsz++] = esc - 0x40;

/* Eat the next character. */
i++;
break;
case '\\':
quoted = true;
break;
default:
processed[procsz++] = c;
break;
}
}

buf = processed;
bufsz = procsz;
sendit:
fd = self->termctl;
totalsz = 0;
while (totalsz < bufsz) {
Expand All @@ -677,21 +623,6 @@ orchlua_process_write(lua_State *L)
return (1);
}

static int
orchlua_process_raw(lua_State *L)
{
struct orch_process *self;
bool wasraw;

self = luaL_checkudata(L, 1, ORCHLUA_PROCESSHANDLE);
wasraw = self->raw;
if (lua_gettop(L) > 1)
self->raw = lua_toboolean(L, 2);

lua_pushboolean(L, wasraw);
return (1);
}

static int
orchlua_process_release(lua_State *L)
{
Expand Down Expand Up @@ -842,7 +773,6 @@ static const luaL_Reg orchlua_process[] = {
PROCESS_SIMPLE(close),
PROCESS_SIMPLE(read),
PROCESS_SIMPLE(write),
PROCESS_SIMPLE(raw),
PROCESS_SIMPLE(release),
PROCESS_SIMPLE(released),
PROCESS_SIMPLE(term),
Expand Down
38 changes: 37 additions & 1 deletion lib/orch/process.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ function Process:new(cmd, ctx)
pwrap._process = assert(core.spawn(table.unpack(cmd)))
pwrap.buffer = MatchBuffer:new(pwrap, ctx)
pwrap.ctx = ctx
pwrap.is_raw = false

pwrap.term = assert(pwrap._process:term())
local mask = pwrap.term:fetch("lflag")
Expand All @@ -116,10 +117,45 @@ function Process:read(func, timeout)
end
end
function Process:raw(is_raw)
local prev_raw = self.is_raw
self.is_raw = is_raw
return self._process:raw(is_raw)
return prev_raw
end
function Process:write(data)
if not self.is_raw then
-- Convert ^[A-Z] -> cntrl sequence
local quoted = false
for i = 1, #data do
if i > #data then
break
end

local ch = data:sub(i, i)

if quoted then
quoted = false
elseif ch == "\\" then
quoted = true
data = data:sub(1, i - 1) .. data:sub(i + 1)
elseif ch == "^" then
if did_quote then
error("Huh")
end
if i == #data then
error("Incomplete CNTRL character at end of buffer")
end

local esch = data:sub(i + 1, i + 1)
local esc = string.byte(esch)
if esc < 0x40 or esc > 0x5f then
error("Invalid escape of '" .. esch .. "'")
end

esch = string.char(esc - 0x40)
data = data:sub(1, i - 1) .. esch .. data:sub(i + 2)
end
end
end
if self.log then
self.log:write(data)
end
Expand Down

0 comments on commit 9a0fe10

Please sign in to comment.