summaryrefslogtreecommitdiffhomepage
path: root/src/sst.c
diff options
context:
space:
mode:
authorMichael Smith <mikesmiffy128@gmail.com>2024-08-03 16:11:57 +0100
committerMichael Smith <mikesmiffy128@gmail.com>2024-08-22 00:01:06 +0100
commit44902cb49cd51e2bb2f1cef05cb3c0e799b83434 (patch)
treeb64af413b10c32173aa535df22b5ee4162eb0290 /src/sst.c
parent01ec55edd9f767bebb1222c88f0e53e9cf8b2d59 (diff)
Rework OS abstractions
- As much as possible avoid dragging system headers into translation units. This should avoid namespace pollution and, hopefully, speed up builds a little bit. - Avoid leaning on the UCRT so much on Windows - prefer native win32 calls and native file handles except where doing so is inconvenient (in particular, for stat(), which we might try and replace later). - Also, switch from SystemFunction036 to ProcessPrng on Windows. This requires us to generate a stub for bcryptprimitives.dll because Microsoft haven't bothered to provide a link library, but the function is better-documented and seems to be a more direct under-the-hood call as well. Apparently it's what's used by the major web browsers these days, which seems like a good indication it's stable and trusted. - Lastly, remove a bunch of functions and macros and stuff that weren't actually being used. It seems good to try and keep the scope of OS-dependent stuff relatively contained and only add to it when actually required.
Diffstat (limited to 'src/sst.c')
-rw-r--r--src/sst.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/src/sst.c b/src/sst.c
index de04b88..ce80032 100644
--- a/src/sst.c
+++ b/src/sst.c
@@ -14,13 +14,14 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef _WIN32
-#include <stdlib.h> // unsetenv
-#endif
#include <string.h>
#ifdef _WIN32
+#include <Windows.h>
#include <shlwapi.h>
+#else
+#include <stdlib.h> // unsetenv
+#include <sys/uio.h>
#endif
#include "con_.h"
@@ -74,8 +75,6 @@ static void *ownhandle(void) {
}
return cached;
}
-
-struct gnu_link_map *_os_lmbase = 0; // XXX: stupid place to put this, oh well
#endif
#ifdef _WIN32
@@ -99,7 +98,7 @@ DEF_CCMD_HERE(sst_autoload_enable, "Register SST to load on game startup", 0) {
const os_char *startdir;
if (ifacever == 2) {
startdir = _startdir;
- os_getcwd(_startdir, PATH_MAX); // if this fails, OS devs are all fired.
+ os_getcwd(_startdir);
#ifdef _WIN32
// note: strictly speaking we *could* allow this with an absolute path
// since old builds allow absolute plugin_load paths but since it's less
@@ -112,13 +111,12 @@ DEF_CCMD_HERE(sst_autoload_enable, "Register SST to load on game startup", 0) {
errmsg_errorx("path to game is too long");
return;
}
- memcpy(_startdir + len,
#ifdef _WIN32
- L"\\bin", // PathRelativePathToW actually NEEDS a backslash, UGH
+ // PathRelativePathToW actually NEEDS a backslash, UGH
+ os_spancopy(_startdir + len, L"\\bin", 5);
#else
- "/bin",
+ os_spancopy(_startdir + len, L"/bin", 5);
#endif
- 5 * sizeof(os_char));
}
else /* ifacever == 3 */ {
// newer games load from the mod dir instead of engine bin, and search
@@ -143,8 +141,17 @@ DEF_CCMD_HERE(sst_autoload_enable, "Register SST to load on game startup", 0) {
errmsg_errorsys("couldn't compute a relative path");
return;
}
- // arbitrary aesthetic judgement
- for (ushort *p = relpath; *p; ++p) if (*p == L'\\') *p = L'/';
+ // arbitrary aesthetic judgement - use forward slashes. while we're at it,
+ // also make sure there's no unicode in there, just in case...
+ int rellen = 0;
+ for (ushort *p = relpath; *p; ++p, ++rellen) {
+ if (*p > 127) {
+ errmsg_errorx("mod dir contains Unicode characters which Source "
+ "doesn't handle well - autoload file not created");
+ return;
+ }
+ if (*p == L'\\') *p = L'/';
+ }
#else
const char *p = path, *q = startdir;
int slash = 0;
@@ -177,27 +184,34 @@ c: memcpy(r, p + slash + 1, rellen);
errmsg_errorx("path to VDF is too long");
return;
}
- memcpy(path, gameinfo_gamedir, len * sizeof(*gameinfo_gamedir));
- memcpy(path + len, OS_LIT("/addons"), 8 * sizeof(os_char));
- if (os_mkdir(path) == -1 && errno != EEXIST) {
- errmsg_errorstd("couldn't create %" fS, path);
+ os_spancopy(path, gameinfo_gamedir, len);
+ os_spancopy(path + len, OS_LIT("/addons"), 8);
+ if (!os_mkdir(path) && os_lasterror() != OS_EEXIST) {
+ errmsg_errorsys("couldn't create %" fS, path);
return;
}
- memcpy(path + len + sizeof("/addons") - 1,
+ os_spancopy(path + len + sizeof("/addons") - 1,
OS_LIT("/") OS_LIT(VDFBASENAME) OS_LIT(".vdf"),
- sizeof("/" VDFBASENAME ".vdf") * sizeof(os_char));
- FILE *f = os_fopen(path, OS_LIT("wb"));
- if (!f) {
- errmsg_errorstd("couldn't open %" fS, path);
- return;
- }
- // XXX: oh crap, we're clobbering unicode again. welp, let's continue
- // relying on the theory that the engine would fail to deal with it anyway.
- if (fprintf(f, "Plugin { file \"%" fS "\" }\n", relpath) < 0 ||
- fflush(f) == -1) {
- errmsg_errorstd("couldn't write to %" fS, path);
+ sizeof("/" VDFBASENAME ".vdf"));
+ int f = os_open_write(path);
+ if (f == -1) { errmsg_errorsys("couldn't open %" fS, path); return; }
+#ifdef _WIN32
+ char buf[19 + PATH_MAX];
+ memcpy(buf, "Plugin { file \"", 15);
+ for (int i = 0; i < rellen; ++i) buf[i + 15] = relpath[i];
+ memcpy(buf + 15 + rellen, "\" }\n", 4);
+ if (os_write(f, buf, rellen + 19) == -1) { // blegh
+#else
+ struct iovec iov[3] = {
+ {"Plugin { file \"", 15},
+ {relpath, rellen},
+ {"\" }\n", 4}
+ };
+ if (writev(fd, &iov, 3) == -1) {
+#endif
+ errmsg_errorsys("couldn't write to %" fS, path);
}
- fclose(f);
+ os_close(f);
}
DEF_CCMD_HERE(sst_autoload_disable, "Stop loading SST on game startup", 0) {
@@ -208,11 +222,11 @@ DEF_CCMD_HERE(sst_autoload_disable, "Stop loading SST on game startup", 0) {
errmsg_errorx("path to VDF is too long");
return;
}
- memcpy(path, gameinfo_gamedir, len * sizeof(*gameinfo_gamedir));
- memcpy(path + len, OS_LIT("/addons/") OS_LIT(VDFBASENAME) OS_LIT(".vdf"),
- sizeof("/addons/" VDFBASENAME ".vdf") * sizeof(os_char));
- if (os_unlink(path) == -1 && errno != ENOENT) {
- errmsg_warnstd("couldn't delete %" fS, path);
+ os_spancopy(path, gameinfo_gamedir, len);
+ os_spancopy(path + len, OS_LIT("/addons/") OS_LIT(VDFBASENAME) OS_LIT(".vdf"),
+ sizeof("/addons/" VDFBASENAME ".vdf"));
+ if (!os_unlink(path) && os_lasterror() != OS_ENOENT) {
+ errmsg_warnsys("couldn't delete %" fS, path);
}
}