Browse Source

The full executable path, rather than argv[0], is now used when determining whether the executable is fused (resolves issue #1043.)

Alex Szpakowski 10 years ago
parent
commit
811b2db466

+ 5 - 0
src/common/OSX.h

@@ -45,6 +45,11 @@ std::string getLoveInResources();
  **/
  **/
 std::string checkDropEvents();
 std::string checkDropEvents();
 
 
+/**
+ * Returns the full path to the executable.
+ **/
+std::string getExecutablePath();
+
 } // osx
 } // osx
 } // love
 } // love
 
 

+ 8 - 0
src/common/OSX.mm

@@ -69,6 +69,14 @@ std::string checkDropEvents()
 	return dropstr;
 	return dropstr;
 }
 }
 
 
+std::string getExecutablePath()
+{
+	@autoreleasepool
+	{
+		return std::string([NSBundle mainBundle].executablePath.UTF8String);
+	}
+}
+
 } // osx
 } // osx
 } // love
 } // love
 
 

+ 5 - 0
src/common/iOS.h

@@ -54,6 +54,11 @@ std::string getHomeDirectory();
  **/
  **/
 bool openURL(const std::string &url);
 bool openURL(const std::string &url);
 
 
+/**
+ * Returns the full path to the executable.
+ **/
+std::string getExecutablePath();
+
 } // ios
 } // ios
 } // love
 } // love
 
 

+ 11 - 2
src/common/iOS.mm

@@ -305,15 +305,24 @@ bool openURL(const std::string &url)
 
 
 	@autoreleasepool
 	@autoreleasepool
 	{
 	{
+		UIApplication *app = [UIApplication sharedApplication];
 		NSURL *nsurl = [NSURL URLWithString:@(url.c_str())];
 		NSURL *nsurl = [NSURL URLWithString:@(url.c_str())];
 
 
-		if ([[UIApplication sharedApplication] canOpenURL:nsurl])
-			success = [[UIApplication sharedApplication] openURL:nsurl];
+		if ([app canOpenURL:nsurl])
+			success = [app openURL:nsurl];
 	}
 	}
 
 
 	return success;
 	return success;
 }
 }
 
 
+std::string getExecutablePath()
+{
+	@autoreleasepool
+	{
+		return std::string([NSBundle mainBundle].executablePath.UTF8String);
+	}
+}
+
 } // ios
 } // ios
 } // love
 } // love
 
 

+ 6 - 2
src/modules/filesystem/DroppedFile.cpp

@@ -64,7 +64,9 @@ bool DroppedFile::open(Mode newmode)
 #ifdef LOVE_WINDOWS
 #ifdef LOVE_WINDOWS
 	// make sure non-ASCII filenames work.
 	// make sure non-ASCII filenames work.
 	std::wstring modestr = to_widestr(getModeString(newmode));
 	std::wstring modestr = to_widestr(getModeString(newmode));
-	file = _wfopen(to_widestr(filename).c_str(), modestr.c_str());
+	std::wstring wfilename = to_widestr(filename);
+
+	file = _wfopen(wfilename.c_str(), modestr.c_str());
 #else
 #else
 	file = fopen(filename.c_str(), getModeString(newmode));
 	file = fopen(filename.c_str(), getModeString(newmode));
 #endif
 #endif
@@ -105,8 +107,10 @@ int64 DroppedFile::getSize()
 #ifdef LOVE_WINDOWS
 #ifdef LOVE_WINDOWS
 
 
 	// make sure non-ASCII filenames work.
 	// make sure non-ASCII filenames work.
+	std::wstring wfilename = to_widestr(filename);
+
 	struct _stat buf;
 	struct _stat buf;
-	if (_wstat(to_widestr(filename).c_str(), &buf) != 0)
+	if (_wstat(wfilename.c_str(), &buf) != 0)
 		return -1;
 		return -1;
 
 
 	return (int64) buf.st_size;
 	return (int64) buf.st_size;

+ 44 - 1
src/modules/filesystem/Filesystem.cpp

@@ -26,6 +26,17 @@
 #include <sys/types.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/stat.h>
 
 
+#if defined(LOVE_MACOSX)
+#include "common/OSX.h"
+#elif defined(LOVE_IOS)
+#include "common/iOS.h"
+#elif defined(LOVE_WINDOWS)
+#include <windows.h>
+#include "common/utf8.h"
+#elif defined(LOVE_LINUX)
+#include <unistd.h>
+#endif
+
 namespace love
 namespace love
 {
 {
 namespace filesystem
 namespace filesystem
@@ -43,8 +54,10 @@ bool Filesystem::isRealDirectory(const std::string &path) const
 {
 {
 #ifdef LOVE_WINDOWS
 #ifdef LOVE_WINDOWS
 	// make sure non-ASCII paths work.
 	// make sure non-ASCII paths work.
+	std::wstring wpath = to_widestr(path);
+
 	struct _stat buf;
 	struct _stat buf;
-	if (_wstat(to_widestr(path).c_str(), &buf) != 0)
+	if (_wstat(wpath.c_str(), &buf) != 0)
 		return false;
 		return false;
 
 
 	return (buf.st_mode & _S_IFDIR) == _S_IFDIR;
 	return (buf.st_mode & _S_IFDIR) == _S_IFDIR;
@@ -58,5 +71,35 @@ bool Filesystem::isRealDirectory(const std::string &path) const
 #endif
 #endif
 }
 }
 
 
+std::string Filesystem::getExecutablePath() const
+{
+#if defined(LOVE_MACOSX)
+	return love::osx::getExecutablePath();
+#elif defined(LOVE_IOS)
+	return love::ios::getExecutablePath();
+#elif defined(LOVE_WINDOWS)
+
+	wchar_t buffer[MAX_PATH + 1] = {0};
+
+	if (GetModuleFileNameW(nullptr, buffer, MAX_PATH) == 0)
+		return "";
+
+	return to_utf8(buffer);
+
+#elif defined(LOVE_LINUX)
+
+	char buffer[2048] = {0};
+
+	ssize_t len = readlink("/proc/self/exe", buffer, 2048);
+	if (len <= 0)
+		return "";
+
+	return std::string(buffer, len);
+
+#else
+#error Missing implementation for Filesystem::getExecutablePath!
+#endif
+}
+
 } // filesystem
 } // filesystem
 } // love
 } // love

+ 5 - 0
src/modules/filesystem/Filesystem.h

@@ -252,6 +252,11 @@ public:
 	 **/
 	 **/
 	virtual bool isRealDirectory(const std::string &path) const;
 	virtual bool isRealDirectory(const std::string &path) const;
 
 
+	/**
+	 * Gets the full platform-dependent path to the executable.
+	 **/
+	virtual std::string getExecutablePath() const;
+
 }; // Filesystem
 }; // Filesystem
 
 
 } // filesystem
 } // filesystem

+ 7 - 0
src/modules/filesystem/wrap_Filesystem.cpp

@@ -301,6 +301,12 @@ int w_getRealDirectory(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
+int w_getExecutablePath(lua_State *L)
+{
+	luax_pushstring(L, instance()->getExecutablePath());
+	return 1;
+}
+
 int w_isDirectory(lua_State *L)
 int w_isDirectory(lua_State *L)
 {
 {
 	const char *arg = luaL_checkstring(L, 1);
 	const char *arg = luaL_checkstring(L, 1);
@@ -699,6 +705,7 @@ static const luaL_Reg functions[] =
 	{ "getSaveDirectory", w_getSaveDirectory },
 	{ "getSaveDirectory", w_getSaveDirectory },
 	{ "getSourceBaseDirectory", w_getSourceBaseDirectory },
 	{ "getSourceBaseDirectory", w_getSourceBaseDirectory },
 	{ "getRealDirectory", w_getRealDirectory },
 	{ "getRealDirectory", w_getRealDirectory },
+	{ "getExecutablePath", w_getExecutablePath },
 	{ "isDirectory", w_isDirectory },
 	{ "isDirectory", w_isDirectory },
 	{ "isFile", w_isFile },
 	{ "isFile", w_isFile },
 	{ "createDirectory", w_createDirectory },
 	{ "createDirectory", w_createDirectory },

+ 1 - 0
src/modules/filesystem/wrap_Filesystem.h

@@ -57,6 +57,7 @@ int w_getAppdataDirectory(lua_State *L);
 int w_getSaveDirectory(lua_State *L);
 int w_getSaveDirectory(lua_State *L);
 int w_getSourceBaseDirectory(lua_State *L);
 int w_getSourceBaseDirectory(lua_State *L);
 int w_getRealDirectory(lua_State *L);
 int w_getRealDirectory(lua_State *L);
+int w_getExecutablePath(lua_State *L);
 int w_isDirectory(lua_State *L);
 int w_isDirectory(lua_State *L);
 int w_isFile(lua_State *L);
 int w_isFile(lua_State *L);
 int w_createDirectory(lua_State *L);
 int w_createDirectory(lua_State *L);

+ 0 - 1
src/modules/system/System.cpp

@@ -84,7 +84,6 @@ bool System::openURL(const std::string &url) const
 #if defined(LOVE_MACOSX)
 #if defined(LOVE_MACOSX)
 
 
 	bool success = false;
 	bool success = false;
-	// We could be lazy and use system("open " + url), but this is safer.
 	CFURLRef cfurl = CFURLCreateWithBytes(nullptr,
 	CFURLRef cfurl = CFURLCreateWithBytes(nullptr,
 	                                      (const UInt8 *) url.c_str(),
 	                                      (const UInt8 *) url.c_str(),
 	                                      url.length(),
 	                                      url.length(),

+ 8 - 2
src/scripts/boot.lua

@@ -271,8 +271,14 @@ function love.boot()
 	local arg0 = love.arg.getLow(arg)
 	local arg0 = love.arg.getLow(arg)
 	love.filesystem.init(arg0)
 	love.filesystem.init(arg0)
 
 
+	local exepath = love.filesystem.getExecutablePath()
+	if #exepath == 0 then
+		-- This shouldn't happen, but just in case we'll fall back to arg0.
+		exepath = arg0
+	end
+
 	-- Is this one of those fancy "fused" games?
 	-- Is this one of those fancy "fused" games?
-	local can_has_game = pcall(love.filesystem.setSource, arg0)
+	local can_has_game = pcall(love.filesystem.setSource, exepath)
 	local is_fused_game = can_has_game
 	local is_fused_game = can_has_game
 	if love.arg.options.fused.set then
 	if love.arg.options.fused.set then
 		is_fused_game = true
 		is_fused_game = true
@@ -293,7 +299,7 @@ function love.boot()
 		identity = love.path.leaf(full_source)
 		identity = love.path.leaf(full_source)
 	else
 	else
 		-- Use the name of the exe as the identity for now.
 		-- Use the name of the exe as the identity for now.
-		identity = love.path.leaf(arg0)
+		identity = love.path.leaf(exepath)
 	end
 	end
 
 
 	identity = identity:gsub("^([%.]+)", "") -- strip leading "."'s
 	identity = identity:gsub("^([%.]+)", "") -- strip leading "."'s

+ 13 - 2
src/scripts/boot.lua.h

@@ -497,13 +497,24 @@ const unsigned char boot_lua[] =
 	0x2e, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x77, 0x28, 0x61, 0x72, 0x67, 0x29, 0x0a,
 	0x2e, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x4c, 0x6f, 0x77, 0x28, 0x61, 0x72, 0x67, 0x29, 0x0a,
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x69, 
 	0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x69, 
 	0x6e, 0x69, 0x74, 0x28, 0x61, 0x72, 0x67, 0x30, 0x29, 0x0a,
 	0x6e, 0x69, 0x74, 0x28, 0x61, 0x72, 0x67, 0x30, 0x29, 0x0a,
+	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x6c, 
+	0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x67, 0x65, 0x74, 
+	0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x28, 0x29, 0x0a,
+	0x09, 0x69, 0x66, 0x20, 0x23, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 
+	0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x2d, 0x2d, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x6e, 0x27, 
+	0x74, 0x20, 0x68, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6a, 0x75, 0x73, 0x74, 
+	0x20, 0x69, 0x6e, 0x20, 0x63, 0x61, 0x73, 0x65, 0x20, 0x77, 0x65, 0x27, 0x6c, 0x6c, 0x20, 0x66, 0x61, 0x6c, 
+	0x6c, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x72, 0x67, 0x30, 0x2e, 0x0a,
+	0x09, 0x09, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x67, 0x30, 0x0a,
+	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x49, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 
 	0x09, 0x2d, 0x2d, 0x20, 0x49, 0x73, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 
 	0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x66, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x22, 0x66, 0x75, 0x73, 0x65, 
 	0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x66, 0x61, 0x6e, 0x63, 0x79, 0x20, 0x22, 0x66, 0x75, 0x73, 0x65, 
 	0x64, 0x22, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x3f, 0x0a,
 	0x64, 0x22, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x3f, 0x0a,
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 
 	0x65, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 
 	0x65, 0x20, 0x3d, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 
 	0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 
 	0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 
-	0x20, 0x61, 0x72, 0x67, 0x30, 0x29, 0x0a,
+	0x20, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x29, 0x0a,
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61, 
 	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61, 
 	0x6d, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x0a,
 	0x6d, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x6d, 0x65, 0x0a,
 	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 
 	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 
@@ -548,7 +559,7 @@ const unsigned char boot_lua[] =
 	0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 
 	0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x78, 0x65, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 
 	0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x77, 0x2e, 0x0a,
 	0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x77, 0x2e, 0x0a,
 	0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 
 	0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 
-	0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x61, 0x72, 0x67, 0x30, 0x29, 0x0a,
+	0x70, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x28, 0x65, 0x78, 0x65, 0x70, 0x61, 0x74, 0x68, 0x29, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 
 	0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 
 	0x74, 0x79, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5e, 0x28, 0x5b, 0x25, 0x2e, 0x5d, 0x2b, 0x29, 0x22, 
 	0x74, 0x79, 0x3a, 0x67, 0x73, 0x75, 0x62, 0x28, 0x22, 0x5e, 0x28, 0x5b, 0x25, 0x2e, 0x5d, 0x2b, 0x29, 0x22,