static int lua_run_generic(lua_State *L, bool utils) { // Flush the lua output (it seems to buffered separately) do_flush(L, "stdout"); do_flush(L, "stderr"); // Extract the parameters. There's a lot of them. luaL_checktype(L, 1, LUA_TFUNCTION); int pf_cback_type = lua_type(L, 2); if (pf_cback_type != LUA_TNIL && pf_cback_type != LUA_TFUNCTION) return luaL_error(L, "The 2nd argument of run_command must be either function or nil"); if (!lua_isnil(L, 3) && !lua_isstring(L, 3)) return luaL_error(L, "The 3rd argument of run_command is a string input or nil"); int term_timeout = luaL_checkinteger(L, 4); int kill_timeout = luaL_checkinteger(L, 5); const char *cmd = luaL_checkstring(L, 6); struct log_buffer log; log_buffer_init(&log, LL_DBG); // The rest of the args are args for the command ‒ get them into an array const size_t arg_count = (size_t)lua_gettop(L) - 6; const char *args[arg_count + 1]; for (int i = 6; i < lua_gettop(L); i ++) { args[i - 6] = luaL_checkstring(L, i + 1); if (log.f) fprintf(log.f, "%s ", args[i - 6]); } args[arg_count] = NULL; if (log.f) { fclose(log.f); if (utils) { DBG("Util command: %s %s", cmd, log.char_buffer); } else DBG("Command: %s %s", cmd, log.char_buffer); free(log.char_buffer); } // Data for the callbacks. It will get freed there. struct lua_command_data *data = malloc(sizeof *data); data->L = L; data->terminated_callback = register_value(L, 1); data->postfork_callback = lua_isnil(L, 2) ? NULL : register_value(L, 2); struct events *events = extract_registry(L, "events"); ASSERT(events); size_t input_size = 0; const char *input = NULL; if (lua_isstring(L, 3)) input = lua_tolstring(L, 3, &input_size); struct wait_id id; if (utils) id = run_util_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, cmd, args); else id = run_command_a(events, command_terminated, command_postfork, data, input_size, input, term_timeout, kill_timeout, cmd, args); push_wid(L, &id); // Return 1 value ‒ the wait_id return 1; }
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); struct subprocess_callback_data callback_data = { .L = L, .callback = NULL }; // This can be on stack as we won't return while using this int cmd_index = 4; if (lua_isfunction(L, 4)) { callback_data.callback = register_value(L, 4); cmd_index++; } const char *cmd = luaL_checkstring(L, cmd_index); const char *args[lua_gettop(L) - cmd_index - 1]; for (int i = cmd_index + 1; i <= lua_gettop(L); i++) { args[i - cmd_index - 1] = luaL_checkstring(L, i); } args[lua_gettop(L) - cmd_index] = NULL; char *output; int ec = lsubproclc(type, message, &output, timeout, subprocess_callback, &callback_data, cmd, args); // Free callback data callback name if (callback_data.callback) free(callback_data.callback); lua_pushinteger(L, ec); lua_pushstring(L, output); free(output); return 2; }
static int lua_download(lua_State *L) { // Flush the lua output (it seems to buffered separately) do_flush(L, "stdout"); do_flush(L, "stderr"); // Extract params luaL_checktype(L, 1, LUA_TFUNCTION); int pcount = lua_gettop(L); const char *url = luaL_checkstring(L, 2); const char *cacert = NULL; if (pcount >= 3 && !lua_isnil(L, 3)) cacert = luaL_checkstring(L, 3); const char *crl = NULL; if (pcount >= 4 && !lua_isnil(L, 4)) crl = luaL_checkstring(L, 4); bool ocsp = lua_toboolean(L, 5); bool ssl = lua_toboolean(L, 6); // Handle the callback struct lua_download_data *data = malloc(sizeof *data); data->L = L; data->callback = register_value(L, 1); // Run the download struct events *events = extract_registry(L, "events"); ASSERT(events); struct wait_id id = download(events, download_callback, data, url, cacert, crl, ocsp, ssl); // Return the ID push_wid(L, &id); return 1; }
void lib_register(VMState *vm) { register_value(vm, value_null(), "null"); register_value(vm, value_undefined(), "undefined"); register_function(vm, _lib_char_at, "char_at"); register_function(vm, _lib_char_code_at, "char_code_at"); register_function(vm, _lib_concat, "concat"); register_function(vm, _lib_foreach, "foreach"); register_function(vm, _lib_import, "import"); register_function(vm, _lib_parse_number, "parse_number"); register_function(vm, _lib_print, "print"); register_function(vm, _lib_println, "println"); register_function(vm, _lib_random, "random"); register_function(vm, _lib_sizeof, "sizeof"); register_function(vm, _lib_to_string, "to_string"); register_function(vm, _lib_typeof, "typeof"); }
uint8_t register_value_by_id(fuzzy_engine* engine, int id, double value) { return register_value(engine, 0, id, value); }
uint8_t register_value_by_name(fuzzy_engine* engine, char* name, double value) { return register_value(engine, name, -1, value); }