X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Flua.c;h=3f48a55dee5e122e042b38e550d2e26434f828d6;hb=d931e9e904f61e28013c01ee6903985d3c9f0ba8;hp=b5d3ce54c902b26b2e5ab99debe921605effe341;hpb=1fe028d387704d46ef777a3f47168baa2262ef78;p=collectd.git diff --git a/src/lua.c b/src/lua.c index b5d3ce54..3f48a55d 100644 --- a/src/lua.c +++ b/src/lua.c @@ -40,6 +40,9 @@ #include +#define PLUGIN_READ 1 +#define PLUGIN_WRITE 2 + typedef struct lua_script_s { lua_State *lua_state; struct lua_script_s *next; @@ -265,62 +268,39 @@ static void lua_cb_free(void *data) { free(cb); } -static int lua_cb_register_read(lua_State *L) /* {{{ */ +static int lua_cb_register_generic(lua_State *L, int type) /* {{{ */ { int nargs = lua_gettop(L); if (nargs != 1) return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs); - luaL_checktype(L, 1, LUA_TFUNCTION); - - char function_name[DATA_MAX_NAME_LEN]; - snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1)); - - int callback_id = clua_store_callback(L, 1); - if (callback_id < 0) - return luaL_error(L, "%s", "Storing callback function failed"); - - lua_State *thread = lua_newthread(L); - if (thread == NULL) - return luaL_error(L, "%s", "lua_newthread failed"); - clua_store_thread(L, -1); - lua_pop(L, 1); - - clua_callback_data_t *cb = calloc(1, sizeof(*cb)); - if (cb == NULL) - return luaL_error(L, "%s", "calloc failed"); - - cb->lua_state = thread; - cb->callback_id = callback_id; - cb->lua_function_name = strdup(function_name); - pthread_mutex_init(&cb->lock, NULL); + char subname[DATA_MAX_NAME_LEN]; + if (!lua_isfunction(L, 1) && lua_isstring(L, 1)) { + const char *fname = lua_tostring(L, 1); + ssnprintf(subname, sizeof(subname), "%s()", fname); - int status = - plugin_register_complex_read(/* group = */ "lua", - /* name = */ function_name, - /* callback = */ clua_read, - /* interval = */ 0, - &(user_data_t){ - .data = cb, .free_func = lua_cb_free, - }); - - if (status != 0) - return luaL_error(L, "%s", "plugin_register_complex_read failed"); - return 0; -} /* }}} int lua_cb_register_read */ - -static int lua_cb_register_write(lua_State *L) /* {{{ */ -{ - int nargs = lua_gettop(L); - - if (nargs != 1) - return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs); + lua_getglobal(L, fname); // Push function into stack + lua_remove(L, 1); // Remove string from stack + if (!lua_isfunction(L, -1)) { + return luaL_error(L, "Unable to find function '%s'", fname); + } + } else { + lua_getfield(L, LUA_REGISTRYINDEX, "collectd:callback_num"); + int tmp = lua_tointeger(L, -1); + ssnprintf(subname, sizeof(subname), "callback_%d", tmp); + lua_pop(L, 1); // Remove old value from stack + lua_pushinteger(L, tmp + 1); + lua_setfield(L, LUA_REGISTRYINDEX, "collectd:callback_num"); // pops value + } luaL_checktype(L, 1, LUA_TFUNCTION); - char function_name[DATA_MAX_NAME_LEN] = ""; - snprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1)); + lua_getfield(L, LUA_REGISTRYINDEX, "collectd:script_path"); + char function_name[DATA_MAX_NAME_LEN]; + ssnprintf(function_name, sizeof(function_name), "lua/%s/%s", + lua_tostring(L, -1), subname); + lua_pop(L, 1); int callback_id = clua_store_callback(L, 1); if (callback_id < 0) @@ -341,16 +321,42 @@ static int lua_cb_register_write(lua_State *L) /* {{{ */ cb->lua_function_name = strdup(function_name); pthread_mutex_init(&cb->lock, NULL); - int status = plugin_register_write(/* name = */ function_name, - /* callback = */ clua_write, - &(user_data_t){ - .data = cb, .free_func = lua_cb_free, - }); + if (PLUGIN_READ == type) { + int status = plugin_register_complex_read(/* group = */ "lua", + /* name = */ function_name, + /* callback = */ clua_read, + /* interval = */ 0, + &(user_data_t){ + .data = cb, + .free_func = lua_cb_free, + }); + + if (status != 0) + return luaL_error(L, "%s", "plugin_register_complex_read failed"); + return 0; + } else if (PLUGIN_WRITE == type) { + int status = plugin_register_write(/* name = */ function_name, + /* callback = */ clua_write, + &(user_data_t){ + .data = cb, + .free_func = lua_cb_free, + }); + + if (status != 0) + return luaL_error(L, "%s", "plugin_register_write failed"); + return 0; + } else { + return luaL_error(L, "%s", "lua_cb_register_generic unsupported type"); + } +} /* }}} int lua_cb_register_generic */ - if (status != 0) - return luaL_error(L, "%s", "plugin_register_write failed"); - return 0; -} /* }}} int lua_cb_register_write */ +static int lua_cb_register_read(lua_State *L) { + return lua_cb_register_generic(L, PLUGIN_READ); +} + +static int lua_cb_register_write(lua_State *L) { + return lua_cb_register_generic(L, PLUGIN_WRITE); +} static const luaL_Reg collectdlib[] = { {"log_debug", lua_cb_log_debug}, @@ -457,6 +463,11 @@ static int lua_script_load(const char *script_path) /* {{{ */ return -1; } + lua_pushstring(script->lua_state, script_path); + lua_setfield(script->lua_state, LUA_REGISTRYINDEX, "collectd:script_path"); + lua_pushinteger(script->lua_state, 0); + lua_setfield(script->lua_state, LUA_REGISTRYINDEX, "collectd:callback_num"); + status = lua_pcall(script->lua_state, /* nargs = */ 0, /* nresults = */ LUA_MULTRET, @@ -469,8 +480,8 @@ static int lua_script_load(const char *script_path) /* {{{ */ "In addition, no error message could be retrieved from the stack.", status); else - ERROR("Lua plugin: Executing script \"%s\" failed:\n%s", - script_path, errmsg); + ERROR("Lua plugin: Executing script \"%s\" failed: %s", script_path, + errmsg); } /* Append this script to the global list of scripts. */ @@ -520,7 +531,7 @@ static int lua_config_script(const oconfig_item_t *ci) /* {{{ */ if (base_path[0] == '\0') sstrncpy(abs_path, rel_path, sizeof(abs_path)); else - snprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path); + ssnprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path); DEBUG("Lua plugin: abs_path = \"%s\";", abs_path);