Merge pull request #290 from rcgordon/autoupdater

Initial shot at writing an ioquake3 autoupdater. Thank you icculus, and everyone who contributed to his patreon! https://www.patreon.com/icculus
This commit is contained in:
Zachary J. Slater 2017-06-02 22:46:22 -10:00 committed by GitHub
commit 87eecd7bc1
7 changed files with 1468 additions and 22 deletions

View file

@ -0,0 +1,86 @@
/*
The code in this file is in the public domain. The rest of ioquake3
is licensed under 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 <windows.h>
# else
# include <unistd.h>
# endif
# include <stdio.h>
# include <string.h>
#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;
STARTUPINFO startinfo;
char cmdline[128];
memset(&procinfo, '\0', sizeof (procinfo));
memset(&startinfo, '\0', sizeof (startinfo));
startinfo.cb = sizeof (startinfo);
sprintf(cmdline, "" AUTOUPDATER_BIN " --waitpid %u", (unsigned int) GetCurrentProcessId());
if (CreateProcessA(AUTOUPDATER_BIN, cmdline, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startinfo, &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';
if (chdir(argv[0]) == -1) {
_exit(1); /* oh well. */
}
#ifdef __APPLE__
if (chdir("../..") == -1) { /* put this at base of app bundle so paths make sense later. */
_exit(1); /* oh well. */
}
#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. */
}

View file

@ -683,6 +683,9 @@ int main( int argc, char **argv )
int i;
char commandLine[ MAX_STRING_CHARS ] = { 0 };
extern void Sys_LaunchAutoupdater(int argc, char **argv);
Sys_LaunchAutoupdater(argc, argv);
#ifndef DEDICATED
// SDL version check