summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/os-unix.h26
-rw-r--r--src/os-win32.h6
-rw-r--r--src/sst.c2
3 files changed, 21 insertions, 13 deletions
diff --git a/src/os-unix.h b/src/os-unix.h
index 5c3c604..ec9a940 100644
--- a/src/os-unix.h
+++ b/src/os-unix.h
@@ -1,5 +1,5 @@
/*
- * Copyright © 2022 Michael Smith <mikesmiffy128@gmail.com>
+ * Copyright © 2023 Michael Smith <mikesmiffy128@gmail.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -46,14 +46,22 @@ typedef char os_char;
#define os_dlsym dlsym
#ifdef __linux__
-static inline bool os_dlfile(void *m, char *buf, int sz) {
- // NOTE: this might be linux/glibc-specific (I haven't checked every
- // implementation). this is fine as we don't use it in any build-time code,
- // only in the plugin itself. just keep it in mind!
- struct link_map *lm = m;
- ssz len = strlen(lm->l_name) + 1;
- if (ssz > sz) { errno = ENAMETOOLONG; return false; }
- memcpy(buf, lm->l_name, ssz); return true;
+// note: this is glibc-specific. it shouldn't be used in build-time code, just
+// the plugin itself (that really shouldn't be a problem).
+static inline int os_dlfile(void *m, char *buf, int sz) {
+ // private struct hidden behind _GNU_SOURCE. see dlinfo(3) or <link.h>
+ struct gnu_link_map {
+ unsigned long l_addr;
+ const char *l_name;
+ void *l_ld;
+ struct gnu_link_map *l_next, *l_prev;
+ // [more private stuff below]
+ };
+ struct gnu_link_map *lm = m;
+ int ssz = strlen(lm->l_name) + 1;
+ if (ssz > sz) { errno = ENAMETOOLONG; return -1; }
+ memcpy(buf, lm->l_name, ssz);
+ return ssz;
}
#endif
diff --git a/src/os-win32.h b/src/os-win32.h
index 8f554bd..365e2dc 100644
--- a/src/os-win32.h
+++ b/src/os-win32.h
@@ -53,16 +53,16 @@ static inline void *os_dlsym(void *m, const char *s) {
return (void *)GetProcAddress(m, s);
}
-static inline bool os_dlfile(void *m, unsigned short *buf, int sz) {
+static inline int os_dlfile(void *m, unsigned short *buf, int sz) {
unsigned int n = GetModuleFileNameW(m, buf, sz);
- if (n == 0 || n == sz) return false;
+ if (n == 0 || n == sz) return -1;
// get the canonical capitalisation, as for some reason GetModuleFileName()
// returns all lowercase. this doesn't really matter except it looks nicer
GetLongPathNameW(buf, buf, n + 1);
// the drive letter will also be lower case, if it is an actual drive letter
// of course. it should be; I'm not gonna lose sleep over UNC paths and such
if (buf[0] >= L'a' && buf[0] <= L'z' && buf[1] == L':') buf[0] &= ~32u;
- return true;
+ return n;
}
static inline bool os_mprot(void *addr, int len, int fl) {
diff --git a/src/sst.c b/src/sst.c
index fcf26c4..5d21f06 100644
--- a/src/sst.c
+++ b/src/sst.c
@@ -76,7 +76,7 @@ DEF_CCMD_HERE(sst_autoload_enable, "Register SST to load on game startup", 0) {
const os_char *searchdir = ifacever == 3 ?
gameinfo_gamedir : gameinfo_bindir;
os_char path[PATH_MAX];
- if (!os_dlfile(ownhandle(), path, sizeof(path) / sizeof(*path))) {
+ if (os_dlfile(ownhandle(), path, sizeof(path) / sizeof(*path)) == -1) {
// hopefully by this point this won't happen, but, like, never know
errmsg_errordl("failed to get path to plugin");
return;