From 45862a1b9fedcf31e6219359bbfaae2bef2405b1 Mon Sep 17 00:00:00 2001 From: jacob1 Date: Sun, 8 Jun 2014 20:37:44 -0400 Subject: [PATCH] only use Application Support directory on OS X 10.9, probably fix crash on startup for macs The original reason it broke on macs was because gFinderLaunch was broken --- src/SDLMain.m | 58 +++++++++++++---- src/lua/socket/socket.lua | 133 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 src/lua/socket/socket.lua diff --git a/src/SDLMain.m b/src/SDLMain.m index fbe9da2df..148c97e95 100644 --- a/src/SDLMain.m +++ b/src/SDLMain.m @@ -88,21 +88,47 @@ static NSString *getApplicationName(void) /* Set the working directory to the .app's parent directory */ - (void) setupWorkingDirectory:(BOOL)shouldChdir { - NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - if([paths count] < 1) return; - - NSString *appSupportPath = [paths objectAtIndex:0]; - BOOL isDir = NO; - NSError *error = nil; - NSString *appPath = [appSupportPath stringByAppendingPathComponent:@"The Powder Toy"]; - if (![[NSFileManager defaultManager] fileExistsAtPath:appPath isDirectory:&isDir] && isDir == NO) { - if(![[NSFileManager defaultManager] createDirectoryAtPath:appPath withIntermediateDirectories:YES attributes:nil error:&error]) - { - NSLog(@"Could not set up working dir. Error: %@", error); + SInt32 versionMajor = 0, versionMinor = 0; + Gestalt(gestaltSystemVersionMajor, &versionMajor); + Gestalt(gestaltSystemVersionMinor, &versionMinor); + + /* Set the working directory to Application Support on Mavericks and above */ + if (versionMajor > 10 || versionMinor >= 9) + { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); + if ([paths count] < 1) return; + + NSString *appSupportPath = [paths objectAtIndex:0]; + BOOL isDir = NO; + NSError *error = nil; + NSString *appPath = [appSupportPath stringByAppendingPathComponent:@"The Powder Toy"]; + if (![[NSFileManager defaultManager] fileExistsAtPath:appPath isDirectory:&isDir] && isDir == NO) + { + if (![[NSFileManager defaultManager] createDirectoryAtPath:appPath withIntermediateDirectories:YES attributes:nil error:&error]) + { + NSLog(@"Could not set up working dir. Error: %@", error); + return; + } + } + chdir([appPath UTF8String]); + } + /* Set the working directory to the .app's parent directory, because the code above breaks anything below Mavericks? (just a guess) */ + else + { + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) + { + chdir(parentdir); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); } } - chdir([appPath UTF8String]); } #if SDL_USE_NIB_FILE @@ -301,8 +327,14 @@ static void CustomApplicationMain (int argc, char **argv) - (void) applicationDidFinishLaunching: (NSNotification *) note { int status; + SInt32 versionMajor = 0, versionMinor = 0; + Gestalt(gestaltSystemVersionMajor, &versionMajor); + Gestalt(gestaltSystemVersionMinor, &versionMinor); - /* Set the working directory to the .app's parent directory */ + /* using gFinderLaunch doesn't work in Mavericks and above, so always change it */ + if (versionMajor > 10 || versionMinor >= 9) + [self setupWorkingDirectory:TRUE]; + else [self setupWorkingDirectory:gFinderLaunch]; #if SDL_USE_NIB_FILE diff --git a/src/lua/socket/socket.lua b/src/lua/socket/socket.lua new file mode 100644 index 000000000..211adcd1d --- /dev/null +++ b/src/lua/socket/socket.lua @@ -0,0 +1,133 @@ +----------------------------------------------------------------------------- +-- LuaSocket helper module +-- Author: Diego Nehab +-- RCS ID: $Id: socket.lua,v 1.22 2005/11/22 08:33:29 diego Exp $ +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local math = require("math") +local socket = require("socket.core") +module("socket") + +----------------------------------------------------------------------------- +-- Exported auxiliar functions +----------------------------------------------------------------------------- +function connect(address, port, laddress, lport) + local sock, err = socket.tcp() + if not sock then return nil, err end + if laddress then + local res, err = sock:bind(laddress, lport, -1) + if not res then return nil, err end + end + local res, err = sock:connect(address, port) + if not res then return nil, err end + return sock +end + +function bind(host, port, backlog) + local sock, err = socket.tcp() + if not sock then return nil, err end + sock:setoption("reuseaddr", true) + local res, err = sock:bind(host, port) + if not res then return nil, err end + res, err = sock:listen(backlog) + if not res then return nil, err end + return sock +end + +try = newtry() + +function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) + else return f(opt1, opt2) end + end +end + +----------------------------------------------------------------------------- +-- Socket sources and sinks, conforming to LTN12 +----------------------------------------------------------------------------- +-- create namespaces inside LuaSocket namespace +sourcet = {} +sinkt = {} + +BLOCKSIZE = 2048 + +sinkt["close-when-done"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then + sock:close() + return 1 + else return sock:send(chunk) end + end + }) +end + +sinkt["keep-open"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if chunk then return sock:send(chunk) + else return 1 end + end + }) +end + +sinkt["default"] = sinkt["keep-open"] + +sink = choose(sinkt) + +sourcet["by-length"] = function(sock, length) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if length <= 0 then return nil end + local size = math.min(socket.BLOCKSIZE, length) + local chunk, err = sock:receive(size) + if err then return nil, err end + length = length - string.len(chunk) + return chunk + end + }) +end + +sourcet["until-closed"] = function(sock) + local done + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if done then return nil end + local chunk, err, partial = sock:receive(socket.BLOCKSIZE) + if not err then return chunk + elseif err == "closed" then + sock:close() + done = 1 + return partial + else return nil, err end + end + }) +end + + +sourcet["default"] = sourcet["until-closed"] + +source = choose(sourcet) +