How to Restart Linux from Inside a C++ Program

how to use linux reboot function in C for shutdown Linux(Ubuntu) system?

For a large number of reasons, it is better to power off the machine using e.g.

execl("/bin/shutdown", "shutdown", "-P", "now", (char *)0);

or reboot using

execl("/bin/shutdown", "shutdown", "-r", "now", (char *)0);

There is no shell involved at all. The current process is replaced by the shutdown system management command, which already has the necessary privileges if the user the process is running has is allowed to shutdown or reboot the machine.

(That is, code following the above statement is not executed at all, except if the system utility is missing. It will be there on any functioning system, even embedded ones.)

You can even replace the "now" with a fixed string like "+1m", to shutdown or reboot after one minute has elapsed. (During that time, everything else will continue running normally. Running shutdown with just a -c parameter during that period will cancel the pending shutdown/reboot.)

If you do this from a GUI application, only do it where a normal program would either return from main(), or exit().


What are those reasons?

Simplicity, robustness, the principle of least surprise, proper management of privileges for shutdown/reboot, not requiring special privileges and thus reduced threat surface (bugs in your program less likely to grant special privileges, because there are none). For starters.

Shutdown Linux from C program meant to be ran as init process

Why doesn't poweroff work?

A number of programs assume the kernel has booted with init as PID 1. On many systems init is a symbolic link to the systemd program; similarly on these systems, poweroff is often a symbolic link to the systemctl program.

In your setup, systemd is never started since you set your custom init=/path/to/program kernel parameter line. This is why the poweroff command doesn't work: systemctl is trying to contact a systemd instance which was never created.

How to power off without systemd.

The reboot function is described in the Linux Programmer's Manual. Under glibc, you can pass the RB_POWER_OFF macro constant to perform the reboot.

Note that if reboot is not preceded by a call to sync, data may be lost.

Using glibc in Linux:

#include <unistd.h>
#include <sys/reboot.h>

sync();
reboot(RB_POWER_OFF);

See also

How to restart Linux from inside a C++ program?

Restart C program from Bash terminal

You need to keep the parent process running to monitor the child process. If the parent detects that the child is no longer running, it can restart it.

The parent can use the wait system call to detect when the child exits.

while (1) {
pid_t pid = fork();
if (pid < 0) {
return -1;
} else if (pid > 0) {
// parent waits for child to finish
// when it does, it goes back to the top of the loop and forks again
wait(NULL);
} else {
// child process
while (1);
}
}

Restart program in C

Since you are on linux I think this is the cleanest way:

int main(int argc, char **argv) {
/* your program here */

/* if you want to restart call this */
if (execv(argv[0], argv)) {
/* ERROR, handle this yourself */
}

return 0;
}

Linux reboot function called in C program causes file loss created by the program on disk

The man page for fclose says:

Note that fclose() only flushes the user space buffers provided by the
C library. To ensure that the data is physically stored on disk the
kernel buffers must be flushed too, for example, with sync(2) or
fsync(2).

Which means that you need to call fsync before closing the file descriptor.

How to make a program to restart itself? (Linux process)

Why bother with the fork if you're just going to kill the parent? Just do the exec. The new instance of the program will still be the same process but will effectively be rebooted.



Related Topics



Leave a reply



Submit