From a0cdb4beb86919fd5e3b4d2177264845e91348c0 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Mon, 4 Apr 2011 00:47:32 +0000
Subject: [PATCH] remove lua from the runner (making ita dll) to prevent core &
 runner from absuing the wrong lua

git-svn-id: http://svn.net-core.org/repos/t-engine4@3149 51575b47-30f0-44d4-a5cc-537603b46e54
---
 build/runner.lua    |  29 ++++++++--
 src/runner/main.c   | 125 +++++++++++++++++++++++++++-----------------
 src/runner/runner.c |  97 ++++++++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+), 51 deletions(-)
 create mode 100644 src/runner/runner.c

diff --git a/build/runner.lua b/build/runner.lua
index 999596e8ac..a71d8cb514 100644
--- a/build/runner.lua
+++ b/build/runner.lua
@@ -21,8 +21,8 @@ project "TEngineRunner"
 	kind "WindowedApp"
 	language "C"
 	targetname "t-engine"
-	files { "../src/runner/*.c", "../src/getself.c", "../src/physfs.c", "../src/auxiliar.c" }
-	links { "runner-physfs", "runner-lua", "m" }
+	files { "../src/runner/main.c", "../src/getself.c" }
+	links { "m" }
 
 	configuration "linux"
 		links { "dl", "SDL", "SDL_ttf", "SDL_image", "SDL_mixer", "GL", "GLU", "m", "pthread" }
@@ -41,14 +41,36 @@ project "TEngineRunner"
 
 	configuration {"Debug"}
 		postbuildcommands { "cp ../bin/Debug/t-engine ../t-engine", }
-
 	configuration {"Release"}
 		postbuildcommands { "cp ../bin/Release/t-engine ../t-engine", }
 
+project "te4runner"
+	kind "SharedLib"
+	language "C"
+	targetname "te4runner"
+	targetprefix ""
+	targetextension ".tec"
+
+	files { "../src/runner/runner.c", "../src/physfs.c", "../src/auxiliar.c" }
+	links { "runner-physfs", "runner-lua", "m" }
+
+	configuration "linux"
+		defines { [[TENGINE_HOME_PATH='".t-engine"']], 'SELFEXE_LINUX'  }
+	configuration "windows"
+		defines { [[TENGINE_HOME_PATH='"T-Engine"']], 'SELFEXE_WINDOWS'  }
+	configuration "macosx"
+		defines { [[TENGINE_HOME_PATH='".t-engine"']], "USE_TENGINE_MAIN", 'SELFEXE_MACOSX'  }
+
+	configuration {"Debug"}
+		postbuildcommands { "cp ../bin/Debug/te4runner.tec ../", }
+	configuration {"Release"}
+		postbuildcommands { "cp ../bin/Release/te4runner.tec ../", }
+
 project "runner-physfs"
 	kind "StaticLib"
 	language "C"
 	targetname "runner-physfs"
+	buildoptions { "-fPIC" }
 
 	defines {"PHYSFS_SUPPORTS_ZIP"}
 
@@ -66,5 +88,6 @@ project "runner-lua"
 	kind "StaticLib"
 	language "C"
 	targetname "runner-lua"
+	buildoptions { "-fPIC" }
 
 	files { "../src/lua/*.c", }
diff --git a/src/runner/main.c b/src/runner/main.c
index 27f1090871..8be729da27 100644
--- a/src/runner/main.c
+++ b/src/runner/main.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "getself.h"
 
 #ifdef SELFEXE_WINDOWS
 #include <windows.h>
@@ -29,12 +30,7 @@
 #include <dlfcn.h>
 #endif
 
-#include "lua.h"
-#include "lauxlib.h"
-#include "lualib.h"
-#include "physfs.h"
 #include "core.h"
-#include "getself.h"
 
 // Update core to run
 void define_core(core_boot_type *core_def, const char *coretype, int id, const char *reboot_engine, const char *reboot_engine_version, const char *reboot_module, const char *reboot_name, int reboot_new, const char *reboot_einfo)
@@ -56,63 +52,96 @@ void define_core(core_boot_type *core_def, const char *coretype, int id, const c
 	core_def->reboot_new = reboot_new;
 }
 
-// Load the shared lib containing the core and calls te4main inside it, passing control to that core
-void run_core(core_boot_type *core_def, int argc, char **argv)
+// Load the shared lib containing the core loader and find a core
+static char *get_core(core_boot_type *core_def, int argc, char **argv)
 {
-	int (*te4main)(int, char**, core_boot_type*);
-
-	/******************************************************************
-	 ** Find a core file
-	 ******************************************************************/
-	PHYSFS_init(argv[0]);
-
+	char* (*find_te4_core)(core_boot_type*, const char*);
 	const char *selfexe = get_self_executable(argc, argv);
-	if (selfexe && PHYSFS_mount(selfexe, "/", 1)) {} else
+	const char* loader = "te4runner.tec";
+
+	if (selfexe)
 	{
-		printf("NO SELFEXE: bootstrapping from CWD\n");
-		PHYSFS_mount("bootstrap", "/bootstrap", 1);
+		// Load the file from the same directory
+		char buf[1024];
+		strcpy(buf, selfexe);
+#ifdef SELFEXE_WINDOWS
+		char *pos = strrchr(buf, '\\');
+#else
+		char *pos = strrchr(buf, '/');
+#endif
+		if (pos)
+		{
+			strcpy(pos+1, loader);
+			printf("SELF %s\n",buf);
+			loader = buf;
+		}
+	}
+
+	/***********************************************************************
+	 ** Windows DLL loading code
+	 ***********************************************************************/
+#ifdef SELFEXE_WINDOWS
+	HINSTANCE handle = LoadLibrary(loader);
+	if (!handle) {
+		fprintf(stderr, "Error loading core loader (%s): %d\n", loader, GetLastError());
+		exit(EXIT_FAILURE);
 	}
 
-	lua_State *L = lua_open();
-	luaL_openlibs(L);
-	luaopen_physfs(L);
+	*(void **) (&find_te4_core) = GetProcAddress(handle, "find_te4_core");
+	if (find_te4_core == NULL)  {
+		fprintf(stderr, "Error binding to core loader (%s): %d\n", loader, GetLastError());
+		exit(EXIT_FAILURE);
+	}
 
-	// Tell the boostrapping code the selfexe path
-	if (selfexe) lua_pushstring(L, selfexe);
-	else lua_pushnil(L);
-	lua_setglobal(L, "__SELFEXE");
+	// Run the core
+	char *core = find_te4_core(core_def, selfexe);
 
-	// Will be useful
-#ifdef __APPLE__
-	lua_pushboolean(L, TRUE);
-	lua_setglobal(L, "__APPLE__");
-#endif
+	FreeLibrary(handle);
 
-	// Run bootstrapping
-	if (!luaL_loadfile(L, "/bootstrap/boot.lua")) { lua_call(L, 0, 0); }
-	// Could not load bootstrap! Try to mount the engine from working directory as last resort
-	else
-	{
-		printf("Could not find bootstrapping code! Aborting!\n");
-		exit(1);
+	/***********************************************************************
+	 ** POSIX so loading code
+	 ***********************************************************************/
+#else
+	char *error;
+
+	void *handle = dlopen(loader, RTLD_LAZY);
+	if (!handle) {
+		fprintf(stderr, "Error loading core loader (%s): %s\n", loader, dlerror());
+		exit(EXIT_FAILURE);
 	}
 
-	// Get the core
-	lua_getglobal(L, "get_core");
-	if (core_def->coretype) lua_pushstring(L, core_def->coretype); else lua_pushnil(L);
-	lua_pushnumber(L, core_def->corenum);
-	lua_call(L, 2, 1);
-	char *core = strdup((char*)lua_tostring(L, -1));
-	printf("Runner booting core: %s\n", core);
+	dlerror();    /* Clear any existing error */
+
+	/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
+	 would seem more natural, but the C99 standard leaves
+	 casting from "void *" to a function pointer undefined.
+	 The assignment used below is the POSIX.1-2003 (Technical
+	 Corrigendum 1) workaround; see the Rationale for the
+	 POSIX specification of dlsym(). */
 
-	lua_close(L);
-	PHYSFS_deinit();
+	*(void **) (&find_te4_core) = dlsym(handle, "find_te4_core");
 
-	if (!core) {
-		printf("No core found!");
-		exit(1);
+	if ((error = dlerror()) != NULL)  {
+		fprintf(stderr, "Error binding to core loader (%s): %s\n", loader, error);
+		exit(EXIT_FAILURE);
 	}
 
+	// Run the core
+	char *core = find_te4_core(core_def, selfexe);
+
+	dlclose(handle);
+#endif
+	return core;
+}
+
+// Load the shared lib containing the core and calls te4main inside it, passing control to that core
+static void run_core(core_boot_type *core_def, int argc, char **argv)
+{
+	int (*te4main)(int, char**, core_boot_type*);
+
+	char *core = get_core(core_def, argc, argv);
+	printf("Runner booting core: %s\n", core);
+
 	/***********************************************************************
 	 ** Windows DLL loading code
 	 ***********************************************************************/
diff --git a/src/runner/runner.c b/src/runner/runner.c
new file mode 100644
index 0000000000..93dafe7c3c
--- /dev/null
+++ b/src/runner/runner.c
@@ -0,0 +1,97 @@
+/*
+    TE4 - T-Engine 4
+    Copyright (C) 2009, 2010, 2011 Nicolas Casalini
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+    Nicolas Casalini "DarkGod"
+    darkgod@te4.org
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+#include "lualib.h"
+#include "physfs.h"
+#include "core.h"
+
+#if defined(SELFEXE_LINUX)
+#define _te4_export
+#elif defined(SELFEXE_WINDOWS)
+#define _te4_export __declspec(dllexport)
+#elif defined(SELFEXE_MACOSX)
+#define _te4_export
+#else
+#define _te4_export
+#endif
+
+// Load the shared lib containing the core and calls te4main inside it, passing control to that core
+_te4_export char* find_te4_core(core_boot_type *core_def, const char *selfexe)
+{
+	/******************************************************************
+	 ** Find a core file
+	 ******************************************************************/
+	PHYSFS_init(selfexe);
+
+	if (selfexe && PHYSFS_mount(selfexe, "/", 1)) {} else
+	{
+		printf("NO SELFEXE: bootstrapping from CWD\n");
+		PHYSFS_mount("bootstrap", "/bootstrap", 1);
+	}
+
+	lua_State *L = lua_open();
+	luaL_openlibs(L);
+	luaopen_physfs(L);
+
+	// Tell the boostrapping code the selfexe path
+	if (selfexe) lua_pushstring(L, selfexe);
+	else lua_pushnil(L);
+	lua_setglobal(L, "__SELFEXE");
+
+	// Will be useful
+#ifdef __APPLE__
+	lua_pushboolean(L, TRUE);
+	lua_setglobal(L, "__APPLE__");
+#endif
+
+	// Run bootstrapping
+	if (!luaL_loadfile(L, "/bootstrap/boot.lua")) { lua_call(L, 0, 0); }
+	// Could not load bootstrap! Try to mount the engine from working directory as last resort
+	else
+	{
+		printf("Could not find bootstrapping code! Aborting!\n");
+		exit(1);
+	}
+
+	// Get the core
+	lua_getglobal(L, "get_core");
+	if (core_def->coretype) lua_pushstring(L, core_def->coretype); else lua_pushnil(L);
+	lua_pushnumber(L, core_def->corenum);
+	lua_call(L, 2, 1);
+	char *core = strdup((char*)lua_tostring(L, -1));
+	printf("Runner booting core: %s\n", core);
+
+	lua_close(L);
+	PHYSFS_deinit();
+
+	if (!core) {
+		printf("No core found!");
+		exit(1);
+	}
+
+	return core;
+}
-- 
GitLab