Skip to content

Instantly share code, notes, and snippets.

@u8sand
Last active October 26, 2016 14:32
Show Gist options
  • Save u8sand/df0544b0c82f4bc02db38531ac12cb67 to your computer and use it in GitHub Desktop.
Save u8sand/df0544b0c82f4bc02db38531ac12cb67 to your computer and use it in GitHub Desktop.
A proof of concept auto-update mechanism
// Auto-update proof of concept
// embedding the update step into the
// current and new executables ahead of
// time, we don't need any extra scripts.
// It works by calling the new executable
// to rename the old one, and call the
// old one to rename the new one, execute
// it and exit. Finally the renamed new
// one removes the old one and runs normally.
// Process:
// self.new.exe -u1 self
// mv self{,.old}.exe
// self.old.exe -u2 new
// mv self.{new,}.exe
// self.exe -u3 self.old.exe
// rm self.old.exe
#include <iostream>
#include <string>
#include <fstream>
#include <cstdio>
#include <unistd.h>
unsigned int backoff = 100;
unsigned int max_tries = 3;
int safe_rename(char *old_f, char *new_f) {
int status = rename(old_f, new_f);
int t = 1;
while(status != 0 && max_tries > t++) {
usleep(backoff);
status = rename(old_f, new_f);
}
return status;
}
int safe_remove(char *f) {
int status = remove(f);
int t = 1;
while(status != 0 && max_tries > t++) {
usleep(backoff);
status = remove(f);
}
return status;
}
int main(int argc, char *argv[]) {
char *self = argv[0];
if(argc > 1) {
char *arg = argv[1];
if(*arg == '-') {
++arg;
if(*arg == '-') {
++arg;
// --
}
else if(*arg == 'u') {
++arg;
// -u
if(*arg == '1') {
std::string farg = std::string(argv[2]);
farg = farg.substr(0, farg.length()-4);
safe_rename((farg+".exe").c_str(), (farg+".old.exe").c_str());
char *args[] = { const_cast<char*>((farg+".old.exe").c_str()), const_cast<char*>("-u2"), self, NULL };
char *environ[] = { NULL };
return execve((farg+".old.exe").c_str(), args, environ);
}
else if(*arg == '2') {
std::string farg = std::string(argv[2]);
farg = farg.substr(0, farg.length()-8);
safe_rename((farg+".new.exe").c_str(), (farg+".exe").c_str());
char *args[] = { const_cast<char*>((farg+".exe").c_str()), const_cast<char*>("-u3"), self, NULL };
char *environ[] = { NULL };
return execve((farg+".exe").c_str(), args, environ);
}
else if(*arg == '3') {
safe_remove(argv[2]);
}
}
else if(*arg == '\0') {
// self.exe -
}
}
}
std::cout << "Normal Runtime" << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment