Skip to content

Instantly share code, notes, and snippets.

@landonf
Last active October 4, 2020 17:44
Show Gist options
  • Save landonf/6984228 to your computer and use it in GitHub Desktop.
Save landonf/6984228 to your computer and use it in GitHub Desktop.
Enables OS X's hardware watchdog.
#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