Skip to content

Commit

Permalink
macOS: Add an entry point to use that works even if run via a symlink
Browse files Browse the repository at this point in the history
Fixes #1539
  • Loading branch information
kovidgoyal committed May 11, 2019
1 parent 268e5ce commit bdeec61
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
4 changes: 4 additions & 0 deletions setup.py
Expand Up @@ -744,6 +744,10 @@ def src_ignore(parent, entries):
os.rename('../lib', 'Frameworks')
if not os.path.exists(logo_dir):
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([
'iconutil', '-c', 'icns', logo_dir, '-o',
os.path.join('Resources', os.path.basename(logo_dir).partition('.')[0] + '.icns')
Expand Down
47 changes: 47 additions & 0 deletions symlink-deref.c
@@ -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);
}

0 comments on commit bdeec61

Please sign in to comment.