diff --git a/lualib/bootstrap.lua b/lualib/bootstrap.lua index cb41689..93e427f 100644 --- a/lualib/bootstrap.lua +++ b/lualib/bootstrap.lua @@ -32,8 +32,11 @@ local function start(config) end local function wait(ctx) - boot.wait(ctx) + local exitcode = boot.wait(ctx) boot.deinit() + if exitcode ~= 0 then + os.exit(exitcode, true) + end end return { diff --git a/service/root.lua b/service/root.lua index 80e4172..d362d7d 100644 --- a/service/root.lua +++ b/service/root.lua @@ -14,6 +14,8 @@ local RECEIPT_ERROR = 2 local RECEIPT_BLOCK = 3 local RECEIPT_RESPONSE = 4 +local EXIT_CODE_ERROR = 1 + local S = {} local anonymous_services = {} @@ -42,6 +44,7 @@ do if type == MESSAGE_ERROR then ltask.log.error("Root fatal:", table.concat(errobj, "\n")) writelog() + root.set_exit_code(EXIT_CODE_ERROR) root_quit() end end diff --git a/src/ltask.c b/src/ltask.c index 6402d6c..c36b821 100644 --- a/src/ltask.c +++ b/src/ltask.c @@ -106,6 +106,7 @@ struct ltask { atomic_int thread_count; int blocked_service; // binding service may block FILE *logfile; + int exit_code; // process exit code, set by root service }; struct service_ud { @@ -974,8 +975,10 @@ ltask_wait(lua_State *L) { } message_delete(ctx->task->external_last_message); queue_delete(ctx->task->external_message); + int exit_code = ctx->task->exit_code; mainthread_deinit(&ctx->task->mt); - return 0; + lua_pushinteger(L, exit_code); + return 1; } static int @@ -1735,6 +1738,14 @@ lmainthread_yield(lua_State *L) { return mainthread_change_status(L, MAINTHREAD_STATUS_YIELD); } +static int +ltask_set_exit_code(lua_State *L) { + const struct service_ud *S = getS(L); + int code = (int)luaL_checkinteger(L, 1); + S->task->exit_code = code; + return 0; +} + LUAMOD_API int luaopen_ltask(lua_State *L) { luaL_checkversion(L); @@ -1881,6 +1892,7 @@ luaopen_ltask_root(lua_State *L) { luaL_Reg l[] = { { "init_service", ltask_initservice }, { "close_service", ltask_closeservice }, + { "set_exit_code", ltask_set_exit_code }, { NULL, NULL }, };