macOS: Add an entry point to use that works even if run via a symlink

Fixes #1539
This commit is contained in:
Kovid Goyal 2019-05-11 10:25:06 +05:30
parent 268e5cef3b
commit bdeec61266
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 51 additions and 0 deletions

View File

@ -744,6 +744,10 @@ Categories=System;TerminalEmulator;
os.rename('../lib', 'Frameworks') os.rename('../lib', 'Frameworks')
if not os.path.exists(logo_dir): if not os.path.exists(logo_dir):
raise SystemExit('The kitty logo has not been generated, you need to run logo/make.py') raise SystemExit('The kitty logo has not been generated, you need to run logo/make.py')
cmd = [env.cc] + ['-Wall', '-Werror'] + [
'symlink-deref.c', '-o', os.path.join('MacOS', 'kitty-deref-symlink')]
run_tool(cmd)
subprocess.check_call([ subprocess.check_call([
'iconutil', '-c', 'icns', logo_dir, '-o', 'iconutil', '-c', 'icns', logo_dir, '-o',
os.path.join('Resources', os.path.basename(logo_dir).partition('.')[0] + '.icns') os.path.join('Resources', os.path.basename(logo_dir).partition('.')[0] + '.icns')

47
symlink-deref.c Normal file
View File

@ -0,0 +1,47 @@
/*
* symlink-deref.c
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include <unistd.h>
#include <sys/stat.h>
#include <mach-o/dyld.h>
#include <sys/syslimits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <unistd.h>
static inline bool
safe_realpath(const char* src, char *buf, size_t buf_sz) {
char* ans = realpath(src, NULL);
if (ans == NULL) return false;
snprintf(buf, buf_sz, "%s", ans);
free(ans);
return true;
}
static inline bool
read_exe_path(char *exe, size_t buf_sz) {
(void)buf_sz;
uint32_t size = PATH_MAX;
char apple[PATH_MAX+1] = {0};
if (_NSGetExecutablePath(apple, &size) != 0) { fprintf(stderr, "Failed to get path to executable\n"); return false; }
if (!safe_realpath(apple, exe, buf_sz)) { fprintf(stderr, "realpath() failed on the executable's path\n"); return false; }
return true;
}
int
main(int argc, char *argv[]) {
char exe[PATH_MAX+1] = {0};
char real_exe[PATH_MAX+1] = {0};
if (!read_exe_path(exe, sizeof(exe))) return 1;
snprintf(real_exe, sizeof(real_exe), "%s/kitty", dirname(exe));
return execv(real_exe, argv);
}