Пример #1
0
ngx_int_t
ngx_http_lua_set_by_chunk(lua_State *L, ngx_http_request_t *r, ngx_str_t *val,
    ngx_http_variable_value_t *args, size_t nargs, ngx_str_t *script)
{
    size_t           i;
    ngx_int_t        rc;
    u_char          *err_msg;
    size_t           len;
    u_char          *data;
#if (NGX_PCRE)
    ngx_pool_t      *old_pool;
#endif

    dd("nargs: %d", (int) nargs);

    dd("set Lua VM panic handler");

    lua_atpanic(L, ngx_http_lua_atpanic);

    NGX_LUA_EXCEPTION_TRY {
        dd("initialize nginx context in Lua VM, code chunk at "
           "stack top    sp = 1");
        ngx_http_lua_set_by_lua_env(L, r, nargs, args);

        /*  passing directive arguments to the user code */
        for (i = 0; i < nargs; i++) {
            lua_pushlstring(L, (const char *) args[i].data, args[i].len);
        }

#if (NGX_PCRE)
        /* XXX: work-around to nginx regex subsystem */
        old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
#endif

        lua_pushcfunction(L, ngx_http_lua_traceback);
        lua_insert(L, 1);  /* put it under chunk and args */

        dd("protected call user code");

        rc = lua_pcall(L, nargs, 1, 1);

        dd("after protected call user code");

        lua_remove(L, 1);  /* remove traceback function */

#if (NGX_PCRE)
        /* XXX: work-around to nginx regex subsystem */
        ngx_http_lua_pcre_malloc_done(old_pool);
#endif

        if (rc != 0) {
            /*  error occured when running loaded code */
            err_msg = (u_char *) lua_tolstring(L, -1, &len);

            if (err_msg == NULL) {
                err_msg = (u_char *) "unknown reason";
                len = sizeof("unknown reason") - 1;
            }

            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "failed to run set_by_lua*: %*s", len, err_msg);

            lua_settop(L, 0);    /*  clear remaining elems on stack */

            return NGX_ERROR;
        }

        data = (u_char *) lua_tolstring(L, -1, &len);

        if (data) {
            val->data = ngx_palloc(r->pool, len);
            if (val->data == NULL) {
                return NGX_ERROR;
            }

            ngx_memcpy(val->data, data, len);
            val->len = len;

        } else {
            val->data = NULL;
            val->len = 0;
        }

    } NGX_LUA_EXCEPTION_CATCH {

        dd("nginx execution restored");
        return NGX_ERROR;
    }

    /*  clear Lua stack */
    lua_settop(L, 0);

    return NGX_OK;
}
Пример #2
0
static int
lua_general_handler(mtev_dso_generic_t *self) {
  int status, rv;
  lua_general_conf_t *conf = get_config(self);
  lua_module_closure_t *lmc = pthread_getspecific(conf->key);
  mtev_lua_resume_info_t *ri = NULL;
  const char *err = NULL;
  char errbuf[128];
  lua_State *L;

  if(!lmc) mtev_lua_general_init(self);
  lmc = pthread_getspecific(conf->key);
  if(!lmc || !conf || !conf->module || !conf->function) {
    goto boom;
  }
  ri = lua_general_new_resume_info(lmc);
  L = ri->coro_state;

  lua_getglobal(L, "require");
  lua_pushstring(L, conf->module);
  rv = lua_pcall(L, 1, 1, 0);
  if(rv) {
    int i;
    mtevL(nlerr, "lua: require %s failed\n", conf->module);
    mtev_lua_traceback(L);
    i = lua_gettop(L);
    if(i>0) {
      if(lua_isstring(L, i)) {
        const char *err;
        size_t len;
        err = lua_tolstring(L, i, &len);
        mtevL(nlerr, "lua: %s\n", err);
      }
    }
    lua_pop(L,i);
    goto boom;
  }
  lua_pop(L, lua_gettop(L));

  mtev_lua_pushmodule(L, conf->module);
  if(lua_isnil(L, -1)) {
    lua_pop(L, 1);
    snprintf(errbuf, sizeof(errbuf), "no such module: '%s'", conf->module);
    err = errbuf;
    goto boom;
  }
  lua_getfield(L, -1, conf->function);
  lua_remove(L, -2);
  if(!lua_isfunction(L, -1)) {
    lua_pop(L, 1);
    snprintf(errbuf, sizeof(errbuf), "no function '%s' in module '%s'",
             conf->function, conf->module);
    err = errbuf;
    goto boom;
  }

  status = lmc->resume(ri, 0);
  if(status == 0) return 0;
  /* If we've failed, resume has freed ri, so we should just return. */
  mtevL(nlerr, "lua dispatch error: %d\n", status);
  tragic_failure(self);
  return 0;

 boom:
  if(err) mtevL(nlerr, "lua dispatch error: %s\n", err);
  if(ri) lua_general_ctx_free(ri);
  tragic_failure(self);
  return 0;
}
Пример #3
0
bool CLuaArguments::Call ( CLuaMain* pLuaMain, const CLuaFunctionRef& iLuaFunction, CLuaArguments * returnValues ) const
{
    assert ( pLuaMain );
    TIMEUS startTime = GetTimeUs ();

    // Add the function name to the stack and get the event from the table
    lua_State* luaVM = pLuaMain->GetVirtualMachine ();
    assert ( luaVM );
    LUA_CHECKSTACK ( luaVM, 1 );
    int luaStackPointer = lua_gettop ( luaVM );
    lua_getref ( luaVM, iLuaFunction.ToInt () );

    // Push our arguments onto the stack
    PushArguments ( luaVM );

    // Call the function with our arguments
    pLuaMain->ResetInstructionCount ();

    int iret = lua_pcall ( luaVM, m_Arguments.size (), LUA_MULTRET, 0 );
    if ( iret == LUA_ERRRUN || iret == LUA_ERRMEM )
    {
        SString strRes = ConformResourcePath ( lua_tostring( luaVM, -1 ) );
        
        vector <SString> vecSplit;
        strRes.Split ( ":", vecSplit );
        
        if ( vecSplit.size ( ) >= 3 )
        {
            SString strFile = vecSplit[0];
            int     iLine   = atoi ( vecSplit[1].c_str ( ) );
            SString strMsg  = vecSplit[2].substr ( 1 );
            
            g_pGame->GetScriptDebugging()->LogError ( strFile, iLine, strMsg );
        }
        else
            g_pGame->GetScriptDebugging()->LogError ( luaVM, "%s", strRes.c_str () );

        // cleanup the stack
        while ( lua_gettop ( luaVM ) - luaStackPointer > 0 )
            lua_pop ( luaVM, 1 );

       return false; // the function call failed
    }
    else
    {
        int iReturns = lua_gettop ( luaVM ) - luaStackPointer;

        if ( returnValues != NULL )
        {
            for ( int i = - iReturns; i <= -1; i++ )
            {
                returnValues->ReadArgument ( luaVM, i );
            }
        }

        // cleanup the stack
        while ( lua_gettop ( luaVM ) - luaStackPointer > 0 )
            lua_pop ( luaVM, 1 );
    }

    CPerfStatLuaTiming::GetSingleton ()->UpdateLuaTiming ( pLuaMain, pLuaMain->GetFunctionTag ( iLuaFunction.m_iFunction ), GetTimeUs() - startTime );
    return true;
}
Пример #4
0
/*****************************************************************************
 * Called through lua_scripts_batch_execute to call 'probe' on
 * the script pointed by psz_filename.
 *****************************************************************************/
static int probe_luascript( vlc_object_t *p_this, const char * psz_filename,
                            const luabatch_context_t *p_context )
{
    VLC_UNUSED(p_context);
    demux_t * p_demux = (demux_t *)p_this;

    p_demux->p_sys->psz_filename = strdup(psz_filename);

    /* Initialise Lua state structure */
    lua_State *L = luaL_newstate();
    if( !L )
    {
        msg_Err( p_demux, "Could not create new Lua State" );
        goto error;
    }
    p_demux->p_sys->L = L;

    /* Load Lua libraries */
    luaL_openlibs( L ); /* FIXME: Don't open all the libs? */

    vlclua_set_this( L, p_demux );
    luaL_register( L, "vlc", p_reg );
    luaopen_msg( L );
    luaopen_strings( L );
    luaopen_stream( L );
    luaopen_variables( L );
    luaopen_xml( L );
    lua_pushstring( L, p_demux->psz_location );
    lua_setfield( L, -2, "path" );
    lua_pushstring( L, p_demux->psz_access );
    lua_setfield( L, -2, "access" );

    lua_pop( L, 1 );

    /* Setup the module search path */
    if( vlclua_add_modules_path( L, psz_filename ) )
    {
        msg_Warn( p_demux, "Error while setting the module search path for %s",
                  psz_filename );
        goto error;
    }

    /* Load and run the script(s) */
    if( vlclua_dofile( VLC_OBJECT(p_demux), L, psz_filename ) )
    {
        msg_Warn( p_demux, "Error loading script %s: %s", psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        goto error;
    }

    lua_getglobal( L, "probe" );

    if( !lua_isfunction( L, -1 ) )
    {
        msg_Warn( p_demux, "Error while running script %s, "
                  "function probe() not found", psz_filename );
        goto error;
    }

    if( lua_pcall( L, 0, 1, 0 ) )
    {
        msg_Warn( p_demux, "Error while running script %s, "
                  "function probe(): %s", psz_filename,
                  lua_tostring( L, lua_gettop( L ) ) );
        goto error;
    }

    if( lua_gettop( L ) )
    {
        if( lua_toboolean( L, 1 ) )
        {
            msg_Dbg( p_demux, "Lua playlist script %s's "
                     "probe() function was successful", psz_filename );
            lua_pop( L, 1 );
            return VLC_SUCCESS;
        }
    }

error:
    lua_pop( L, 1 );
    lua_close( p_demux->p_sys->L );
    p_demux->p_sys->L = NULL;
    FREENULL( p_demux->p_sys->psz_filename );
    return VLC_EGENERIC;
}
Пример #5
0
/*!
    Prepares a Lua state for, and catches errors from, CorsixTH_lua_main(). By
    executing in Lua mode as soon as possible, errors can be nicely caught
    sooner, hence this function does as little as possible and leaves the rest
    for CorsixTH_lua_main().
*/
int main(int argc, char** argv)
{
    struct compile_time_lua_check
    {
        // Lua 5.1, not 5.0, is required
        int lua_5_point_1_required[LUA_VERSION_NUM >= 501 ? 1 : -1];

        // Lua numbers must be doubles so that the mantissa has at least
        // 32 bits (floats only have 24 bits)
        int number_is_double[types_equal<lua_Number, double>::result];
    };

    bool bRun = true;

    while(bRun)
    {
        lua_State *L = NULL;

        L = luaL_newstate();
        if(L == NULL)
        {
            fprintf(stderr, "Fatal error starting CorsixTH: "
                "Cannot open Lua state.\n");
            return 0;
        }
        lua_atpanic(L, CorsixTH_lua_panic);
        luaL_openlibs(L);
        lua_settop(L, 0);
        lua_pushcfunction(L, CorsixTH_lua_stacktrace);
        lua_pushcfunction(L, CorsixTH_lua_main);

        // Move command line parameters onto the Lua stack
        lua_checkstack(L, argc);
        for(int i = 0; i < argc; ++i)
        {
            lua_pushstring(L, argv[i]);
        }

        if(lua_pcall(L, argc, 0, 1) != 0)
        {
            const char* err = lua_tostring(L, -1);
            if(err != NULL)
            {
                fprintf(stderr, "%s\n", err);
            }
            else
            {
                fprintf(stderr, "An error has occured in CorsixTH:\n"
                    "Uncaught non-string Lua error\n");
            }
            lua_pushcfunction(L, Bootstrap_lua_error_report);
            lua_insert(L, -2);
            if(lua_pcall(L, 1, 0, 0) != 0)
            {
                fprintf(stderr, "%s\n", lua_tostring(L, -1));
            }
        }

        lua_getfield(L, LUA_REGISTRYINDEX, "_RESTART");
        bRun = lua_toboolean(L, -1) != 0;

        // Get cleanup functions out of the Lua state (but don't run them yet)
        std::stack<void(*)(void)> stkCleanup;
        lua_getfield(L, LUA_REGISTRYINDEX, "_CLEANUP");
        if(lua_type(L, -1) == LUA_TTABLE)
        {
            for(unsigned int i = 1; i <= lua_objlen(L, -1); ++i)
            {
                lua_rawgeti(L, -1, (int)i);
                stkCleanup.push((void(*)(void))lua_touserdata(L, -1));
                lua_pop(L, 1);
            }
        }

        lua_close(L);

        // The cleanup functions are executed _after_ the Lua state is fully
        // closed, and in reserve order to that in which they were registered.
        while(!stkCleanup.empty())
        {
            if(stkCleanup.top() != NULL)
                stkCleanup.top()();
            stkCleanup.pop();
        }

        if(bRun)
        {
            printf("Restarting...\n");
        }
    }
    return 0;
}
Пример #6
0
bool Settings::load()
{
	auto L = m_state;
	bool has_settings = PlatformInterface::fileExists(SETTINGS_PATH);
	bool errors = luaL_loadfile(L, has_settings ? SETTINGS_PATH : DEFAULT_SETTINGS_PATH) != LUA_OK;
	errors = errors || lua_pcall(L, 0, 0, 0) != LUA_OK;
	if (errors)
	{
		Lumix::g_log_error.log("Editor") << SETTINGS_PATH << ": " << lua_tostring(L, -1);
		lua_pop(L, 1);
		return false;
	}

	if (lua_getglobal(L, "window") == LUA_TTABLE)
	{
		m_window.x = getIntegerField(L, "x", 0);
		m_window.y = getIntegerField(L, "y", 0);
		m_window.w = getIntegerField(L, "w", -1);
		m_window.h = getIntegerField(L, "h", -1);
	}
	lua_pop(L, 1);

	loadStyle(L);

	m_is_maximized = getBoolean(L, "maximized", true);
	
	m_is_opened = getBoolean(L, "settings_opened", false);
	m_is_asset_browser_opened = getBoolean(L, "asset_browser_opened", false);
	m_is_entity_list_opened = getBoolean(L, "entity_list_opened", false);
	m_is_entity_template_list_opened = getBoolean(L, "entity_template_list_opened", false);
	m_is_log_opened = getBoolean(L, "log_opened", false);
	m_is_profiler_opened = getBoolean(L, "profiler_opened", false);
	m_is_properties_opened = getBoolean(L, "properties_opened", false);
	m_is_crash_reporting_enabled = getBoolean(L, "error_reporting_enabled", true);
	Lumix::enableCrashReporting(m_is_crash_reporting_enabled && !m_force_no_crash_report);
	m_mouse_sensitivity_x = getFloat(L, "mouse_sensitivity_x", 200.0f);
	m_mouse_sensitivity_y = getFloat(L, "mouse_sensitivity_y", 200.0f);

	if (!m_editor->getEngine().getPatchFileDevice())
	{
		if (lua_getglobal(L, "data_dir") == LUA_TSTRING) Lumix::copyString(m_data_dir, lua_tostring(L, -1));
		lua_pop(L, 1);
		m_editor->getEngine().setPatchPath(m_data_dir);
	}

	auto& actions = m_app.getActions();
	if (lua_getglobal(L, "actions") == LUA_TTABLE)
	{
		for (int i = 0; i < actions.size(); ++i)
		{
			if (lua_getfield(L, -1, actions[i]->name) == LUA_TTABLE)
			{
				for (int j = 0; j < Lumix::lengthOf(actions[i]->shortcut); ++j)
				{
					if (lua_rawgeti(L, -1, 1 + j) == LUA_TNUMBER)
					{
						actions[i]->shortcut[j] = (int)lua_tointeger(L, -1);
					}
					lua_pop(L, 1);
				}
			}
			lua_pop(L, 1);
		}
	}
	lua_pop(L, 1);

	m_app.getToolbarActions().clear();
	if (lua_getglobal(L, "toolbar") == LUA_TTABLE)
	{
		int len = (int)lua_rawlen(L, -1);
		for (int i = 0; i < len; ++i)
		{
			if (lua_rawgeti(L, -1, i + 1) == LUA_TSTRING)
			{
				const char* action_name = lua_tostring(L, -1);
				Action* action = m_app.getAction(action_name);
				if(action) m_app.getToolbarActions().push(action);
			}
			lua_pop(L, 1);
		}
	}
	lua_pop(L, 1);

	ImGui::LoadDock(L);
	return true;
}
Пример #7
0
	bool compiled_chunk::run(lua_State* L) const 
	{
		chunks_it_ = chunks_.begin();
		if(lua_load(L, chunk_reader, reinterpret_cast<void*>(const_cast<compiled_chunk*>(this)), NULL, NULL) || lua_pcall(L, 0, 0, 0)) {
			const char* a = lua_tostring(L, -1);
			std::cerr << a << "\n";
			lua_pop(L, 1);
			return true;
		}
		return false;
	}
Пример #8
0
const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
{


	if(!unit.valid())
	{
		return std::vector<std::string>();
	}

	const std::string& unit_id = (*unit).id();
	const int unit_x = (*unit).get_location().x + 1;
	const int unit_y = (*unit).get_location().y + 1;

	LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id <<  " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";

	if(L_ == NULL || ref_ == LUA_REFNIL)
	{
		//If we end up here, most likely the aspect don't use the lua-engine.
		//Just to make sure:
		if (val_ == "Lua Function")
		{
			return std::vector<std::string>();
		}
		return utils::split(val_);
	}

	//put the Pointer back on the Stack
	lua_rawgeti(L_, LUA_REGISTRYINDEX, ref_);

	if(lua_isstring(L_, -1))
	{
		return utils::split(lua_tostring(L_, -1));
	}

	if(!lua_isfunction(L_, -1))
	{
		ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
		return std::vector<std::string>();
	}

	//push parameter to the stack
	lua_pushinteger(L_, unit_x);
	lua_pushinteger(L_, unit_y);

	//To make unit_id a Parameter of the Lua function:
	//lua_pushfstring(L_, unit_id.c_str());

	//call function
	if(lua_pcall(L_, 2, 1, 0) != 0)
	{
		ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
		return std::vector<std::string>();
	}
	if (!lua_isstring(L_, -1))
	{
		ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
		return std::vector<std::string>();
	}

	//get result from Lua-Stack
	const std::string retval = std::string(lua_tostring(L_, -1));
	lua_pop(L_, 1);

	LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".\n";

	return utils::split(retval);
}
Пример #9
0
int plugin_debug_con_handle_stmt(chassis *chas, network_mysqld_con *con, GString *s) {
	gsize i, j;
	GPtrArray *fields;
	GPtrArray *rows;
	GPtrArray *row;

	switch(s->str[NET_HEADER_SIZE]) {
	case COM_QUERY:
		fields = NULL;
		rows = NULL;
		row = NULL;

		/* support the basic commands sent by the mysql shell */
		if (0 == g_ascii_strncasecmp(s->str + NET_HEADER_SIZE + 1, C("select @@version_comment limit 1"))) {
			MYSQL_FIELD *field;

			fields = network_mysqld_proto_fielddefs_new();

			field = network_mysqld_proto_fielddef_new();
			field->name = g_strdup("@@version_comment");
			field->type = FIELD_TYPE_VAR_STRING;
			g_ptr_array_add(fields, field);

			rows = g_ptr_array_new();
			row = g_ptr_array_new();
			g_ptr_array_add(row, g_strdup("MySQL Enterprise Agent"));
			g_ptr_array_add(rows, row);

			network_mysqld_con_send_resultset(con->client, fields, rows);
			
		} else if (0 == g_ascii_strncasecmp(s->str + NET_HEADER_SIZE + 1, C("select USER()"))) {
			MYSQL_FIELD *field;

			fields = network_mysqld_proto_fielddefs_new();
			field = network_mysqld_proto_fielddef_new();
			field->name = g_strdup("USER()");
			field->type = FIELD_TYPE_VAR_STRING;
			g_ptr_array_add(fields, field);

			rows = g_ptr_array_new();
			row = g_ptr_array_new();
			g_ptr_array_add(row, g_strdup("root"));
			g_ptr_array_add(rows, row);

			network_mysqld_con_send_resultset(con->client, fields, rows);
		} else {
			MYSQL_FIELD *field = NULL;
			lua_State *L = chas->priv->sc->L;

			if (0 == luaL_loadstring(L, s->str + NET_HEADER_SIZE + 1) &&
			    0 == lua_pcall(L, 0, 1, 0)) {
				/* let's see what is on the stack
				 * - scalars are turned into strings
				 *   return "foo" 
				 * - 1-dim tables are turned into a single-row result-set
				 *   return { foo = "bar", baz = "foz" }
				 * - 2-dim tables are turned into a multi-row result-set
				 *   return { { foo = "bar" }, { "foz" } }
				 */
				switch (lua_type(L, -1)) {
				case LUA_TTABLE:
					/* take the names from the fields */
					fields = network_mysqld_proto_fielddefs_new();

					lua_pushnil(L);
					while (lua_next(L, -2) != 0) {
						if (lua_istable(L, -1)) {
							/* 2-dim table
							 * 
							 * we only only take the keys from the first row
							 * afterwards we ignore them
							 */
					
							lua_pushnil(L);
							while (lua_next(L, -2) != 0) {
								if (!rows) {
									/* this is the 1st round, add the keys */
									lua_table_key_to_mysql_field(L, fields);
								}

								if (!row) row = g_ptr_array_new();
								if (lua_isboolean(L, -1)) {
									g_ptr_array_add(row, g_strdup(lua_toboolean(L, -1) ? "TRUE" : "FALSE"));
								} else if (lua_isnumber(L, -1)) {
									g_ptr_array_add(row, g_strdup_printf("%.0f", lua_tonumber(L, -1)));
								} else {
									g_ptr_array_add(row, g_strdup(lua_tostring(L, -1)));
								}

								lua_pop(L, 1); /* pop the value, but keep the key on the stack */
							}
					
							if (!rows) rows = g_ptr_array_new();
							g_ptr_array_add(rows, row);

							row = NULL;
						} else {
							/* 1-dim table */
							lua_table_key_to_mysql_field(L, fields);

							if (!row) row = g_ptr_array_new();
							if (lua_isboolean(L, -1)) {
								g_ptr_array_add(row, g_strdup(lua_toboolean(L, -1) ? "TRUE" : "FALSE"));
							} else if (lua_isnumber(L, -1)) {
								g_ptr_array_add(row, g_strdup_printf("%.0f", lua_tonumber(L, -1)));
							} else {
								g_ptr_array_add(row, g_strdup(lua_tostring(L, -1)));
							}
						}

						lua_pop(L, 1); /* pop the value, but keep the key on the stack */
					}

					if (row) {
						/* in 1-dim we have to append the row to the result-set,
						 * in 2-dim this is already done and row is NULL */
						if (!rows) rows = g_ptr_array_new();
						g_ptr_array_add(rows, row);
					}

					break;
				default:
					/* a scalar value */
					fields = network_mysqld_proto_fielddefs_new();
					field = network_mysqld_proto_fielddef_new();
					field->name = g_strdup("lua");
					field->type = FIELD_TYPE_VAR_STRING;
					g_ptr_array_add(fields, field);
		
					rows = g_ptr_array_new();
					row = g_ptr_array_new();
					g_ptr_array_add(row, g_strdup(lua_tostring(L, -1)));
					g_ptr_array_add(rows, row);

					break;
				}

				lua_pop(L, 1); /* get rid of the result */

				network_mysqld_con_send_resultset(con->client, fields, rows);
			}

			/* if we don't have fields for the resultset, we should have a
			 * error-msg on the stack */
			if (!fields) {
				size_t err_len = 0;
				const char *err;

				err = lua_tolstring(L, -1, &err_len);

				network_mysqld_con_send_error(con->client, err, err_len);
				
				lua_pop(L, 1);
			}
		}

		/* clean up */
		if (fields) {
			network_mysqld_proto_fielddefs_free(fields);
			fields = NULL;
		}

		if (rows) {
			for (i = 0; i < rows->len; i++) {
				row = rows->pdata[i];

				for (j = 0; j < row->len; j++) {
					g_free(row->pdata[j]);
				}

				g_ptr_array_free(row, TRUE);
			}
			g_ptr_array_free(rows, TRUE);
			rows = NULL;
		}

		break;
	case COM_QUIT:
		break;
	case COM_INIT_DB:
		network_mysqld_con_send_ok(con->client);
		break;
	default:
		network_mysqld_con_send_error(con->client, C("unknown COM_*"));
		break;
	}

	return 0;
}
Пример #10
0
AgentLuaInterface::AgentLuaInterface(int ID, double posX, double posY, double posZ, Sector *sector, std::string filename)
    : Agent(ID, posX, posY, posZ, sector), destinationX(posX), destinationY(posY),speed(1), moving(false),gridmove(false),filename(filename),
      nofile(false),removed(false),L(NULL)
{

    desc = "LUA";
    //Output::Inst()->kprintf("%f,%f", posX, posY);

    Output::Inst()->addGraphicAgent(ID, -1,-1);
    //Setup up the LUA stack:
    L = luaL_newstate();
    if(L == NULL)
    {
        Output::Inst()->kprintf("<b><font color=\"brown\">A new Agent cannot be initialized. Lua(%s) is out of memory, Killing simulation</font></b></>", LUA_VERSION);
        Output::KillSimulation.store(true);
        removed = true;

    }
    else
    {
        luaL_openlibs(L);

        // Register the path to the Rana specific lua modules
        lua_getglobal(L, "package");
        lua_getfield(L, -1, "path");
        std::string cur_path = lua_tostring(L, -1);
        std::string module_path = Output::Inst()->RanaDir;
        //Output::Inst()->kdebug(module_path.c_str());
        module_path.append("/modules/?.lua");
        //Output::Inst()->kdebug(module_path.c_str());
        cur_path.append(";");
        cur_path.append(module_path);
        cur_path.append(";");
        cur_path.append(Output::Inst()->AgentPath);
        cur_path.append("?.lua");
        lua_pop(L,1);
        lua_pushstring(L, cur_path.c_str());
        lua_setfield(L,-2,"path");
        lua_pop(L,1);

        //set the global values for the agent:
        lua_pushnumber(L,ID);
        lua_setglobal(L,"ID");
        lua_pushnumber(L,posX);
        lua_setglobal(L,"PositionX");
        lua_pushnumber(L,posY);
        lua_setglobal(L, "PositionY");
        lua_pushnumber(L, Phys::getMacroFactor()*Phys::getTimeRes());
        lua_setglobal(L, "STEP_RESOLUTION");
        lua_pushnumber(L, Phys::getTimeRes());
        lua_setglobal(L, "EVENT_RESOLUTION");
        lua_pushnumber(L, macroFactorMultiple);
        lua_setglobal(L, "StepMultiple");

        lua_pushnumber(L, Phys::getEnvX());
        lua_setglobal(L, "ENV_WIDTH");
        lua_pushnumber(L, Phys::getEnvY());
		lua_setglobal(L, "ENV_HEIGHT");
		lua_pushnumber(L, Phys::getEnvZ());
		lua_setglobal(L, "ENV_DEPTH");

        lua_pushnumber(L, destinationX);
        lua_setglobal(L, "DestinationX");
        lua_pushnumber(L,destinationY);
        lua_setglobal(L, "DestinationY");
        lua_pushnumber(L, speed);
        lua_setglobal(L, "Speed");
        lua_pushboolean(L, moving);
        lua_setglobal(L, "Moving");
        lua_pushboolean(L, gridmove);
		lua_setglobal(L, "GridMove");

		lua_pushnumber(L, mass);
		lua_setglobal(L, "Mass");
		lua_pushnumber(L, charge);
		lua_setglobal(L, "Charge");
		lua_pushnumber(L, radius);
		lua_setglobal(L, "Radius");

		lua_pushnumber(L, color.red);
		lua_setglobal(L, "ColorRed");
		lua_pushnumber(L, color.green);
		lua_setglobal(L, "ColorGreen");
		lua_pushnumber(L, color.blue);
		lua_setglobal(L, "ColorBlue");
		lua_pushnumber(L, color.alpha);
		lua_setglobal(L, "ColorAlpha");

        //lua_newtable(L);
        //lua_setglobal(L, "EventTable");
        //Register all the API functions:

        //Interface.
        lua_register(L, "l_debug", l_debug);
        lua_register(L, "l_print", l_print);
        lua_register(L, "say", l_debug);
        lua_register(L, "shout", l_print);

        //Physics and generator.
        lua_register(L, "l_speedOfSound", l_speedOfSound);
        lua_register(L, "l_distance", l_distance);
        lua_register(L, "l_currentTime",l_currentTime);
        lua_register(L, "l_currentTimeS", l_currentTimeS);
        lua_register(L, "l_generateEventID", l_generateEventID);
        lua_register(L, "l_getMacroFactor", l_getMacroFactor);
        lua_register(L, "l_getTimeResolution", l_getTimeResolution);
        lua_register(L, "l_getMersenneFloat", l_getMersenneFloat);
        lua_register(L, "l_getRandomFloat", l_getMersenneFloat);
        lua_register(L, "l_getRandomInteger", l_getMersenneInteger);
        lua_register(L, "l_getMersenneInteger", l_getMersenneInteger);

        //Map and movement.
        lua_register(L, "l_getEnvironmentSize", l_getEnvironmentSize);
        lua_register(L, "l_modifyMap", l_modifyMap);
        lua_register(L, "l_checkMap", l_checkMap);
        lua_register(L, "l_checkMapAndChange", l_checkMapAndChange);
        lua_register(L, "l_radialMapScan", l_radialMapScan);
        lua_register(L, "l_radialMapColorScan", l_radialMapColorScan);

        lua_register(L, "l_checkPosition", l_checkPosition);
        lua_register(L, "l_updatePosition", l_updatePosition);
        lua_register(L, "l_addPosition", l_addPosition);
        lua_register(L, "l_checkCollision", l_checkCollision);
        lua_register(L, "l_checkCollisionRadial", l_checkCollisionRadial);
        lua_register(L, "l_gridMove", l_gridMove);
        lua_register(L, "l_getMaskRadial", l_getMaskRadial);
        lua_register(L, "l_radialCollisionScan", l_radialCollisionScan);
        lua_register(L, "l_initializeGrid", l_initializeGrid);
        lua_register(L, "l_getGridScale", l_getGridScale);
        lua_register(L, "l_updatePositionIfFree", l_updatePositionIfFree);

        //Shared values.
        lua_register(L, "l_getSharedNumber", l_getSharedNumber);
        lua_register(L, "l_addSharedNumber",l_addSharedNumber);
        lua_register(L, "l_getSharedString", l_getSharedString);
        lua_register(L, "l_addSharedString", l_addSharedString);

        //Simulation core.
        lua_register(L, "l_getAgentPath", l_getAgentPath);
        lua_register(L, "l_getAgentPath", l_getAgentPath);
        lua_register(L, "l_stopSimulation", l_stopSimulation);
        lua_register(L, "l_removeAgent", l_removeAgent);
        lua_register(L, "l_addAgent", l_addAgent);

        //Agent.
        lua_register(L, "l_emitEvent", l_emitEvent);
        lua_register(L, "l_addGroup", l_addGroup);
        lua_register(L, "l_removeGroup", l_removeGroup);
        lua_register(L, "l_setStepMultiplier", l_setMacroFactorMultipler);
        lua_register(L, "l_changeAgentColor", l_changeAgentColor);

        std::string auxLib = Output::Inst()->RanaDir;
        auxLib.append("/modules/auxiliary.lua");

        std::string settingsPath = filename;
        settingsPath.erase(settingsPath.end()-4,settingsPath.end());
        settingsPath.append("_settings.lua");


        if(luaL_loadfile(L, auxLib.c_str()) || lua_pcall(L,0,0,0))
        {
            Output::Inst()->kprintf("<font color=\"red\">error : %s <\font>", lua_tostring(L, -1));
            nofile = true;
            Output::Inst()->kprintf("Lua Agent disabled\n");
        }

        if(luaL_loadfile(L, filename.c_str() ) || lua_pcall(L,0,0,0))
        {
            Output::Inst()->kprintf("<font color=\"red\">error : %s <\font>", lua_tostring(L, -1));
            nofile = true;
            Output::Inst()->kprintf("Lua Agent disabled\n");
        }

        //if(sector != NULL)
        //Output::Inst()->kdebug("I belong to sector %i", sector->getID());

        getSyncData();
        //Call the Initialization function for the agent
        lua_settop(L,0);
    }


    moveFactor = Phys::getMacroFactor() * Phys::getTimeRes();
}
Пример #11
0
int LuaStack::executeFunction(int handler, int numArgs, int numResults, const std::function<void(lua_State*,int)>& func)
{
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));                        /* L: ... func arg1 arg2 ... */
        }
        
        int functionIndex = -(numArgs + 1);
        
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            return 0;
        }
        
        int traceCallback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                        /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                           /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceCallback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceCallback);     /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        
        if (error)
        {
            if (traceCallback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1);                                        // remove error message from stack
            }
            else                                                           /* L: ... G error */
            {
                lua_pop(_state, 2);                                        // remove __G__TRACKBACK__ and error message from stack
            }
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        do {
            
            if (numResults <= 0 || nullptr == func)
                break;
            
            func(_state, numResults);
            
        } while (0);
        
        if (traceCallback)
        {
            lua_pop(_state, 1);                                          // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    
    return 1;
}
Пример #12
0
int LuaStack::executeFunctionReturnArray(int handler,int numArgs,int numResults,__Array& resultArray)
{
    int top = lua_gettop(_state);
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));         /* L: ... func arg1 arg2 ... */
        }
        int functionIndex = -(numArgs + 1);
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            lua_settop(_state,top);
            return 0;
        }
        
        int traceback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                         /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                            /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceback);                  /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        if (error)
        {
            if (traceback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1); // remove error message from stack
            }
            else                                                            /* L: ... G error */
            {
                lua_pop(_state, 2); // remove __G__TRACKBACK__ and error message from stack
            }
            lua_settop(_state,top);
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        if (numResults <= 0)
        {
            lua_settop(_state,top);
            return 0;
        }
        
        for (int i = 0 ; i < numResults; i++)
        {
            if (lua_type(_state, -1) == LUA_TBOOLEAN) {
                
                bool value = lua_toboolean(_state, -1);
                resultArray.addObject(Bool::create(value)) ;
                
            }else if (lua_type(_state, -1) == LUA_TNUMBER) {
                
                double value = lua_tonumber(_state, -1);
                resultArray.addObject(Double::create(value));
                
            }else if (lua_type(_state, -1) == LUA_TSTRING) {
                
                const char* value = lua_tostring(_state, -1);
                resultArray.addObject(String::create(value));
                
            }else{
                
                resultArray.addObject(static_cast<Ref*>(tolua_tousertype(_state, -1, nullptr)));
            }
            // remove return value from stack
            lua_pop(_state, 1);                                                /* L: ... [G] ret1 ret2 ... ret*/
        }
        /* L: ... [G]*/
        
        if (traceback)
        {
            lua_pop(_state, 1); // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    lua_settop(_state,top);
    return 1;
}
Пример #13
0
void server_destroy(client_t *client, const char *reason) {
    lua_pushliteral(L, "on_client_close");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushnumber(L, client_num(client));
    lua_pushstring(L, reason);
    if (lua_pcall(L, 2, 0, 0) != 0) {
        fprintf(stderr, "error calling on_client_close: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    // Quitmeldung senden
    if (client->is_gui_client) {
        packet_t packet;
        packet_init(&packet, PACKET_QUIT_MSG);
        packet_writeXX(&packet, reason, strlen(reason));
        server_send_packet(&packet, client);
    } else {
        server_writeto(client, "connection terminated: ", 23);
        server_writeto(client, reason, strlen(reason));
        server_writeto(client, "\r\n", 2);
    }

    // Kompressionsrest flushen
    server_flush_compression(client);

    // Rest rausschreiben (hier keine Fehlerbehandlung mehr, da eh egal).
    // Bei Filewritern muss nichts geschrieben werden, da deren Daten
    // immer direkt rausgeschrieben werden.
    if (!client->is_file_writer) 
        evbuffer_write(client->out_buf, client->fd);

    evbuffer_free(client->in_buf);
    evbuffer_free(client->out_buf);

    free(client->kill_me);

    if (client->compress)
        deflateEnd(&client->strm);
    
    event_del(&client->rd_event);
    event_del(&client->wr_event);
    client->in_buf  = NULL;
    client->out_buf = NULL;

    if (client->player) 
        player_detach_client(client, client->player);

    assert(client->next == NULL);
    assert(client->prev == NULL);

    if (client->is_gui_client) {
        if (client->next_gui == client) {
            assert(client->prev_gui == client);
            guiclients = NULL;
        } else {
            client->next_gui->prev_gui = client->prev_gui;
            client->prev_gui->next_gui = client->next_gui;
            guiclients = client->next_gui;
        }
    }

    num_clients--;
    
#ifndef NO_CONSOLE_CLIENT    
    if (client->fd != STDIN_FILENO)
#endif
#ifdef WIN32
        if (client->is_file_writer) {
            close(client->fd);
        } else {
            closesocket(client->fd);
        }
#else
        close(client->fd);
#endif
}
Пример #14
0
client_t *server_accept(int fd, const char *address) {
    client_t *client = clients;

    for (int i = 0; i < MAXCLIENTS; i++, client++) {
        if (!CLIENT_USED(client))
            goto found;
    }

    // write(fd, "no free slot\r\n", 14);
    fprintf(stderr, "cannot accept() new incoming connection: no free slot\n");
    return NULL;

found:
    memset(client, 0, sizeof(client_t));
    client->fd = fd;

    // File Writer wird leicht unterschiedlich behandelt
    client->is_file_writer = strstr(address, "special:file") == address;

    // Non Blocking setzen 
#ifdef WIN32
    DWORD notblock = 1;
    ioctlsocket(client->fd, FIONBIO, &notblock);
#else
    if (fcntl(client->fd, F_SETFL, O_NONBLOCK) < 0) {
        fprintf(stderr, "cannot set accept()ed socket nonblocking: %s\n", strerror(errno));
        return NULL;
    }
#endif

    // Soll Verbindung angenommen werden?
    lua_pushliteral(L, "on_new_client");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushstring(L, address);

    if (lua_pcall(L, 1, 2, 0) != 0) {
        fprintf(stderr, "error calling on_new_client: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
        return NULL;
    }

    if (!lua_toboolean(L, -2)) {
        size_t len; const char *msg = lua_tolstring(L, -1, &len);
        write(client->fd, msg, len);
        lua_pop(L, 2);
        return NULL;
    }

    lua_pop(L, 2);

    // Libevent aktivieren
    event_set(&client->rd_event, client->fd, EV_READ | EV_PERSIST, server_readable, client);
    event_set(&client->wr_event, client->fd, EV_WRITE            , server_writable, client);
    
    client->in_buf  = evbuffer_new();
    client->out_buf = evbuffer_new();

    client->compress = 0;

    client->kill_me = NULL;
    client->player  = NULL;

    client->next = NULL;
    client->prev = NULL;

    client->is_gui_client = 0;
    client->next_gui = NULL;
    client->prev_gui = NULL;

    num_clients++;

    // Annehmen
    lua_pushliteral(L, "on_client_accepted");
    lua_rawget(L, LUA_GLOBALSINDEX);
    lua_pushnumber(L, client_num(client));
    lua_pushstring(L, address);

    if (lua_pcall(L, 2, 0, 0) != 0) {
        fprintf(stderr, "error calling on_client_accepted: %s\n", lua_tostring(L, -1));
        lua_pop(L, 1);
    }

    if (!client->is_file_writer)
        event_add(&client->rd_event, NULL);

    return client;
}
Пример #15
0
int main(int argc, const char *argv[])
{
	WINDOW *wnd;

	// file char-table
	gcTable[enTile_Ground] = ' ';
	gcTable[enTile_Wall] = '#';
	gcTable[enTile_Food] = '@';
	gcTable[enTile_RedHeadUp] = '^';
	gcTable[enTile_RedHeadRight] = '>';
	gcTable[enTile_RedHeadDown] = 'v';
	gcTable[enTile_RedHeadLeft] = '<';
	gcTable[enTile_RedBody] = 'X';
	gcTable[enTile_GreenHeadUp] = '^';
	gcTable[enTile_GreenHeadRight] = '>';
	gcTable[enTile_GreenHeadDown] = 'v';
	gcTable[enTile_GreenHeadLeft] = '<';
	gcTable[enTile_GreenBody] = 'O';

	// init Lua
	L = lua_open();
	luaL_openlibs(L);

	int error = luaL_loadbuffer(L, "dofile('./snake.lua')", sizeof("dofile('./snake.lua')"), "line") || lua_pcall(L, 0, 0, 0);
	if (error) {
		mvaddstr(0, 0, lua_tostring(L, -1));
	}
	luaL_openlib(L, "mylib", myLib, 0);

	// initialize curses
	wnd = initscr();
	start_color();
	init_pair(1, COLOR_RED, COLOR_BLACK);// for red snake
	init_pair(2, COLOR_GREEN, COLOR_BLACK);// for green snake
	init_pair(3, COLOR_WHITE, COLOR_BLACK);// for system output
	cbreak();
	noecho();
	getmaxyx(wnd, g_max_x, g_max_y);
	clear();
	refresh();

	init_game();
	broadcast();
	while (gbGameOn) {//game loop
	//getch();
		get_input();
		update_game();
		broadcast();
//		sleep(500);
	}
	lua_close(L);
	endwin();
	return 0;
}
Пример #16
0
// Initializes a lua chisel
bool sinsp_chisel::init_lua_chisel(chisel_desc &cd, string const &fpath)
{
	lua_State* ls = lua_open();
	if(ls == NULL)
	{
		return false;
	}

	luaL_openlibs(ls);

	//
	// Load our own lua libs
	//
	luaL_openlib(ls, "sysdig", ll_sysdig, 0);
	luaL_openlib(ls, "chisel", ll_chisel, 0);
	luaL_openlib(ls, "evt", ll_evt, 0);

	//
	// Add our chisel paths to package.path
	//
	for(vector<chiseldir_info>::const_iterator it = g_chisel_dirs->begin();
		it != g_chisel_dirs->end(); ++it)
	{
		string path(it->m_dir);
		path += "?.lua";
		add_lua_package_path(ls, path.c_str());
	}

	//
	// Load the script
	//
	if(luaL_loadfile(ls, fpath.c_str()) || lua_pcall(ls, 0, 0, 0))
	{
		goto failure;
	}

	//
	// Extract the description
	//
	lua_getglobal(ls, "description");
	if(!lua_isstring(ls, -1))
	{
		return parse_view_info(ls, &cd);
	}
	cd.m_description = lua_tostring(ls, -1);

	//
	// Extract the short description
	//
	lua_getglobal(ls, "short_description");
	if(!lua_isstring(ls, -1))
	{
		goto failure;
	}
	cd.m_shortdesc = lua_tostring(ls, -1);

	//
	// Extract the category
	//
	cd.m_category = "";
	lua_getglobal(ls, "category");
	if(lua_isstring(ls, -1))
	{
		cd.m_category = lua_tostring(ls, -1);
	}

	//
	// Extract the hidden flag and skip the chisel if it's set
	//
	lua_getglobal(ls, "hidden");
	if(lua_isboolean(ls, -1))
	{
		int sares = lua_toboolean(ls, -1);
		if(sares)
		{
			goto failure;
		}
	}

	//
	// Extract the args
	//
	lua_getglobal(ls, "args");
	if(lua_isnoneornil(ls, -1))
	{
		goto failure;
	}

	try
	{
		parse_lua_chisel_args(ls, &cd);
	}
	catch(...)
	{
		goto failure;
	}

	return true;

failure:
	lua_close(ls);
	return false;
}
Пример #17
0
int
ts_lua_http_cont_handler(TSCont contp, TSEvent event, void *edata)
{
    TSHttpTxn           txnp = (TSHttpTxn)edata;
    lua_State           *l;
    ts_lua_http_ctx     *http_ctx;
    ts_lua_main_ctx     *main_ctx;

    http_ctx = (ts_lua_http_ctx*)TSContDataGet(contp);
    main_ctx = http_ctx->mctx;

    l = http_ctx->lua;

    TSMutexLock(main_ctx->mutexp);

    switch (event) {

        case TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE:

            lua_getglobal(l, TS_LUA_FUNCTION_CACHE_LOOKUP_COMPLETE);
            if (lua_type(l, -1) == LUA_TFUNCTION) {
                if (lua_pcall(l, 0, 1, 0)) {
                    fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1));
                }
            }

            break;

        case TS_EVENT_HTTP_SEND_REQUEST_HDR:

            lua_getglobal(l, TS_LUA_FUNCTION_SEND_REQUEST);
            if (lua_type(l, -1) == LUA_TFUNCTION) {
                if (lua_pcall(l, 0, 1, 0)) {
                    fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1));
                }
            }

            break;

        case TS_EVENT_HTTP_READ_RESPONSE_HDR:

            lua_getglobal(l, TS_LUA_FUNCTION_READ_RESPONSE);
            if (lua_type(l, -1) == LUA_TFUNCTION) {
                if (lua_pcall(l, 0, 1, 0)) {
                    fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1));
                }
            }

            break;

        case TS_EVENT_HTTP_SEND_RESPONSE_HDR:

            lua_getglobal(l, TS_LUA_FUNCTION_SEND_RESPONSE);
            if (lua_type(l, -1) == LUA_TFUNCTION) {
                if (lua_pcall(l, 0, 1, 0)) {
                    fprintf(stderr, "lua_pcall failed: %s\n", lua_tostring(l, -1));
                }
            }

            break;

        case TS_EVENT_HTTP_TXN_CLOSE:
            ts_lua_destroy_http_ctx(http_ctx);
            TSContDestroy(contp);
            break;

        default:
            break;
    }

    TSMutexUnlock(main_ctx->mutexp);
    TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
    return 0;
}
Пример #18
0
void sinsp_chisel::load(string cmdstr)
{
	m_filename = cmdstr;
	trim(cmdstr);

	ifstream is;

	//
	// Try to open the file as is
	//
	if(!openfile(m_filename, &is))
	{
		//
		// Try to add the .sc extension
		//
		if(!openfile(m_filename + ".sc", &is))
		{
			if(!openfile(m_filename + ".lua", &is))
			{
				throw sinsp_exception("can't open file " + m_filename);
			}
		}
	}

	//
	// Bring the file into a string
	//
	string docstr((istreambuf_iterator<char>(is)),
		istreambuf_iterator<char>());

#ifdef HAS_LUA_CHISELS
	//
	// Rewind the stream
	//
	is.seekg(0);

	//
	// Load the file
	//
	std::istreambuf_iterator<char> eos;
	std::string scriptstr(std::istreambuf_iterator<char>(is), eos);

	//
	// Open the script
	//
	m_ls = lua_open();
 
	luaL_openlibs(m_ls);

	//
	// Load our own lua libs
	//
	luaL_openlib(m_ls, "sysdig", ll_sysdig, 0);
	luaL_openlib(m_ls, "chisel", ll_chisel, 0);
	luaL_openlib(m_ls, "evt", ll_evt, 0);

	//
	// Add our chisel paths to package.path
	//
	for(uint32_t j = 0; j < g_chisel_dirs->size(); j++)
	{
		string path(g_chisel_dirs->at(j).m_dir);
		path += "?.lua";
		add_lua_package_path(m_ls, path.c_str());
	}

	//
	// Load the script
	//
	if(luaL_loadstring(m_ls, scriptstr.c_str()) || lua_pcall(m_ls, 0, 0, 0)) 
	{
		throw sinsp_exception("Failed to load chisel " + 
			m_filename + ": " + lua_tostring(m_ls, -1));
	}

	//
	// Allocate the chisel context for the script
	//
	m_lua_cinfo = new chiselinfo(m_inspector);

	//
	// Set the context globals
	//
	lua_pushlightuserdata(m_ls, this);
	lua_setglobal(m_ls, "sichisel");

	//
	// Extract the args
	//
	lua_getglobal(m_ls, "args");
	if(!lua_istable(m_ls, -1))
	{
		throw sinsp_exception("Failed to load chisel " + 
			m_filename + ": args table missing");
	}

	try
	{
		parse_lua_chisel_args(m_ls, &m_lua_script_info);
	}
	catch(sinsp_exception& e)
	{
		throw e;
	}

	//
	// Check if the script has an on_event
	//
	lua_getglobal(m_ls, "on_event");
	if(lua_isfunction(m_ls, -1))
	{
		m_lua_has_handle_evt = true;
		lua_pop(m_ls, 1);
	}
#endif

	is.close();
}
Пример #19
0
void sinsp_chisel::on_init()
{
	//
	// Done with the arguments, call init()
	//
	lua_getglobal(m_ls, "on_init");

	if(!lua_isfunction(m_ls, -1)) 
	{
		//
		// No on_init. 
		// That's ok. Just return.
		//
		return;
	}

	if(lua_pcall(m_ls, 0, 1, 0) != 0) 
	{
		//
		// Exception running init
		//
		const char* lerr = lua_tostring(m_ls, -1);
		string err = m_filename + ": error in init(): " + lerr;
		throw sinsp_exception(err);
	}

	if(m_new_chisel_to_exec == "")
	{
		if(!lua_isboolean(m_ls, -1)) 
		{
			throw sinsp_exception(m_filename + " chisel error: wrong init() return value.");
		}

		if(!lua_toboolean(m_ls, -1))
		{
			throw sinsp_exception("init() for chisel " + m_filename + " failed.");
		}
	}

	lua_pop(m_ls, 1);

	//
	// If the chisel called chisel.exec(), free this chisel and load the new one
	//
	if(m_new_chisel_to_exec != "")
	{
		free_lua_chisel();
		load(m_new_chisel_to_exec);
		m_new_chisel_to_exec = "";

		string args;
		for(uint32_t j = 0; j < m_argvals.size(); j++)
		{
			if(m_argvals[j].find(" ") == string::npos)
			{
				args += m_argvals[j];
			}
			else
			{
				args += string("'") + m_argvals[j] + "'";
			}

			if(j < m_argvals.size() - 1)
			{
				args += " ";
			}
		}

		m_argvals.clear();
		set_args(args);

		on_init();
	}
}
Пример #20
0
bool sinsp_chisel::run(sinsp_evt* evt)
{
#ifdef HAS_LUA_CHISELS
	string line;

	ASSERT(m_ls);

	//
	// Make the event available to the API
	//
	lua_pushlightuserdata(m_ls, evt);
	lua_setglobal(m_ls, "sievt");

	//
	// If this is the first event, put the event pointer on the stack.
	// We assume that the event pointer will never change.
	//
	if(m_lua_is_first_evt)
	{
		first_event_inits(evt);
	}

	//
	// If there is a timeout callback, see if it's time to call it
	//
	do_timeout(evt);

	//
	// If there is a filter, run it
	//
	if(m_lua_cinfo->m_filter != NULL)
	{
		if(!m_lua_cinfo->m_filter->run(evt))
		{
			return false;
		}
	}

	//
	// If the script has the on_event callback, call it
	//
	if(m_lua_has_handle_evt)
	{
		lua_getglobal(m_ls, "on_event");
			
		if(lua_pcall(m_ls, 0, 1, 0) != 0) 
		{
			throw sinsp_exception(m_filename + " chisel error: " + lua_tostring(m_ls, -1));
		}
	
		int oeres = lua_toboolean(m_ls, -1);
		lua_pop(m_ls, 1);

		if(m_lua_cinfo->m_end_capture == true)
		{
			throw sinsp_capture_interrupt_exception();
		}

		if(oeres == false)
		{
			return false;
		}
	}

	//
	// If the script has a formatter, run it
	//
	if(m_lua_cinfo->m_formatter != NULL)
	{
		if(m_lua_cinfo->m_formatter->tostring(evt, &line))
		{
			cout << line << endl;
		}
	}

	return true;
#endif
}
Пример #21
0
ngx_int_t
ngx_http_lua_set_by_chunk(
        lua_State *l,
        ngx_http_request_t *r,
        ngx_str_t *val,
        ngx_http_variable_value_t *args,
        size_t nargs
        )
{
    size_t i;
    ngx_int_t rc;

    // set Lua VM panic handler
    lua_atpanic(l, ngx_http_lua_atpanic);

    // initialize nginx context in Lua VM, code chunk at stack top    sp = 1
    ngx_http_lua_set_by_lua_env(l, r, nargs, args);

    // passing directive arguments to the user code
    for(i = 0; i < nargs; ++i) {
        lua_pushlstring(l, (const char*)args[i].data, args[i].len);
    }

    // protected call user code
    rc = lua_pcall(l, nargs, 1, 0);
    if(rc) {
        // error occured when running loaded code
        const char *err_msg = lua_tostring(l, -1);
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "(lua-error) %s", err_msg);

        lua_settop(l, 0);    // clear remaining elems on stack
        assert(lua_gettop(l) == 0);

        return NGX_ERROR;
    }

    if(setjmp(ngx_http_lua_exception) == 0) {
        // try {
        size_t rlen;
        const char *rdata = lua_tolstring(l, -1, &rlen);

        if(rdata) {
            val->data = ngx_pcalloc(r->pool, rlen);
            if (val->data == NULL) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate result buffer!");

                return NGX_ERROR;
            }

            ngx_memcpy(val->data, rdata, rlen);
            val->len = rlen;
        } else {
            val->data = NULL;
            val->len = 0;
        }
    } else {
        // } catch
        dd("NginX execution restored");
    }

    // clear Lua stack
    lua_settop(l, 0);

    return NGX_OK;
}
Пример #22
0
void sinsp_chisel::set_args(vector<pair<string, string>> args)
{
#ifdef HAS_LUA_CHISELS
	uint32_t j;
	uint32_t n_required_args = get_n_required_args();
	uint32_t n_optional_args = get_n_optional_args();

	ASSERT(m_ls);

	//
	// Validate the arguments
	//
	if(args.size() < n_required_args)
	{
		throw sinsp_exception("wrong number of parameters for chisel " + m_filename +
			", " + to_string((long long int)n_required_args) + " required, " + 
			to_string((long long int)args.size()) + " given");
	}
	else if(args.size() > n_optional_args + n_required_args)
	{
		throw sinsp_exception("too many parameters for chisel " + m_filename +
			", " + to_string((long long int)(n_required_args)) + " required, " +
			to_string((long long int)(n_optional_args)) + " optional, " +
			to_string((long long int)args.size()) + " given");
	}

	//
	// Push the arguments
	//
	for(j = 0; j < args.size(); j++)
	{
		lua_getglobal(m_ls, "on_set_arg");
		if(!lua_isfunction(m_ls, -1))
		{
			lua_pop(m_ls, 1);
			throw sinsp_exception("chisel " + m_filename + " misses a set_arg() function.");
		}

		lua_pushstring(m_ls, args[j].first.c_str()); 
		lua_pushstring(m_ls, args[j].second.c_str());

		//
		// call get_info()
		//
		if(lua_pcall(m_ls, 2, 1, 0) != 0) 
		{
			throw sinsp_exception(m_filename + " chisel error: " + lua_tostring(m_ls, -1));
		}

		if(!lua_isboolean(m_ls, -1)) 
		{
			throw sinsp_exception(m_filename + " chisel error: wrong set_arg() return value.");
		}

		int sares = lua_toboolean(m_ls, -1);

		if(!sares)
		{
			throw sinsp_exception("set_arg() for chisel " + m_filename + " failed.");
		}

		lua_pop(m_ls, 1);
	}
#endif
}
Пример #23
0
/* Initialize the scripting environment.
 *
 * 初始化脚本环境。
 *
 * It is possible to call this function to reset the scripting environment
 * assuming that we call scriptingRelease() before.
 *
 * 这个函数也可以在 scriptingRelease() 执行之后使用,用于对脚本环境进行重置。
 *
 * See scriptingReset() for more information.
 */
void scriptingInit(void)
{
    // 创建一个新的 lua 环境
    lua_State *lua = lua_open();

    // 载入内置函数库
    luaLoadLibraries(lua);

    // 屏蔽所有不想暴露给脚本环境的函数(目前只有 loadfile)
    luaRemoveUnsupportedFunctions(lua);

    /* Initialize a dictionary we use to map SHAs to scripts.
     * 创建一个字典,用于将 SHA 校验码映射到脚本
     * This is useful for replication, as we need to replicate EVALSHA
     * as EVAL, so we need to remember the associated script.
     * 因为 Redis 目前复制脚本的方法是将 EVALSHA 转换成 EVAL 来进行的,
     * 所以程序需要保存和 SHA 校验值相对应的脚本。
     */
    server.lua_scripts = dictCreate(&shaScriptObjectDictType,NULL);

    /* Register the redis commands table and fields */
    // 创建 table ,并以给定名称将 C 函数注册到表格上
    lua_newtable(lua);

    /* 注册 redis.call */
    lua_pushstring(lua,"call");
    lua_pushcfunction(lua,luaRedisCallCommand);
    lua_settable(lua,-3);

    /* 注册 redis.pcall */
    lua_pushstring(lua,"pcall");
    lua_pushcfunction(lua,luaRedisPCallCommand);
    lua_settable(lua,-3);

    /* 注册 redis.log 和 log levels. */
    lua_pushstring(lua,"log");
    lua_pushcfunction(lua,luaLogCommand);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_DEBUG");
    lua_pushnumber(lua,REDIS_DEBUG);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_VERBOSE");
    lua_pushnumber(lua,REDIS_VERBOSE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_NOTICE");
    lua_pushnumber(lua,REDIS_NOTICE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_WARNING");
    lua_pushnumber(lua,REDIS_WARNING);
    lua_settable(lua,-3);

    /* 注册 redis.sha1hex */
    lua_pushstring(lua, "sha1hex");
    lua_pushcfunction(lua, luaRedisSha1hexCommand);
    lua_settable(lua, -3);

    /* 注册 redis.error_reply and redis.status_reply */
    lua_pushstring(lua, "error_reply");
    lua_pushcfunction(lua, luaRedisErrorReplyCommand);
    lua_settable(lua, -3);
    lua_pushstring(lua, "status_reply");
    lua_pushcfunction(lua, luaRedisStatusReplyCommand);
    lua_settable(lua, -3);

    /* Finally set the table as 'redis' global var. */
    // 将 table 设置为 redis 全局变量
    lua_setglobal(lua,"redis");

    /* Replace math.random and math.randomseed with our implementations. */
    // 将 math.random 和 math.randomseed 设置为 Redis 实现
    // 用于生成确定性的随机数
    // (对于同一个 seed ,生成的随机序列总是相同)
    lua_getglobal(lua,"math");

    lua_pushstring(lua,"random");
    lua_pushcfunction(lua,redis_math_random);
    lua_settable(lua,-3);

    lua_pushstring(lua,"randomseed");
    lua_pushcfunction(lua,redis_math_randomseed);
    lua_settable(lua,-3);

    lua_setglobal(lua,"math");

    /* Add a helper funciton that we use to sort the multi bulk output of non
     * deterministic commands, when containing 'false' elements.
     * 用于对不确定性多个回复的输出进行排序
     */
    {
        char *compare_func =    "function __redis__compare_helper(a,b)\n"
                                "  if a == false then a = '' end\n"
                                "  if b == false then b = '' end\n"
                                "  return a<b\n"
                                "end\n";
        luaL_loadbuffer(lua,compare_func,strlen(compare_func),"@cmp_func_def");
        lua_pcall(lua,0,0,0);
    }

    /* Create the (non connected) client that we use to execute Redis commands
     * inside the Lua interpreter.
     * 创建一个无网络连接的伪客户端,用于执行 Lua 脚本中的命令
     * Note: there is no need to create it again when this function is called
     * by scriptingReset().
     */
    if (server.lua_client == NULL)
    {
        server.lua_client = createClient(-1);
        server.lua_client->flags |= REDIS_LUA_CLIENT;
    }

    /* Lua beginners ofter don't use "local", this is likely to introduce
     * subtle bugs in their code. To prevent problems we protect accesses
     * to global variables.
     *
     * 为了避免全局变量被意外地修改,保护全局变量。
     */
    scriptingEnableGlobalsProtection(lua);

    // 将 lua 环境赋值到服务器变量
    server.lua = lua;
}
Пример #24
0
void evalGenericCommand(redisClient *c, int evalsha)
{
    lua_State *lua = server.lua;
    char funcname[43];
    long long numkeys;
    int delhook = 0;

    /* We want the same PRNG sequence at every call so that our PRNG is
     * not affected by external state.
     *
     * 在每次执行 EVAL 时重置随机 seed ,从而保证可以生成相同的随机序列。
     */
    redisSrand48(0);

    /* We set this flag to zero to remember that so far no random command
     * was called. This way we can allow the user to call commands like
     * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
     * is called (otherwise the replication and AOF would end with non
     * deterministic sequences).
     *
     * Thanks to this flag we'll raise an error every time a write command
     * is called after a random command was used.
     *
     * 用两个变量,对命令进行检查
     * 确保在调用随机命令之后,再调用写命令将出现错误
     */
    server.lua_random_dirty = 0;
    server.lua_write_dirty = 0;

    /* Get the number of arguments that are keys */
    // 获取输入键的数量
    if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
        return;
    // 对键的正确性做一个快速检查
    if (numkeys > (c->argc - 3))
    {
        addReplyError(c,"Number of keys can't be greater than number of args");
        return;
    }

    /* We obtain the script SHA1, then check if this function is already
     * defined into the Lua state */
    // 组合出函数的名字,例如 f_282297a0228f48cd3fc6a55de6316f31422f5d17
    funcname[0] = 'f';
    funcname[1] = '_';
    if (!evalsha)
    {
        /* Hash the code if this is an EVAL call */
        // 如果执行的是 EVAL 命令,那么计算脚本的 SHA1 校验和
        sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
    }
    else
    {
        // 如果执行的是 EVALSHA 命令,直接使用传入的 SHA1 值
        /* We already have the SHA if it is a EVALSHA */
        int j;
        char *sha = c->argv[1]->ptr;

        for (j = 0; j < 40; j++)
            funcname[j+2] = tolower(sha[j]);
        funcname[42] = '\0';
    }

    /* Try to lookup the Lua function */
    // 按名查找函数
    lua_getglobal(lua, funcname);
    if (lua_isnil(lua,1))
    {

        // 没找到脚本相应的脚本

        lua_pop(lua,1); /* remove the nil from the stack */
        /* Function not defined... let's define it if we have the
         * body of the funciton. If this is an EVALSHA call we can just
         * return an error. */
        if (evalsha)
        {
            // 如果执行的是 EVALSHA ,返回脚本未找到错误
            addReply(c, shared.noscripterr);
            return;
        }
        // 如果执行的是 EVAL ,那么创建并执行新函数,然后将代码添加到脚本字典中
        if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
        /* Now the following is guaranteed to return non nil */
        lua_getglobal(lua, funcname);
        redisAssert(!lua_isnil(lua,1));
    }

    /* Populate the argv and keys table accordingly to the arguments that
     * EVAL received. */
    // 设置 KEYS 和 ARGV 全局变量到 Lua 环境
    luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
    luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);

    /* Select the right DB in the context of the Lua client */
    // 为 Lua 所属的(伪)客户端设置数据库
    selectDb(server.lua_client,c->db->id);

    /* Set an hook in order to be able to stop the script execution if it
     * is running for too much time.
     *
     * 设置一个钩子,用于在运行时间过长时停止脚本的运作。
     *
     * We set the hook only if the time limit is enabled as the hook will
     * make the Lua script execution slower.
     *
     * 只在开启了时间限制选项时使用钩子,因为它会拖慢脚本的运行速度。
     */
    // 调用客户端
    server.lua_caller = c;
    // 脚本开始时间
    server.lua_time_start = ustime()/1000;
    // 是否杀死脚本
    server.lua_kill = 0;
    // 只在开启时间限制时使用钩子
    if (server.lua_time_limit > 0 && server.masterhost == NULL)
    {
        lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
        delhook = 1;
    }

    /* At this point whatever this script was never seen before or if it was
     * already defined, we can call it. We have zero arguments and expect
     * a single return value. */
    // 执行脚本(所属的函数)
    if (lua_pcall(lua,0,1,0))
    {

        // 以下是脚本执行出错的代码。。。

        // 删除钩子
        if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */

        // 脚本执行已超时
        if (server.lua_timedout)
        {
            // 清除超时 FLAG
            server.lua_timedout = 0;
            /* Restore the readable handler that was unregistered when the
             * script timeout was detected. */
            // 将超时钩子里删除的读事件重新加上
            aeCreateFileEvent(server.el,c->fd,AE_READABLE,
                              readQueryFromClient,c);
        }

        // 清空调用者
        server.lua_caller = NULL;
        // 更新目标数据库
        selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
        addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
                            funcname, lua_tostring(lua,-1));
        // 弹出函数
        lua_pop(lua,1);
        // 执行完整的废料回首循环(full garbage-collection cycle)
        lua_gc(lua,LUA_GCCOLLECT,0);
        // 返回
        return;
    }

    // 以下是脚本执行成功时执行的代码。。。

    // 删除钩子
    if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */

    // 清空超时 FLAG
    server.lua_timedout = 0;

    // 清空调用者
    server.lua_caller = NULL;

    // 更新 DB
    selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */

    // 将 Lua 回复转换成 Redis 回复
    luaReplyToRedisReply(c,lua);

    // 执行 1 步渐进式 GC
    lua_gc(lua,LUA_GCSTEP,1);

    /* If we have slaves attached we want to replicate this command as
     * EVAL instead of EVALSHA. We do this also in the AOF as currently there
     * is no easy way to propagate a command in a different way in the AOF
     * and in the replication link.
     *
     * 如果有附属节点,那么使用 EVAL 而不是 EVALSHA 来传播脚本
     * 因为目前还没有代码可以检测脚本是否已经传送到附属节点中
     *
     * IMPROVEMENT POSSIBLE:
     * 1) Replicate this command as EVALSHA in the AOF.
     * 2) Remember what slave already received a given script, and replicate
     *    the EVALSHA against this slaves when possible.
     */
    // 如果执行的是 EVALSHA 命令
    if (evalsha)
    {
        // 取出脚本代码体(body)
        robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);

        redisAssertWithInfo(c,NULL,script != NULL);
        // 重写客户端命令为 EVAL
        rewriteClientCommandArgument(c,0,
                                     resetRefCount(createStringObject("EVAL",4)));
        rewriteClientCommandArgument(c,1,script);
    }
}
Пример #25
0
static int _load_script(void)
{
	int rc = SLURM_SUCCESS;
	struct stat st;
	lua_State *L_orig = L;

	if (stat(lua_script_path, &st) != 0) {
		if (L_orig) {
			(void) error("Unable to stat %s, "
			             "using old script: %s",
			             lua_script_path, strerror(errno));
			return SLURM_SUCCESS;
		}
		return error("Unable to stat %s: %s",
		             lua_script_path, strerror(errno));
	}
	
	if (st.st_mtime <= lua_script_last_loaded) {
		return SLURM_SUCCESS;
	}

	/*
	 *  Initilize lua
	 */
	L = luaL_newstate();
	luaL_openlibs(L);
	if (luaL_loadfile(L, lua_script_path)) {
		if (L_orig) {
			(void) error("lua: %s: %s, using previous script",
			             lua_script_path, lua_tostring(L, -1));
			lua_close(L);
			L = L_orig;
			return SLURM_SUCCESS;
		}
		rc = error("lua: %s: %s", lua_script_path,
		           lua_tostring(L, -1));
		lua_pop(L, 1);
		return rc;
	}

	/*
	 *  Register SLURM functions in lua state:
	 *  logging and slurm structure read/write functions
	 */
	_register_lua_slurm_output_functions();
	_register_lua_slurm_struct_functions();

	/*
	 *  Run the user script:
	 */
	if (lua_pcall(L, 0, 1, 0) != 0) {
		if (L_orig) {
			(void) error("job_submit/lua: %s: %s, "
			             "using previous script",
			             lua_script_path, lua_tostring(L, -1));
			lua_close(L);
			L = L_orig;
			return SLURM_SUCCESS;
		}
		rc = error("job_submit/lua: %s: %s",
		           lua_script_path, lua_tostring(L, -1));
		lua_pop(L, 1);
		return rc;
	}

	/*
	 *  Get any return code from the lua script
	 */
	rc = (int) lua_tonumber(L, -1);
	if (rc != SLURM_SUCCESS) {
		if (L_orig) {
			(void) error("job_submit/lua: %s: returned %d "
			             "on load, using previous script",
			             lua_script_path, rc);
			lua_close(L);
			L = L_orig;
			return SLURM_SUCCESS;
		}
		(void) error("job_submit/lua: %s: returned %d on load",
		             lua_script_path, rc);
		lua_pop (L, 1);
		return rc;
	}

	/*
	 *  Check for required lua script functions:
	 */
	rc = _check_lua_script_functions();
	if (rc != SLURM_SUCCESS) {
		if (L_orig) {
			(void) error("job_submit/lua: %s: "
			             "required function(s) not present, "
			             "using previous script",
			             lua_script_path);
			lua_close(L);
			L = L_orig;
			return SLURM_SUCCESS;
		}
		return rc;
	}

	if (L_orig)
		lua_close(L_orig);
	lua_script_last_loaded = time(NULL);
	return SLURM_SUCCESS;
}
Пример #26
0
void evalGenericCommand(redisClient *c, int evalsha) {
    lua_State *lua = server.lua;
    char funcname[43];
    long long numkeys;
    int delhook = 0;

    /* We want the same PRNG sequence at every call so that our PRNG is
     * not affected by external state. */
    redisSrand48(0);

    /* We set this flag to zero to remember that so far no random command
     * was called. This way we can allow the user to call commands like
     * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
     * is called (otherwise the replication and AOF would end with non
     * deterministic sequences).
     *
     * Thanks to this flag we'll raise an error every time a write command
     * is called after a random command was used. */
    server.lua_random_dirty = 0;
    server.lua_write_dirty = 0;

    /* Get the number of arguments that are keys */
    if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
        return;
    if (numkeys > (c->argc - 3)) {
        addReplyError(c,"Number of keys can't be greater than number of args");
        return;
    }

    /* We obtain the script SHA1, then check if this function is already
     * defined into the Lua state */
    funcname[0] = 'f';
    funcname[1] = '_';
    if (!evalsha) {
        /* Hash the code if this is an EVAL call */
        sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
    } else {
        /* We already have the SHA if it is a EVALSHA */
        int j;
        char *sha = c->argv[1]->ptr;

        for (j = 0; j < 40; j++)
            funcname[j+2] = tolower(sha[j]);
        funcname[42] = '\0';
    }

    /* Try to lookup the Lua function */
    lua_getglobal(lua, funcname);
    if (lua_isnil(lua,1)) {
        lua_pop(lua,1); /* remove the nil from the stack */
        /* Function not defined... let's define it if we have the
         * body of the funciton. If this is an EVALSHA call we can just
         * return an error. */
        if (evalsha) {
            addReply(c, shared.noscripterr);
            return;
        }
        if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
        /* Now the following is guaranteed to return non nil */
        lua_getglobal(lua, funcname);
        redisAssert(!lua_isnil(lua,1));
    }

    /* Populate the argv and keys table accordingly to the arguments that
     * EVAL received. */
    luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
    luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);

    /* Select the right DB in the context of the Lua client */
    selectDb(server.lua_client,c->db->id);
    
    /* Set an hook in order to be able to stop the script execution if it
     * is running for too much time.
     * We set the hook only if the time limit is enabled as the hook will
     * make the Lua script execution slower. */
    server.lua_caller = c;
    server.lua_time_start = ustime()/1000;
    server.lua_kill = 0;
    if (server.lua_time_limit > 0 && server.masterhost == NULL) {
        lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
        delhook = 1;
    }

    /* At this point whatever this script was never seen before or if it was
     * already defined, we can call it. We have zero arguments and expect
     * a single return value. */
    if (lua_pcall(lua,0,1,0)) {
        if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
        if (server.lua_timedout) {
            server.lua_timedout = 0;
            /* Restore the readable handler that was unregistered when the
             * script timeout was detected. */
            aeCreateFileEvent(server.el,c->fd,AE_READABLE,
                              readQueryFromClient,c);
        }
        server.lua_caller = NULL;
        selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
        addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
            funcname, lua_tostring(lua,-1));
        lua_pop(lua,1);
        lua_gc(lua,LUA_GCCOLLECT,0);
        return;
    }
    if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
    server.lua_timedout = 0;
    server.lua_caller = NULL;
    selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
    luaReplyToRedisReply(c,lua);
    lua_gc(lua,LUA_GCSTEP,1);

    /* If we have slaves attached we want to replicate this command as
     * EVAL instead of EVALSHA. We do this also in the AOF as currently there
     * is no easy way to propagate a command in a different way in the AOF
     * and in the replication link.
     *
     * IMPROVEMENT POSSIBLE:
     * 1) Replicate this command as EVALSHA in the AOF.
     * 2) Remember what slave already received a given script, and replicate
     *    the EVALSHA against this slaves when possible.
     */
    if (evalsha) {
        robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);

        redisAssertWithInfo(c,NULL,script != NULL);
        rewriteClientCommandArgument(c,0,
            resetRefCount(createStringObject("EVAL",4)));
        rewriteClientCommandArgument(c,1,script);
    }
}
Пример #27
0
/* Initialize the scripting environment.
 * It is possible to call this function to reset the scripting environment
 * assuming that we call scriptingRelease() before.
 * See scriptingReset() for more information. */
void scriptingInit(void) {
    lua_State *lua = lua_open();

    luaLoadLibraries(lua);
    luaRemoveUnsupportedFunctions(lua);

    /* Initialize a dictionary we use to map SHAs to scripts.
     * This is useful for replication, as we need to replicate EVALSHA
     * as EVAL, so we need to remember the associated script. */
    server.lua_scripts = dictCreate(&dbDictType,NULL);

    /* Register the redis commands table and fields */
    lua_newtable(lua);

    /* redis.call */
    lua_pushstring(lua,"call");
    lua_pushcfunction(lua,luaRedisCallCommand);
    lua_settable(lua,-3);

    /* redis.pcall */
    lua_pushstring(lua,"pcall");
    lua_pushcfunction(lua,luaRedisPCallCommand);
    lua_settable(lua,-3);

    /* redis.log and log levels. */
    lua_pushstring(lua,"log");
    lua_pushcfunction(lua,luaLogCommand);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_DEBUG");
    lua_pushnumber(lua,REDIS_DEBUG);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_VERBOSE");
    lua_pushnumber(lua,REDIS_VERBOSE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_NOTICE");
    lua_pushnumber(lua,REDIS_NOTICE);
    lua_settable(lua,-3);

    lua_pushstring(lua,"LOG_WARNING");
    lua_pushnumber(lua,REDIS_WARNING);
    lua_settable(lua,-3);

    /* redis.sha1hex */
    lua_pushstring(lua, "sha1hex");
    lua_pushcfunction(lua, luaRedisSha1hexCommand);
    lua_settable(lua, -3);

    /* redis.error_reply and redis.status_reply */
    lua_pushstring(lua, "error_reply");
    lua_pushcfunction(lua, luaRedisErrorReplyCommand);
    lua_settable(lua, -3);
    lua_pushstring(lua, "status_reply");
    lua_pushcfunction(lua, luaRedisStatusReplyCommand);
    lua_settable(lua, -3);

    /* Finally set the table as 'redis' global var. */
    lua_setglobal(lua,"redis");

    /* Replace math.random and math.randomseed with our implementations. */
    lua_getglobal(lua,"math");

    lua_pushstring(lua,"random");
    lua_pushcfunction(lua,redis_math_random);
    lua_settable(lua,-3);

    lua_pushstring(lua,"randomseed");
    lua_pushcfunction(lua,redis_math_randomseed);
    lua_settable(lua,-3);

    lua_setglobal(lua,"math");

    /* Add a helper funciton that we use to sort the multi bulk output of non
     * deterministic commands, when containing 'false' elements. */
    {
        char *compare_func =    "function __redis__compare_helper(a,b)\n"
                                "  if a == false then a = '' end\n"
                                "  if b == false then b = '' end\n"
                                "  return a<b\n"
                                "end\n";
        luaL_loadbuffer(lua,compare_func,strlen(compare_func),"@cmp_func_def");
        lua_pcall(lua,0,0,0);
    }

    /* Create the (non connected) client that we use to execute Redis commands
     * inside the Lua interpreter.
     * Note: there is no need to create it again when this function is called
     * by scriptingReset(). */
    if (server.lua_client == NULL) {
        server.lua_client = createClient(-1);
        server.lua_client->flags |= REDIS_LUA_CLIENT;
    }

    /* Lua beginners ofter don't use "local", this is likely to introduce
     * subtle bugs in their code. To prevent problems we protect accesses
     * to global variables. */
    scriptingEnableGlobalsProtection(lua);

    server.lua = lua;
}
Пример #28
0
/*
 * Arguments: function, [arguments (any) ...]
 * Returns: [thread_ludata]
 */
static int
thread_run (lua_State *L)
{
    struct sys_thread *vmtd = sys_get_thread();
    lua_State *NL;
    struct sys_thread *td;
#ifndef _WIN32
    pthread_attr_t attr;
    int res = 0;
#else
    HANDLE hThr;
    const int res = 0;
#endif

    if (!vmtd) luaL_argerror(L, 0, "Threading not initialized");
    luaL_checktype(L, 1, LUA_TFUNCTION);

    NL = lua_newthread(L);
    if (!NL) goto err;

    td = lua_newuserdata(L, sizeof(struct sys_thread));
    memset(td, 0, sizeof(struct sys_thread));
    td->mutex = vmtd->mutex;
    td->L = NL;
    td->vmtd = vmtd->vmtd;

#ifndef _WIN32
    if ((res = pthread_attr_init(&attr))
     || (res = pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE)))
	goto err;
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    res = pthread_create(&td->tid, &attr,
     (thread_func_t) thread_start, td);
    pthread_attr_destroy(&attr);
    if (!res) {
#else
    hThr = (HANDLE) _beginthreadex(NULL, THREAD_STACK_SIZE,
     (thread_func_t) thread_start, td, 0, &td->tid);
    if (hThr) {
	CloseHandle(hThr);
#endif
	thread_settable(L, NL, td->tid);  /* save thread to avoid GC */
	lua_xmove(L, NL, lua_gettop(L));  /* move function and args to NL */

	lua_pushlightuserdata(L, td);
	return 1;
    }
 err:
    return sys_seterror(L, res);
}


/*
 * Arguments: function, master (thread_ludata),
 *	[arguments (string | number | boolean | lightuserdata) ...],
 *	thread, thread_udata
 */
static THREAD_FUNC_API
thread_startvm (struct sys_thread *td)
{
    lua_State *L = td->L;

    thread_settable(L, L, td->tid);

    sys_set_thread(td);
    sys_vm2_enter(td);

    if (lua_pcall(L, lua_gettop(L) - 1, 0, 0)) {
	if (td->interrupted && lua_touserdata(L, -1) == &g_TLSIndex)
	    lua_pop(L, 1);
	else
	    lua_error(L);
    }

    /* notify event_queue */
    if (td->trigger)
	sys_trigger_notify(&td->trigger, SYS_EVEOF | SYS_EVDEL);

    lua_close(L);
    return 0;
}
Пример #29
-1
int LuaInterface::pcall(int numArgs, int numRets, int errorFuncIndex)
{
    assert(hasIndex(-numArgs - 1));
    return lua_pcall(L, numArgs, numRets, errorFuncIndex);
}
Пример #30
-1
int
ts_lua_add_module(ts_lua_instance_conf *conf, ts_lua_main_ctx *arr, int n, int argc, char *argv[])
{
    int             i, ret;
    int             t;
    lua_State       *L;

    for (i = 0; i < n; i++) {

        L = arr[i].lua;

        lua_newtable(L);                                    // create this module's global table
        lua_pushvalue(L, -1);
        lua_setfield(L, -2, "_G");
        lua_newtable(L);
        lua_rawgeti(L, LUA_REGISTRYINDEX, arr[i].gref);
        lua_setfield(L, -2, "__index");
        lua_setmetatable(L, -2);
        lua_replace(L, LUA_GLOBALSINDEX);

        if (luaL_loadfile(L, conf->script)) {
            fprintf(stderr, "[%s] luaL_loadfile %s failed: %s\n", __FUNCTION__, conf->script, lua_tostring(L, -1));
            lua_pop(L, 1);
            return -1;
        }

        if (lua_pcall(L, 0, 0, 0)) {
            fprintf(stderr, "[%s] lua_pcall %s failed: %s\n", __FUNCTION__, conf->script, lua_tostring(L, -1));
            lua_pop(L, 1);
            return -1;
        }

        /* call "__init__", to parse parameters */
        lua_getglobal(L, "__init__");

        if (lua_type(L, -1) == LUA_TFUNCTION) {

            lua_newtable(L);

            for (t = 0; t < argc; t++) {
                lua_pushnumber(L, t);
                lua_pushstring(L, argv[t]);
                lua_rawset(L, -3);
            }

            if (lua_pcall(L, 1, 1, 0)) {
                fprintf(stderr, "[%s] lua_pcall %s failed: %s\n", __FUNCTION__, conf->script, lua_tostring(L, -1));
                lua_pop(L, 1);
                return -1;
            }

            ret = lua_tonumber(L, -1);
            lua_pop(L, 1);

            if (ret)
                return -1;          /* script parse error */

        } else {
            lua_pop(L, 1);          /* pop nil */
        }


        lua_pushlightuserdata(L, conf);
        lua_pushvalue(L, LUA_GLOBALSINDEX);
        lua_rawset(L, LUA_REGISTRYINDEX);

        lua_newtable(L);
        lua_replace(L, LUA_GLOBALSINDEX);               // set empty table to global
    }


    return 0;
}