From 5b17b41e074c78c722d400b0dbbabf885a9417b2 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Sat, 12 Jul 2025 04:16:31 +0300 Subject: [PATCH] Escape translocation on launch so we can update ourselves. --- Cocoa/GBApp.m | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Cocoa/GBApp.m b/Cocoa/GBApp.m index 14bcc16..3702014 100644 --- a/Cocoa/GBApp.m +++ b/Cocoa/GBApp.m @@ -8,6 +8,8 @@ #import #import #import +#include +#include #define UPDATE_SERVER "https://sameboy.github.io" @@ -662,6 +664,14 @@ static uint32_t color_to_int(NSColor *color) } [[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil]; [[NSFileManager defaultManager] removeItemAtPath:contentsTempPath error:nil]; + + // Remove the quarantine flag so we don't have to escape translocation + NSString *bundlePath = [NSBundle mainBundle].bundlePath; + removexattr(bundlePath.UTF8String, "com.apple.quarantine", 0); + for (NSString *path in [[NSFileManager defaultManager] enumeratorAtPath:bundlePath]) { + removexattr([bundlePath stringByAppendingPathComponent:path].UTF8String, "com.apple.quarantine", 0); + }; + _downloadDirectory = nil; atexit_b(^{ execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL); @@ -781,4 +791,27 @@ static uint32_t color_to_int(NSColor *color) - (IBAction)nop:(id)sender { } + +/* This runs before C constructors. If we need to escape translocation, we should + do it ASAP to minimize our launch time. */ + ++ (void)load +{ + if (@available(macOS 10.12, *)) { + /* Detect and escape translocation so we can safely update ourselves */ + if ([[[NSBundle mainBundle] bundlePath] containsString:@"/AppTranslocation/"]) { + const char *mountPath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByDeletingLastPathComponent].UTF8String; + struct statfs *mntbuf; + int mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); + for (unsigned i = 0; i < mntsize; i++) { + if (strcmp(mntbuf[i].f_mntonname, mountPath) == 0) { + NSBundle *origBundle = [NSBundle bundleWithPath:@(mntbuf[i].f_mntfromname)]; + + execl(origBundle.executablePath.UTF8String, origBundle.executablePath.UTF8String, NULL); + break; + } + } + } + } +} @end