diff --git a/tools/blisp/src/cmd/write.c b/tools/blisp/src/cmd/write.c index 5c44453..2d146be 100644 --- a/tools/blisp/src/cmd/write.c +++ b/tools/blisp/src/cmd/write.c @@ -26,6 +26,29 @@ static struct arg_lit* reset; static struct arg_end* end; static void* cmd_write_argtable[6]; +#ifdef __APPLE__ +// Ugh. This stuff is just so messy without C++17 or Qt... +// These are not thread safe, but it doesn't place the responsibility +// to free an allocated buffer on the caller.nn +#include +#include +#include + +static void get_executable_path(char* buffer_out, uint32_t max_size) { + assert (max_size >= PATH_MAX); // n.b. 1024 on MacOS. 4K on most Linux. + + char raw_path_name[PATH_MAX]; // $HOME/../../var/tmp/x + char real_path_name[PATH_MAX]; // /var/tmp/x + uint32_t raw_path_size = sizeof(raw_path_name); + + if(!_NSGetExecutablePath(raw_path_name, &raw_path_size)) { + realpath(raw_path_name, real_path_name); + } + // *real_path_name is appropriately sized and null terminated. + strcpy(buffer_out, real_path_name); +} +#endif + ssize_t get_binary_folder(char* buffer, uint32_t buffer_size) { #ifdef __linux__ @@ -33,6 +56,9 @@ get_binary_folder(char* buffer, uint32_t buffer_size) { return -1; } char* pos = strrchr(buffer, '/'); +#elif defined(__APPLE__) + get_executable_path(buffer, buffer_size); + char* pos = strrchr(buffer, '/'); #else if (GetModuleFileName(NULL, buffer, buffer_size) <= 0) { return -1; @@ -477,4 +503,4 @@ cmd_write_free() { } struct cmd cmd_write - = { "write", cmd_write_args_init, cmd_write_parse_exec, cmd_write_args_print_syntax, cmd_write_free }; \ No newline at end of file + = { "write", cmd_write_args_init, cmd_write_parse_exec, cmd_write_args_print_syntax, cmd_write_free };