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;  | 
