Last active
October 4, 2020 17:44
-
-
Save landonf/6984228 to your computer and use it in GitHub Desktop.
Enables OS X's hardware watchdog.
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
#include <CoreFoundation/CoreFoundation.h> | |
#include <IOKit/IOKitLib.h> | |
#include <dispatch/dispatch.h> | |
// 5 minutes | |
#define TIMEOUT (5*60) | |
bool reset_watchdog (int timeout) { | |
io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOWatchDogTimer")); | |
if (service == IO_OBJECT_NULL) { | |
fprintf(stderr, "Watching service not found\n"); | |
return false; | |
} | |
CFNumberRef number = CFNumberCreate(NULL, kCFNumberIntType, &timeout); | |
kern_return_t ret; | |
if ((ret = IORegistryEntrySetCFProperties(service, number)) != KERN_SUCCESS) { | |
fprintf(stderr, "Failed to enable watchdog: %u\n", ret); | |
IOObjectRelease(service); | |
return false; | |
} | |
IOObjectRelease(service); | |
return true; | |
} | |
void invoke_timer (void *ctx) { | |
if (!reset_watchdog(TIMEOUT)) | |
fprintf(stderr, "Failed to reset watchdog!"); | |
} | |
void handle_signal (void *ctx) { | |
fprintf(stderr, "Got signal, cleaning up ...\n"); | |
fflush(stderr); | |
if (!reset_watchdog(0)) { | |
fprintf(stderr, "Failed to reset watchdog, can't exit!\n"); | |
return; | |
} | |
exit(0); | |
} | |
int main (int argc, char *argv[]) { | |
/* Set up the keep-alive timer */ | |
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); | |
dispatch_source_set_timer(timer, 0, (TIMEOUT/2)*NSEC_PER_SEC, 0); | |
dispatch_source_set_event_handler_f(timer, invoke_timer); | |
dispatch_resume(timer); | |
/* Set up the signal handlers */ | |
int signos[] = { SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT, SIGFPE, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, SIGUSR2 }; | |
for (int i = 0; i < sizeof(signos) / sizeof(signos[0]); i++) { | |
signal(signos[i], SIG_IGN); | |
dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, signos[i], 0, dispatch_get_main_queue()); | |
dispatch_source_set_event_handler_f(source, handle_signal); | |
dispatch_resume(source); | |
} | |
dispatch_main(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment