Verified Commit 186882a1 authored by Karel Koci's avatar Karel Koci 🤘
Browse files

Export subprocess function to lua

parent 64718709
......@@ -21,6 +21,7 @@
#include "util.h"
#include "logging.h"
#include "events.h"
#include "subprocess.h"
#include "journal.h"
#include "locks.h"
#include "arguments.h"
......@@ -452,6 +453,31 @@ static int lua_cleanup_unregister_handle(lua_State *L) {
return 0;
static int lua_subprocess(lua_State *L) {
enum log_subproc_type type = (enum log_subproc_type)luaL_checkinteger(L, 1);
// TODO verify type?
const char *message = luaL_checkstring(L, 2);
int timeout = luaL_checkinteger(L, 3);
const char *command = luaL_checkstring(L, 4);
int ec;
char *output;
if (lua_gettop(L) > 4) {
const char *args[lua_gettop(L) - 4];
for (int i = 5; i <= lua_gettop(L); i++)
args[i - 5] = luaL_checkstring(L, i);
args[lua_gettop(L) - 4] = NULL;
ec = lsubprocl(type, message, &output, timeout, command, args);
} else {
ec = lsubprocv(type, message, &output, timeout, command, NULL);
lua_pushinteger(L, ec);
lua_pushstring(L, output);
return 2;
static int lua_mkdtemp(lua_State *L) {
int param_count = lua_gettop(L);
if (param_count > 1)
......@@ -845,6 +871,7 @@ static const struct injected_func injected_funcs[] = {
* manage the dynamically allocated memory correctly and there doesn't
* seem to be a need for them at this moment.
{ lua_subprocess, "subprocess" },
{ lua_mkdtemp, "mkdtemp" },
{ lua_chdir, "chdir" },
{ lua_getcwd, "getcwd" },
......@@ -882,7 +909,9 @@ struct {
// Various enum values that we want to inject
......@@ -86,6 +86,33 @@ cleanup_unregister_handle(index)::
this cleanup in global table of cleanup functions. It reverse function or
Family of functions ``subproc*`` defined in ``subprocess.h`` are exported to lua
in form of function `subproc`.
Function `subprocess` is defined as follows:
`suboprocess(type, message, timeout, command ...)`
`type` is identification used to specify what type of subprocess it's. Allowed
predefined constants are as follows:
-- `LST_PKG_SCRIPT` Any script provided by package (pre/post inst/rm)
-- `LST_HOOK` Hook script executed on some updater state
`message` is string describing what this subprocess is to user. It's human
readable description of executed command.
`timeout` is time in seconds after which subprocess will be automatically
`command` is any arbitrary number of string arguments that are passed as command
and its additional arguments.
This function returns exit code of executed subprocess as first argument. And
output of this process as second argument. (Output includes both stdout and
Asynchronous events
......@@ -15,6 +15,7 @@ C_TESTS := \
backend \
events \
subprocess \
interpreter \
journal \
planner \
Copyright 2018, CZ.NIC z.s.p.o. (
This file is part of the turris updater.
Updater is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Updater is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Updater. If not, see <>.
require 'lunit'
module("subproc", package.seeall, lunit.testcase)
function test_exit_code()
local ok, out = subprocess(LST_HOOK, "Test: true", 1, "true")
assert_equal(0, ok)
assert_equal("", out)
local ok, out = subprocess(LST_HOOK, "Test: false", 1, "false")
assert_not_equal(0, ok)
assert_equal("", out)
function test_output()
local ok, out = subprocess(LST_HOOK, "Test: echo", 1, "echo", "hello")
assert_equal(0, ok)
assert_equal("hello\n", out)
local ok, out = subprocess(LST_HOOK, "Test: echo stderr", 1, "sh", "-c", "echo hello >&2")
assert_equal(0, ok)
assert_equal("hello\n", out)
function test_timeout()
local ok, out = subprocess(LST_HOOK, "Test: sleep", 1, "sleep", "2")
assert_not_equal(0, ok)
assert_equal("", out)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment