Last active
January 18, 2019 15:09
-
-
Save gilleyj/07c0f03271e3461ef1f20dfa0a8929c3 to your computer and use it in GitHub Desktop.
A deadman's switch in C for a cronjob
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
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