summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMichael Smith <mikesmiffy128@gmail.com>2023-05-21 21:48:52 +0100
committerMichael Smith <mikesmiffy128@gmail.com>2023-05-21 22:11:16 +0100
commit2ba71f27c46dc38b76e932b1b1967d96a9b9f107 (patch)
tree0b38c40d0e562e4d4e6cf39aff40bcefee204c4a /src
parent5dff423338e82a8d9a201534f3f10aee7de0ad56 (diff)
Improve os_dlfile() interface
Might as well return the length since we have it anyway. Also this maybe fixes the totally busted Linux code but it's still untested and probably doesn't work for reasons that will be discovered later on.
Diffstat (limited to 'src')
-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;