diff options
-rw-r--r-- | src/os-unix.h | 26 | ||||
-rw-r--r-- | src/os-win32.h | 6 | ||||
-rw-r--r-- | src/sst.c | 2 |
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) { @@ -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; |