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
How to Initialize All Tuple Elements by the Same Arguments
Could We Use Extern "C" in C File Without #Ifdef _Cplusplus
How to Check That I Didn't Break Anything When Refactoring
How to Reproduce Tcp Protocol 3-Way Handshake with Raw Sockets Correctly
Thread Safety of Matlab Engine API
What's the Real Use of Using N[C-'0']
Linux Ipc - Multiple Writers, Single Reader
Does the Alignas Specifier Work with 'New'
Boost Serialization, Deserialization of Raw C Arrays
Piping Input into a C++ Program to Debug in Visual Studio
C++11 Random Number Distributions Are Not Consistent Across Platforms -- What Alternatives Are There
How to Append to a File with Fstream Fstream::App Flag Seems Not to Work
How to Read Input When Debugging in C++ in Visual Studio Code