diff --git a/Makefile b/Makefile index 73db3f73..964d3a76 100644 --- a/Makefile +++ b/Makefile @@ -1694,6 +1694,7 @@ Q3OBJ = \ $(B)/client/sdl_snd.o \ \ $(B)/client/con_log.o \ + $(B)/client/sys_autoupdater.o \ $(B)/client/sys_main.o ifdef MINGW @@ -2230,6 +2231,7 @@ Q3DOBJ = \ $(B)/ded/null_snddma.o \ \ $(B)/ded/con_log.o \ + $(B)/ded/sys_autoupdater.o \ $(B)/ded/sys_main.o ifeq ($(ARCH),x86) diff --git a/code/sys/sys_autoupdater.c b/code/sys/sys_autoupdater.c new file mode 100644 index 00000000..56873d4e --- /dev/null +++ b/code/sys/sys_autoupdater.c @@ -0,0 +1,77 @@ +/* +The code in this file is in the public domain. The rest of ioquake3 +is licensed until the GPLv2. Do not mingle code, please! +*/ + +#ifdef USE_AUTOUPDATER +# ifndef AUTOUPDATER_BIN +# error The build system should have defined AUTOUPDATER_BIN +# endif + +# ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN 1 +# include +# else +# include +# endif + +# include +# include +#endif + +void Sys_LaunchAutoupdater(int argc, char **argv) +{ +#ifdef USE_AUTOUPDATER + #ifdef _WIN32 + { + /* We don't need the Unix pipe() tapdance here because Windows lets children wait on parent processes. */ + PROCESS_INFORMATION procinfo; + char cmdline[128]; + sprintf(cmdline, AUTOUPDATER_BIN " --waitpid %u", (unsigned int) GetCurrentProcessId()); + if (CreateProcessA(AUTOUPDATER_BIN, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &procinfo)) + { + /* close handles now so child cleans up immediately if nothing to do */ + CloseHandle(procinfo.hProcess); + CloseHandle(procinfo.hThread); + } + } + #else + int updater_pipes[2]; + if (pipe(updater_pipes) == 0) + { + pid_t pid = fork(); + if (pid == -1) /* failure, oh well. */ + { + close(updater_pipes[0]); + close(updater_pipes[1]); + } + else if (pid == 0) /* child process */ + { + close(updater_pipes[1]); /* don't need write end. */ + if (dup2(updater_pipes[0], 3) != -1) + { + char pidstr[64]; + char *ptr = strrchr(argv[0], '/'); + if (ptr) + *ptr = '\0'; + chdir(argv[0]); + #ifdef __APPLE__ + chdir("../.."); /* put this at base of app bundle so paths make sense later. */ + #endif + snprintf(pidstr, sizeof (pidstr), "%lld", (long long) getppid()); + execl(AUTOUPDATER_BIN, AUTOUPDATER_BIN, "--waitpid", pidstr, NULL); + } + _exit(0); /* oh well. */ + } + else /* parent process */ + { + /* leave the write end open until we terminate so updater can block on it. */ + close(updater_pipes[0]); + } + } + #endif +#endif + + (void) argc; (void) argv; /* possibly unused. Pacify compilers. */ +} + diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c index 5f1d4fc4..44d74f92 100644 --- a/code/sys/sys_main.c +++ b/code/sys/sys_main.c @@ -31,15 +31,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include -#ifdef USE_AUTOUPDATER -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN 1 -#include -#else -#include -#endif -#endif - #ifndef DEDICATED #ifdef USE_LOCAL_HEADERS # include "SDL.h" @@ -668,62 +659,8 @@ int main( int argc, char **argv ) int i; char commandLine[ MAX_STRING_CHARS ] = { 0 }; -#ifdef USE_AUTOUPDATER -{ - #ifndef AUTOUPDATER_BIN - #error The build system should have defined AUTOUPDATER_BIN - #endif - - #ifdef _WIN32 - { - /* We don't need the Unix pipe() tapdance here because Windows lets children wait on parent processes. */ - PROCESS_INFORMATION procinfo; - char cmdline[128]; - Com_sprintf(cmdline, sizeof (cmdline), AUTOUPDATER_BIN " --waitpid %u", (unsigned int) GetCurrentProcessId()); - if (CreateProcessA(AUTOUPDATER_BIN, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &procinfo)) - { - /* close handles now so child cleans up immediately if nothing to do */ - CloseHandle(procinfo.hProcess); - CloseHandle(procinfo.hThread); - } - } - #else - int updater_pipes[2]; - if (pipe(updater_pipes) == 0) - { - pid_t pid = fork(); - if (pid == -1) /* failure, oh well. */ - { - close(updater_pipes[0]); - close(updater_pipes[1]); - } - else if (pid == 0) /* child process */ - { - close(updater_pipes[1]); /* don't need write end. */ - if (dup2(updater_pipes[0], 3) != -1) - { - char pidstr[64]; - char *ptr = strrchr(argv[0], '/'); - if (ptr) - *ptr = '\0'; - chdir(argv[0]); - #ifdef __APPLE__ - chdir("../.."); /* put this at base of app bundle so paths make sense later. */ - #endif - snprintf(pidstr, sizeof (pidstr), "%lld", (long long) getppid()); - execl(AUTOUPDATER_BIN, AUTOUPDATER_BIN, "--waitpid", pidstr, NULL); - } - _exit(0); /* oh well. */ - } - else /* parent process */ - { - /* leave the write end open until we terminate so updater can block on it. */ - close(updater_pipes[0]); - } - } - #endif -} -#endif + extern void Sys_LaunchAutoupdater(int argc, char **argv); + Sys_LaunchAutoupdater(argc, argv); #ifndef DEDICATED // SDL version check