Application Cleanup during Linux Shutdown

I'm trying to do some cleanup (write open files) when Linux shuts down. I thought the right method would be to trap SIGTERM and do the necessary processing. Here's my sample code:

#include <stdio.h> // for File I/O
#include <signal.h> // for signals
#include <unistd.h> // for sleep()

void handler(int signal)
{
    FILE *out=fopen("test.txt","at");
    if (out)
    {
        fprintf(out,"got %d\n",signal);
        fclose(out);
    }
}

int main()
{
    signal(SIGTERM,handler);
    signal(SIGINT,handler);
    sleep(30);
}

When I run this, and press Ctrl-C, it writes "got 2" to test.txt. However, if I logout/reboot, nothing is written to the file.

Any help or ideas would be appreciated!

-Ron

Is 30 seconds really a long enough wait?

I wonder if it's getting a SIGHUP or SIGPIPE from a forcibly closed ssh connection or some such.

Or it could even be that, by the time it's getting killed, the filesystem's remounted as read-only.

Interesting thought... but yes, I am fully logged out well before 30 seconds. I just run the app:
% ./test &
...and then logout. From start to finish is only about 10 seconds.
If the file system is read-only at that point, how would an application do any cleanup that required writing data to disk.

This just seems like it should be such a common need.. I am quite befuddled at it not being simpler!

-Ron

What shell are you using? If it's bash, you need to run 'disown' after that so bash doesn't try and wait for it.

Applications that need cleanup should've quit from earlier signals anyhow.

It's supposed to work the way you think; I'm sure there's something obvious we're missing. I'd make a few small changes to your source:

#include <stdio.h> // for File I/O
#include <signal.h> // for signals
#include <unistd.h> // for sleep()

void handler(int sig)
{
        /* Just print to stderr and redirect 2>> test.txt in the shell */
    fprintf(stderr, "got %d\n", signal);

    signal(sig, handler); // let signal be caught again
}

int main()
{
    signal(SIGTERM,handler);
    signal(SIGINT,handler);
    signal(SIGQUIT, handler); // Maybe we're getting QUIT first?
    signal(SIGHUP, handler); // If the terminal closes, we might get this
    signal(SIGPIPE, handler); // Don't know why we'd get this, but check anyway
    while(1) // loop forever with most signals trapped, impolitely waiting for a kill -9 ;)
        sleep(30);
}

Unfortunately, I tried these with no luck. I added the extra signals and added the while(1) just to be certain my application wouldn't exit before logout killed it.

Still, I can press Ctrl-C and that gets caught just fine, but nothing on logout. I also tried launching the application from the Actions/Run Application menu just to be sure it wasn't related to running it from the shell. No difference.

I appreciate all the suggestions, and if you have any others, I'm all ears!!!

Thanks,
Ron

None of the printf() family are async-signal safe. Using them in a signal handler could be deadlocking the app.

Not even printing to stderr? OK, fine...

void handler(int sig)
{
        char buf[128];
        sprintf(buf, "got signal %d\n", sig);
        write(STDERR_FILENO, buf, strlen(buf));
        signal(sig, handler);
}