From f7cc6b4dcc164403d62c9b48ae37f1c4c20f4b4f Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 30 Dec 2021 16:18:25 +0000 Subject: Split up os.h, inline functions and fix some typos --- src/build/mkgamedata.c | 2 +- src/demorec.c | 2 +- src/kv.h | 2 +- src/os-unix.h | 66 +++++++++++++++++++++++++++++ src/os-win32.h | 100 ++++++++++++++++++++++++++++++++++++++++++++ src/os.c | 56 ------------------------- src/os.h | 110 +++++++------------------------------------------ 7 files changed, 183 insertions(+), 155 deletions(-) create mode 100644 src/os-unix.h create mode 100644 src/os-win32.h delete mode 100644 src/os.c (limited to 'src') diff --git a/src/build/mkgamedata.c b/src/build/mkgamedata.c index 87de07d..bd7b2d5 100644 --- a/src/build/mkgamedata.c +++ b/src/build/mkgamedata.c @@ -20,8 +20,8 @@ #include "../intdefs.h" #include "../kv.h" +#include "../noreturn.h" #include "../os.h" -#include "../noreturn.h" // must come after os.h due to __declspec(noreturn) #ifdef _WIN32 #define fS "S" diff --git a/src/demorec.c b/src/demorec.c index dda692f..76e7f00 100644 --- a/src/demorec.c +++ b/src/demorec.c @@ -31,7 +31,7 @@ #include "vcall.h" #define SIGNONSTATE_SPAWN 5 // ready to receive entity packets -#define SIGNONSTATE_FULL 6 // fully connected, first non-delta packet receieved +#define SIGNONSTATE_FULL 6 // fully connected, first non-delta packet received typedef void (*VCALLCONV f_StopRecording)(void *); typedef void (*VCALLCONV f_SetSignonState)(void *, int); diff --git a/src/kv.h b/src/kv.h index 6de2c67..4ed459b 100644 --- a/src/kv.h +++ b/src/kv.h @@ -49,7 +49,7 @@ struct kv_parser { #define KV_PARSER_ERROR -1 /* - * These are the tokens that can be receieved by a kv_parser_cb (below). + * These are the tokens that can be received by a kv_parser_cb (below). * The x-macro and string descriptions are given to allow for easy debug * stringification. Note that this "parser" is really just lexing out these * tokens - handling the actual structure of the file should be done in the diff --git a/src/os-unix.h b/src/os-unix.h new file mode 100644 index 0000000..4ca0d4a --- /dev/null +++ b/src/os-unix.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2021 Michael Smith + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* Unix-specific definitions for os.h - don't include this directly! */ + +#ifdef __GNUC__ +#define EXPORT __attribute__((visibility("default"))) +#else +#define EXPORT int novis[-!!"visibility attribute requires Clang or GCC"]; +#endif +#define IMPORT + +typedef char os_char; +#define OS_LIT(x) x +#define os_snprintf snprintf +#define os_strchr strchr +#define os_strcmp strcmp +#define os_strcpy strcpy +#define os_strlen strlen +#define os_fopen fopen +#define os_open open +#define os_access access +#define os_stat stat +#define os_getenv getenv + +#define OS_DLSUFFIX ".so" + +#define OS_MAIN main + +#define os_dlsym dlsym + +// unix mprot flags are much nicer but cannot be defined in terms of the windows +// ones, so we use the windows ones and define them in terms of the unix ones. +// another victory for stupid! +#define PAGE_NOACCESS 0 +#define PAGE_READONLY PROT_READ +#define PAGE_READWRITE PROT_READ | PROT_WRITE +#define PAGE_EXECUTE_READ PROT_READ | PROT_EXEC +#define PAGE_EXECUTE_READWRITE PROT_READ | PROT_WRITE | PROT_EXEC + +static inline bool os_mprot(void *addr, int len, int fl) { + // round down address and round up size + addr = (void *)((unsigned long)addr & ~(4095)); + len = len + 4095 & ~(4095); + return mprotect(addr, len, fl) != -1; +} + +static inline void os_randombytes(void *buf, int sz) { + // if this call fails, the system is doomed, so loop until success and pray. + while (getentropy(buf, sz) == -1); +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/os-win32.h b/src/os-win32.h new file mode 100644 index 0000000..51d2dc2 --- /dev/null +++ b/src/os-win32.h @@ -0,0 +1,100 @@ +/* + * Copyright © 2021 Michael Smith + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* Windows-specific definitions for os.h - don't include this directly! */ + +#define IMPORT __declspec(dllimport) // only needed for variables +#define EXPORT __declspec(dllexport) + +typedef unsigned short os_char; +#define _OS_CAT(L, x) L##x +#define OS_LIT(x) _OS_CAT(L, x) + +#define os_snprintf _snwprintf +#define os_strchr wcschr +#define os_strcmp wcscmp +#define os_strcpy wcscpy +#define os_strlen wcslen +#define strncasecmp _strnicmp // stupid! + +#define os_fopen _wfopen +// yuck :( +#define _os_open3(path, flags, mode) _wopen((path), (flags) | _O_BINARY, (mode)) +#define _os_open2(path, flags) _wopen((path), (flags) | _O_BINARY) +#define _os_open(a, b, c, x, ...) x +#define os_open(...) _os_open(__VA_ARGS__, _os_open3, _os_open2, _)(__VA_ARGS__) +#define os_access _waccess +// ucrt defines __stat64 to _stat64. we want _wstat64 to be the actual function +#define _stat64(path, buf) _wstat64(path, buf) +#define os_stat _stat64 +#define os_getenv _wgetenv + +#define OS_DLSUFFIX ".dll" + +#define OS_MAIN wmain + +static inline void *os_dlsym(void *m, const char *s) { + return (void *)GetProcAddress(m, s); +} + +static inline bool os_mprot(void *addr, int len, int fl) { + unsigned long old; + return !!VirtualProtect(addr, len, fl, &old); +} + +// SystemFunction036 is the *real* name of "RtlGenRandom," and is also +// incorrectly defined in system headers. Yay. +int __stdcall SystemFunction036(void *buf, unsigned long sz); + +static inline void os_randombytes(void *buf, int sz) { + // if this call fails, the system is doomed, so loop until success and pray. + while (!SystemFunction036(buf, sz)); +} + +/* Further Windows-specific workarounds because Windows is great */ + +#ifndef PATH_MAX +// XXX: win32/crt has this dumb 260 limit even though the actual kernel imposes +// no limit (though apparently NTFS has a limit of 65535). Theoerically we could +// do some memes with UNC paths to extend it to at least have parity with Unix +// PATH_MAX (4096), but for now we just kind of accept that Windows is a +// disaster. +#define PATH_MAX MAX_PATH +#endif + +// why does Windows prefix so many things with underscores? +#define alloca _alloca +#define read _read +#define write _write +#define close _close +#define O_RDONLY _O_RDONLY +#define O_RDWR _O_RDWR +#define O_CLOEXEC _O_NOINHERIT // and why did they rename this!? +#define O_CREAT _O_CREAT +#define O_EXCL _O_EXCL +// missing access() flags +#define F_OK 0 +#define R_OK 4 +#define W_OK 2 +#define X_OK R_OK // there's no actual X bit, just pretend + +// just dump this boilerplate here as well, I spose +#define OS_WINDOWS_ERROR(arrayname) \ + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), \ + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), arrayname, \ + sizeof(arrayname), 0) + +// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/os.c b/src/os.c deleted file mode 100644 index 96e3c48..0000000 --- a/src/os.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright © 2021 Michael Smith - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "intdefs.h" -#include "os.h" - -#ifdef _WIN32 -// SystemFunction036 is the *real* name of "RtlGenRandom," and is also -// incorrectly defined in system headers. Yay, Windows. -int __stdcall SystemFunction036(void *buf, ulong sz); -#endif - -bool os_mprot(void *addr, int len, int fl) { -#ifdef _WIN32 - ulong old; - return !!VirtualProtect(addr, len, fl, &old); -#else - // round down address and round up size - addr = (void *)((ulong)addr & ~(4095)); - len = len + 4095 & ~(4095); - return mprotect(addr, len, fl) != -1; -#endif -} - -#ifdef _WIN32 -void *os_dlsym(void *m, const char *s) { - return (void *)GetProcAddress(m, s); -} -#endif - -void os_randombytes(void *buf, int sz) { - // if these calls ever fail, the system is fundamentally broken with no - // recourse, so just loop until success. hopefully nothing will go wrong. -#ifdef _WIN32 - while (!SystemFunction036(buf, sz)); -#else - while (getentropy(buf, sz) == -1); -#endif -} - -// vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/os.h b/src/os.h index c74d2d0..654e754 100644 --- a/src/os.h +++ b/src/os.h @@ -23,8 +23,6 @@ * Here we declare an absolute ton of wrappers, macros, compatibility shims, * reimplementations and so on to try in vain to sweep the inconsistencies * between Windows and not-Windows under the rug. - * - * If this file gets any bigger it might need to be split up a bit... */ #include @@ -33,112 +31,32 @@ #define WIN32_LEAN_AND_MEAN #include #include +// DUMB HACK: noreturn.h is alphabetically before os.h so including it after +// looks weird and inconsistent. including it before breaks Windows.h though +// because of __declspec(noreturn). Undef for now, and restore at the end of +// this header. +#undef noreturn #include +#include #else #include #include +#include +#include #include #include #endif -#include "intdefs.h" - +// Things were getting unwieldy so they're now split into these headers... #ifdef _WIN32 - -#define IMPORT __declspec(dllimport) // only needed for variables -#define EXPORT __declspec(dllexport) -void *os_dlsym(void *mod, const char *sym); -#define os_char ushort -#define _OS_CAT(L, x) L##x -#define OS_LIT(x) _OS_CAT(L, x) -#define os_snprintf _snwprintf -#define os_strchr wcschr -#define os_strcmp wcscmp -#define os_strcpy wcscpy -#define os_strlen wcslen -#define strncasecmp _strnicmp // stupid! -#define OS_DLSUFFIX ".dll" -#ifndef PATH_MAX -// XXX win32/crt has this dumb 260 limit even though the actual kernel imposes -// no limit (though apparently NTFS has a limit of 65535). Theoerically we could -// do some memes with UNC paths to extend it to at least have parity with Unix -// PATH_MAX (4096), but for now we just kind of accept that Windows is a -// disaster. -#define PATH_MAX MAX_PATH +#include "os-win32.h" +// DUMB HACK part 2: restore what the #including source file had asked for +#ifdef INC_NORETURN_H +#define noreturn _Noreturn void #endif -#define os_fopen _wfopen -// yuck :( -#define _os_open3(path, flags, mode) _wopen((path), (flags) | _O_BINARY, (mode)) -#define _os_open2(path, flags) _wopen((path), (flags) | _O_BINARY) -#define _os_open(a, b, c, x, ...) x -#define os_open(...) _os_open(__VA_ARGS__, _os_open3, _os_open2, _)(__VA_ARGS__) -#define os_access _waccess -#define os_stat _stat64 -// ucrt defines __stat64 to _stat64. we want _wstat64 to be the actual function -#define _stat64(path, buf) _wstat64(path, buf) -// why exactly _does_ windows prefix so many things with underscores? -#define read _read -#define write _write -#define close _close -#define O_RDONLY _O_RDONLY -#define O_RDWR _O_RDWR -#define O_CLOEXEC _O_NOINHERIT -#define O_CREAT _O_CREAT -#define O_EXCL _O_EXCL -#define F_OK 0 -#define R_OK 4 -#define W_OK 2 -#define X_OK R_OK // there's no actual X bit -#define alloca _alloca -#define os_getenv _wgetenv -#define OS_MAIN wmain -// just dump this boilerplate here as well, I spose -#define OS_WINDOWS_ERROR(arrayname) \ - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), \ - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), arrayname, \ - sizeof(arrayname), 0) - -#else - -#ifdef __GNUC__ -#define EXPORT __attribute__((visibility("default"))) #else -#define EXPORT int novis[-!!"visibility attribute requires Clang or GCC"]; +#include "os-unix.h" #endif -#define IMPORT -#define os_dlsym dlsym -#define os_char char -#define OS_LIT(x) x -#define os_snprintf snprintf -#define os_strchr strchr -#define os_strcmp strcmp -#define os_strcpy strcpy -#define os_strlen strlen -#define OS_DLSUFFIX ".so" -#define os_fopen fopen -#define os_open open -#define os_access access -#define os_stat stat -// unix mprot flags are much nicer but cannot be defined in terms of the windows -// ones, so we use the windows ones and define them in terms of the unix ones. -// another victory for stupid! -#define PAGE_NOACCESS 0 -#define PAGE_READONLY PROT_READ -#define PAGE_READWRITE PROT_READ | PROT_WRITE -#define PAGE_EXECUTE_READ PROT_READ | PROT_EXEC -#define PAGE_EXECUTE_READWRITE PROT_READ | PROT_WRITE | PROT_EXEC -#define os_getenv getenv -#define OS_MAIN main - -#endif - -bool os_mprot(void *addr, int len, int fl); -/* - * NOTE: this should be called with a reasonably small buffer (e.g., the size of - * a private key). The maximum size of the buffer on Linux is 256, on Windows - * it's God Knows What. - */ -void os_randombytes(void *buf, int len); #endif -- cgit v1.2.3