Is it possible to restart a program from inside a program?
Solution 1:
If you really need to restart the whole program (i.e. to "close" and "open" again), the "proper" way would be to have a separate program with the sole purpose of restarting your main one. AFAIK a lot of applications with auto-update feature work this way. So when you need to restart your main program, you simply call the "restarter" one, and exit.
Solution 2:
You can use a loop in your main
function:
int main()
{
while(!i_want_to_exit_now) {
// code
}
}
Or, if you want to actually restart the program, run it from a harness:
program "$@"
while [ $? -e 42 ]; do
program "$@"
done
where 42
is a return code meaning "restart, please".
Then inside the program your restart
function would look like this:
void restart() {
std::exit(42);
}
Solution 3:
On Unicies, or anywhere else you have execve
and it works like the man page specifies, you can just...kill me for using atoi
, because it's generally awful, except for this sort of case.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv) {
(void) argc;
printf("arg: %s\n", argv[1]);
int count = atoi(argv[1]);
if ( getchar() == 'y' ) {
++count;
char buf[20];
sprintf(buf, "%d", count);
char* newargv[3];
newargv[0] = argv[0];
newargv[1] = buf;
newargv[2] = NULL;
execve(argv[0], newargv, NULL);
}
return count;
}
Example:
$ ./res 1
arg: 1
y
arg: 2
y
arg: 3
y
arg: 4
y
arg: 5
y
arg: 6
y
arg: 7
n
7 | $
(7 was the return code).
It neither recurses nor explicitly loops -- instead, it just calls itself, replacing its own memory space with a new version of itself.
In this way, the stack will never overflow, though all previous variables will be redeclared, just like with any reinvocation -- the getchar
call prevents 100% CPU utilisation.
In the case of a self-updating binary, since the entire binary (at least, on Unix-likes, I don't know about Windows) will be copied into memory at runtime, then if the file changes on disk before the execve(argv[0], ...
call, the new binary found on disk, not the same old one, will be run instead.
As @CarstenS and @bishop point out in the comments, due to the unique way in which Unix was designed, open file descriptors are kept across fork
/exec
, and as a result in order to avoid leaking open file descriptors across calls to execve
, you should either close them before execve
or open them with e
, FD_CLOEXEC
/ O_CLOEXEC
in the first place -- more information can be found on Dan Walsh's blog.
Solution 4:
This is a very OS-specific question. In Windows you can use the Application Restart API or MFC Restart Manager. In Linux you could do an exec()
However most of the time there is a better solution. You're likely better off using a loop, as suggested in other answers.
Solution 5:
This sounds like the wrong approach, like all your state is global and so the only clear-cut method you have of resetting everything (other than to manually assign "default" values to each variable) is to restart the whole program.
Instead, your state should be held in objects (of class type, or whatever). You are then free to create and destroy these objects whenever you like. Each new object has a fresh state with "default" values.
Don't fight C++; use it!