sys.run()/run_rc() discard io.popen() handle's close() exit status #58

Open
opened 2026-08-16 10:24:55 +02:00 by michael · 0 comments
Owner

Problem

sys.lua's run() and run_rc() both discard the return value of
p:close():

function self:run(cmd)
  local p, err = io.popen("LANG=C " .. cmd .. " 2>/dev/null")
  if not p then
    return nil, fail(...)
  end
  local out = p:read("*a")
  p:close()
  ...
function self:run_rc(cmd)
  ...
  local p, err = io.popen(full)
  if not p then
    return nil, fail(...)
  end
  local out = p:read("*a")
  p:close()
  ...

For a popen() handle, close()'s return value reports the
underlying process's exit status (similar to pclose()). This is
particularly relevant for run(), whose public contract only ever
returns stdout -- a command that fails (non-zero exit) but still
produces some stdout output currently returns that stdout as success,
with no way for the caller to detect the failure.

run_rc() already captures the exit code explicitly via the
printf ... $? marker trick, so this is less pressing there, but
close()'s own result is still unchecked/unused in both functions.

Found while reviewing the daw_i18n/v1 migration of sys.lua
(DAW/daw-lua-common#48). Not an i18n issue, out of scope for #48.

Scope

  • Decide whether run()'s contract should change to surface a non-zero
    exit status (this would be a behavior/API change, needs discussion)
  • Decide whether run_rc()'s unused close() result needs any handling
    given it already has the exit code from the marker

DAW/daw-lua-common#48

## Problem `sys.lua`'s `run()` and `run_rc()` both discard the return value of `p:close()`: ```lua function self:run(cmd) local p, err = io.popen("LANG=C " .. cmd .. " 2>/dev/null") if not p then return nil, fail(...) end local out = p:read("*a") p:close() ... ``` ```lua function self:run_rc(cmd) ... local p, err = io.popen(full) if not p then return nil, fail(...) end local out = p:read("*a") p:close() ... ``` For a `popen()` handle, `close()`'s return value reports the underlying process's exit status (similar to `pclose()`). This is particularly relevant for `run()`, whose public contract only ever returns stdout -- a command that fails (non-zero exit) but still produces some stdout output currently returns that stdout as success, with no way for the caller to detect the failure. `run_rc()` already captures the exit code explicitly via the `printf ... $?` marker trick, so this is less pressing there, but `close()`'s own result is still unchecked/unused in both functions. Found while reviewing the daw_i18n/v1 migration of sys.lua (DAW/daw-lua-common#48). Not an i18n issue, out of scope for #48. ## Scope - Decide whether run()'s contract should change to surface a non-zero exit status (this would be a behavior/API change, needs discussion) - Decide whether run_rc()'s unused close() result needs any handling given it already has the exit code from the marker ## Related DAW/daw-lua-common#48
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
DAW/daw-lua-common#58
No description provided.