Skip to content

Commit

Permalink
Fix crash when restarting app with executable path containing spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
IonAgorria committed Sep 25, 2023
1 parent 1d41eb6 commit 5dfe1d3
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 24 deletions.
14 changes: 9 additions & 5 deletions Source/Game/Runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,15 +1002,15 @@ int SDL_main(int argc, char *argv[])

//Copy the args that launched this game
std::vector<char*> exec_argv;
for (int i = 0; i < __argc; ++i) {
if (startsWith(__argv[i], "tmp_")) {
for (int i = 0; i < app_argc; ++i) {
if (startsWith(app_argv[i], "tmp_")) {
//These are passed internally and are not supposed to pass into next instance
continue;
}

size_t len = strlen(__argv[i]) + 1;
size_t len = app_argv[i].length() + 1;
char* str = static_cast<char*>(malloc(len));
strcpy(str, __argv[i]);
strcpy(str, app_argv[i].c_str());
exec_argv.emplace_back(str);
}

Expand All @@ -1037,9 +1037,13 @@ int SDL_main(int argc, char *argv[])
printf("\n");
int ret = 0;
for (int i = 0; i < 2; ++i) {
#ifdef _WIN32
ret = _execv(exec_argv[0], exec_argv.data());
#else
ret = execv(exec_argv[0], exec_argv.data());
#endif
//We shouldn't reach this point
printf("Error at launch %d\n", ret);
printf("Error at launch %d errno %d\n", ret, errno);
}

ErrH.Abort("Error restarting the application", XERR_USER, ret);
Expand Down
4 changes: 2 additions & 2 deletions Source/XPrm/MemStat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ void allocation_tracking(char* title, AllocationAccumulator* accumulator)
opened = 1;

disabled = 1;
for(int i = 1;i < __argc;i++)
if(strstr(__argv[i], "memory"))
for(int i = 1;i < app_argc;i++)
if(strstr(app_argv[i], "memory"))
disabled = 0;
if(disabled)
return;
Expand Down
41 changes: 28 additions & 13 deletions Source/XTool/XUTIL/XUTIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@

std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> utf8cvt;

#ifndef _WIN32
bool argcv_setup_done = false;
int __argc = 0;
std::vector<const char*> __argv;
#endif
int app_argc = 0;
std::vector<std::string> app_argv;

static unsigned int XRndValue = 83838383;

Expand All @@ -44,14 +42,32 @@ unsigned int XRndGet()
}

void setup_argcv(int argc, char *argv[]) {
#ifndef _WIN32
for(int i = 0; i < argc; i ++){
size_t i = 0;
#ifdef _WIN32
//We need to assemble the program path that might contain whitespaces
//The rest will be processed as usual
std::string program;
for(; i < argc; i ++){
if (0 < i) {
program += " ";
}
program += argv[i];
std::string lower = string_to_lower(argv[i]);
if (endsWith(lower, ".exe")) {
//Found the end of program
break;
}
}
app_argv.emplace_back(program);
app_argc++;
#endif
//Pick the args
for(; i < argc; i ++){
//printf("%d %s\n", i, argv[i]);
__argv.push_back(argv[i]);
__argc++;
app_argv.emplace_back(argv[i]);
app_argc++;
}
argcv_setup_done = true;
#endif
}

void decode_version(const char* version_str, uint16_t version[3]) {
Expand Down Expand Up @@ -94,15 +110,14 @@ int compare_versions(const uint16_t left[3], const char* right) {
}

const char* check_command_line(const char* switch_str) {
#ifndef _WIN32
if (!argcv_setup_done) {
fprintf(stderr, "Called check_command_line %s before setup_argcv\n", switch_str);
xassert(0);
}
#endif
std::string switch_key(switch_str);
switch_key += "=";
for(int i = 1; i < __argc; i ++){
const char* arg = __argv[i];
for(int i = 1; i < app_argc; i ++){
const char* arg = app_argv[i].c_str();
if (startsWith(arg, "tmp_")) {
arg += 4;
}
Expand Down
6 changes: 2 additions & 4 deletions Source/XTool/xutl.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ uint64_t clock_us();
#include <vector>
#include <filesystem>

#ifndef _WIN32
//Hacky way to "store" argc/argv so they can be accessed later like in Windows
extern int __argc;
extern std::vector<const char*> __argv;
#endif
extern int app_argc;
extern std::vector<std::string> app_argv;

///Stores argc/argv from main()
void setup_argcv(int argc, char *argv[]);
Expand Down

0 comments on commit 5dfe1d3

Please sign in to comment.