Skip to content

Instantly share code, notes, and snippets.

@gilleyj
Last active January 18, 2019 15:09
Show Gist options
  • Save gilleyj/07c0f03271e3461ef1f20dfa0a8929c3 to your computer and use it in GitHub Desktop.
Save gilleyj/07c0f03271e3461ef1f20dfa0a8929c3 to your computer and use it in GitHub Desktop.
A deadman's switch in C for a cronjob
/**
Original Request:
****
A dead man's switch is a switch that is automatically operated if the human operator
becomes incapacitated, such as through death, loss of consciousness, or being bodily
removed from control. Originally applied to switches on a vehicle or machine, it has
since come to be used to describe other intangible uses like in computer software.
In alerting systems such a control can be useful, for instance in the case that a
cron job or backup process doesn't complete.
In our case, let's assume that a cron job we want to monitor touches a file named
/tmp/my_cron_job and updates the last modified time each time it runs.
Let's apply the concept to create a script that:
Takes as input two pieces of data: a file whose last modified time we will check
and a TTL after we consider the cron job to have failed
Returns 0 for an ok status, 1 for an error condition
Example usage:
./dead_man_switch <file_to_check> <ttl>
****
My take:
get file mtime
if error then error 1(file gone or permission)
diff = now-then
if > ttl then error 1
if < ttl then not error 0
compile it:
gcc deadman.c -o deadman
run it:
./deadman deadman.c 360
// to see values for fun you can do:
./deadman deadman.c 360 d
**/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
const char *path_file = NULL;
int main(int argc, char* argv[]) {
if (!(argc > 2 && argc < 5)) {
fprintf(stderr, "usage: deadman path MAX_ttl_in_secs [dryrun]\n");
return -1;
}
// quick vars
time_t now = time(NULL);
struct stat attr;
long ttl_seconds = 0;
bool dryrun = false;
// dangerous stuff here
path_file = argv[1];
ttl_seconds = atol(argv[2]);
if(argv[3]!=NULL) dryrun = true;
// if ttl_seconds > diff return 0 - good status
// otherwise return 1 (file missing, ttl_seconds>diff) - bad status
if (!stat(path_file, &attr)) {
// unnecessary casting for darwinbs
long diff = (long)now - (long)attr.st_mtime;
// validate the logics
if(dryrun) {
printf("path: %s \n", path_file);
printf("now : %ld \n", now);
printf("then: %ld \n", attr.st_mtime);
printf("diff: %ld \n", diff);
if(diff < ttl_seconds) printf("ok 1 \n");
else printf("not ok 0 \n");
}
// actual logics heh shortcut 1 second because reasons
if(diff < ttl_seconds) return 0;
else return 1;
} else {
if(dryrun) {
printf("path: %s \n", path_file);
printf("statd error (not found or other) return 1 \n");
}
return 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment