how to detect Linux shutdown/reboot

12,691

Solution 1

Catch SIGTERM. In the handler, read the /var/run/utmp file to get the runlevel. See the source code of the runlevel(8) command for reference.

Solution 2

Your assumptions are mistaken. There is no way to catch SIGKILL; it terminates the process with no chance to respond to it.

With that said, I may have a solution: you can catch SIGTERM, and if you install the signal handler with sigaction and the SA_SIGINFO flag, you should be able to determine which process sent you the SIGTERM signal. If it came from init (pid 1), it's a shutdown. This is mildly hackish but might work for your purposes.

Share:
12,691

Related videos on Youtube

sowrdking
Author by

sowrdking

Updated on September 15, 2022

Comments

  • sowrdking
    sowrdking over 1 year

    I'm trying to detect shut down or reboot from Linux in my c program. I found that program can use signal(SIGTERM, handler) (SIGKILL, handler). But these two will trigger if user kill the process with command, too.

    At some solutions, they said can use runlevel but it won't work. Don't know if the process is kill before the system init the runlevel. I even try to put script in rcx.d, but it still won't work.

    Does anyone has some advise? I need to run on many kinds of Linux system.

    Thanks.

    [Update] I use R solution, but I still don't see my data were clear at reboot or shutdown. Is it my function is wrong??

    int start() {
        if (initIni() == EXIT_FAILURE)
            return EXIT_FAILURE;
        struct sigaction act;
        memset(&act, '\0', sizeof(act));
        act.sa_sigaction = &signal_callback_handler;
        act.sa_flags = SA_SIGINFO;
        sigaction(SIGTERM, &act, NULL);
    ....
    }
    
    void signal_callback_handler(int signum, siginfo_t *siginfo, void *context) {
        if (signum == SIGTERM && (long)siginfo->si_pid == 1) {
            clearData();
        }
        exit(signum);
    }
    

    [Update] Finally, I use David Schwartz runlevel(8) example to solve my problem. It won't be useful if you use linux command runlevel. Thanks for the great solution.

    • versvs
      versvs about 10 years
      What do you want to do with this shutdown/reboot signal? Restart the process, in example?
    • isedev
      isedev about 10 years
      note SIGKILL cannot be caught!
  • sowrdking
    sowrdking about 10 years
    hello, I try to use you solution but it still won't be trigger at shutdown. Please see my update above. Thanks.