get_program_exe_path() is subject to overflow on long paths and it only works on Linux, Cygwin, and macOS.
I ported the libsir _sir_getappfilename function to work on 17 platforms: Linux, Android, macOS, IBM AIX, IBM i (OS/400), Windows, Cygwin, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, GNU/Hurd, Haiku, Solaris, illumos, SerenityOS, and Emscripten.
This was especially complicated to get working right without too many edge cases on OpenBSD, AIX, and IBM i. This functionality on all platforms is heavily tested and proven.
You can use actually use it as a direct drop-in replacement.
Here is a patch if you want to try it. It assumes libsir in ./libsir:
Details
diff --git a/GNUmakefile b/GNUmakefile
index 2c10fa8..026f81f 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,13 +1,13 @@
CC?=cc
-CFLAGS?=-O3 -flto -Wall -g -Werror=implicit-function-declaration -Werror=int-conversion
-LDLIBS?=-lm
+CFLAGS?=-O3 -flto -Wall -g -Werror=implicit-function-declaration -Werror=int-conversion -I./libsir/include
+LDLIBS?=-L./libsir/build/lib -lsir_s -lm
INSTALL?=install
PREFIX?=/usr
OBJS=\
cpu.o\
loader.o\
main.o\
codepage.o\
dosnames.o\
dis.o\
diff --git a/src/utils.c b/src/utils.c
index 138029a..10dcbed 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,38 +1,9 @@
/* Platform dependent utility functions */
-#include "utils.h"
-#include "dbg.h"
-#include <unistd.h>
-#ifdef __APPLE__
-#include <mach-o/dyld.h>
-#endif
+#include "sir.h"
+#include "sir/filesystem.h"
const char *get_program_exe_path(void)
{
-#if defined(__linux__) || defined(__CYGWIN__)
-
- static char exe_path[4096] = {
- 0,
- };
- if(readlink("/proc/self/exe", exe_path, 4095) == -1)
- return 0;
- else
- return exe_path;
-
-#elif defined(__APPLE__)
-
- static char exe_path[4096] = {
- 0,
- };
- uint32_t length = 4095;
- if(_NSGetExecutablePath(exe_path, &length))
- return 0;
- else
- return exe_path;
-#else
-
- /* No implementation */
- return 0;
-
-#endif
+ return _sir_getappfilename();
}
I know you probably don't want to bring in libsir as a dependency/subtree/submodule (although it does have a lot of other nice features you could use).
It is actually trivial to get Linux, Android, NetBSD, Solaris, illumos, Dragonfly BSD, Hurd, and SerenityOS working. I've made a PR for that (#97).
Haiku will be easy too.
Extracting the functionality needed to implement this for OpenBSD, AIX, and IBM i (OS/400) — without libsir — would be a much larger project, but is of course possible.
get_program_exe_path()is subject to overflow on long paths and it only works on Linux, Cygwin, and macOS.I ported the libsir
_sir_getappfilenamefunction to work on 17 platforms: Linux, Android, macOS, IBM AIX, IBM i (OS/400), Windows, Cygwin, FreeBSD, NetBSD, OpenBSD, DragonFly BSD, GNU/Hurd, Haiku, Solaris, illumos, SerenityOS, and Emscripten.This was especially complicated to get working right without too many edge cases on OpenBSD, AIX, and IBM i. This functionality on all platforms is heavily tested and proven.
You can use actually use it as a direct drop-in replacement.
Here is a patch if you want to try it. It assumes
libsirin./libsir:Details
I know you probably don't want to bring in
libsiras a dependency/subtree/submodule (although it does have a lot of other nice features you could use).It is actually trivial to get Linux, Android, NetBSD, Solaris, illumos, Dragonfly BSD, Hurd, and SerenityOS working. I've made a PR for that (#97).
Haiku will be easy too.
Extracting the functionality needed to implement this for OpenBSD, AIX, and IBM i (OS/400) — without libsir — would be a much larger project, but is of course possible.