~schnouki/pustule

1525927e8eaf01c6f58e6f7439457e08fedb317c — Thomas Jost 9 months ago f0a1e93
Don't let Lua errors crash pustule itself

Use protected calls and log errors instead.
3 files changed, 28 insertions(+), 4 deletions(-)

M events.c
M lua_mod.c
M pustule.h
M events.c => events.c +8 -4
@@ 43,7 43,8 @@ static void handle_input_added(pustule_input_event_t* iev) {
        lua_rawgeti(g_L, LUA_REGISTRYINDEX, cb_ref);  // Push callback to the stack
        lua_pushinteger(g_L, iev->index);  // Push 1st argument (index) to the stack
        pustule_push_input_event(g_L, iev);  // Push 2nd argument (event table) to the stack
        lua_call(g_L, 2, 0);  // Call the function with 2 arguments and no result
        int res = lua_pcall(g_L, 2, 0, 0);  // Call the function with 2 arguments and no result
        check_pcall_error(g_L, res);
    }
}
static void handle_input_removed(pustule_input_event_t* iev) {


@@ 56,7 57,8 @@ static void handle_input_removed(pustule_input_event_t* iev) {

        lua_rawgeti(g_L, LUA_REGISTRYINDEX, cb_ref);  // Push callback to the stack
        lua_pushinteger(g_L, iev->index);  // Push 1st argument (index) to the stack
        lua_call(g_L, 1, 0);  // Call the function with 1 argument and no result
        int res = lua_pcall(g_L, 1, 0, 0);  // Call the function with 1 argument and no result
        check_pcall_error(g_L, res);
    }
}



@@ 71,7 73,8 @@ static void handle_device_added(pustule_device_event_t* dev) {
        lua_rawgeti(g_L, LUA_REGISTRYINDEX, cb_ref);  // Push callback to the stack
        lua_pushinteger(g_L, dev->index);  // Push 1st argument (index) to the stack
        pustule_push_device_event(g_L, dev);  // Push 2nd argument (event table) to the stack
        lua_call(g_L, 2, 0);  // Call the function with 2 arguments and no result
        int res = lua_pcall(g_L, 2, 0, 0);  // Call the function with 2 arguments and no result
        check_pcall_error(g_L, res);
    }
}
static void handle_device_removed(pustule_device_event_t* dev) {


@@ 84,7 87,8 @@ static void handle_device_removed(pustule_device_event_t* dev) {

        lua_rawgeti(g_L, LUA_REGISTRYINDEX, cb_ref);  // Push callback to the stack
        lua_pushinteger(g_L, dev->index);  // Push 1st argument (index) to the stack
        lua_call(g_L, 1, 0);  // Call the function with 1 argument and no result
        int res = lua_pcall(g_L, 1, 0, 0);  // Call the function with 1 argument and no result
        check_pcall_error(g_L, res);
    }
}


M lua_mod.c => lua_mod.c +19 -0
@@ 59,6 59,25 @@ void _dump_stack (lua_State *L) {
    printf("\n");
}

/* Helper for protected calls */
bool check_pcall_error(lua_State* L, int res) {
    if (res == LUA_OK)
        return false;

    const char* msg = lua_tostring(L, -1);
    if (res == LUA_ERRRUN) {
        log_warn("Lua runtime error: %s", msg);
        return true;
    }

    char* type = "unknown error";
    if (res == LUA_ERRMEM) type = "memory error";
    else if (res == LUA_ERRERR) type = "message handler error";
    else if (res == LUA_ERRGCMM) type = "__gc error";
    log_error("Lua %s: %s", type, msg);
    return true;
}

/* Signal listeners */
lua_State* g_L;
array_t input_added_listeners;

M pustule.h => pustule.h +1 -0
@@ 117,6 117,7 @@ int pustule_suspend_device(lua_State* L);
/* Lua helpers */
void pustule_push_input_event(lua_State* L, pustule_input_event_t* event);
void pustule_push_device_event(lua_State* L, pustule_device_event_t* event);
bool check_pcall_error(lua_State* L, int res);

/* Pustule event loop */
void pustule_handle_event(pustule_event_t* event);