X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/edebe297f772e4cdd76278ebb777820466d2917b..1e2cbe6aa7461cd7abf510b7c26db26974657962:/scutil.tproj/notifications.c diff --git a/scutil.tproj/notifications.c b/scutil.tproj/notifications.c index 8cb779f..a50302e 100644 --- a/scutil.tproj/notifications.c +++ b/scutil.tproj/notifications.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004, 2008-2011 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,39 @@ static int osig; static struct sigaction *oact = NULL; +static char * +elapsed() +{ + int n; + static char str[128]; + struct tm tm_diff; + struct tm tm_now; + struct timeval tv_diff; + struct timeval tv_now; + static struct timeval tv_then = { 0, 0 }; + + (void)gettimeofday(&tv_now, NULL); + + (void)localtime_r(&tv_now.tv_sec, &tm_now); + + timersub(&tv_now, &tv_then, &tv_diff); + (void)localtime_r(&tv_diff.tv_sec, &tm_diff); + n = snprintf(str, sizeof(str), "%2d:%02d:%02d.%03d", + tm_now.tm_hour, + tm_now.tm_min, + tm_now.tm_sec, + tv_now.tv_usec / 1000); + if (((tv_then.tv_sec != 0) || (tv_then.tv_usec != 0)) && (n < sizeof(str))) { + snprintf(&str[n], sizeof(str) - n, " (+%ld.%03d)", + tv_diff.tv_sec, + tv_diff.tv_usec / 1000); + } + + tv_then = tv_now; + return str; +} + + static CFComparisonResult sort_keys(const void *p1, const void *p2, void *context) { CFStringRef key1 = (CFStringRef)p1; @@ -67,7 +101,8 @@ storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) for (i = 0; i < n; i++) { SCPrint(TRUE, stdout, - CFSTR(" changed key [%d] = %@\n"), + CFSTR(" %s changedKey [%d] = %@\n"), + elapsed(), i, CFArrayGetValueAtIndex(changedKeys, i)); } @@ -227,7 +262,8 @@ do_notify_changes(int argc, char **argv) for (i = 0; i < listCnt; i++) { SCPrint(TRUE, stdout, - CFSTR(" changedKey [%d] = %@\n"), + CFSTR(" %s changedKey [%d] = %@\n"), + elapsed(), i, CFArrayGetValueAtIndex(list, i)); } @@ -244,19 +280,31 @@ static void * _watcher(void *arg) { notifyRl = CFRunLoopGetCurrent(); - if (!notifyRl) { + if (notifyRl == NULL) { SCPrint(TRUE, stdout, CFSTR(" CFRunLoopGetCurrent() failed\n")); return NULL; } - notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); - if (!notifyRls) { - SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); - return NULL; + if (doDispatch) { + if (!SCDynamicStoreSetDispatchQueue(store, dispatch_get_current_queue())) { + SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); + notifyRl = NULL; + return NULL; + } + notifyRls = (CFRunLoopSourceRef)kCFNull; + } else { + notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); + if (notifyRls == NULL) { + SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); + notifyRl = NULL; + return NULL; + } + CFRunLoopAddSource(notifyRl, notifyRls, kCFRunLoopDefaultMode); } - CFRunLoopAddSource(notifyRl, notifyRls, kCFRunLoopDefaultMode); + pthread_setname_np("n.watch"); CFRunLoopRun(); + notifyRl = NULL; return NULL; } @@ -267,7 +315,8 @@ do_notify_watch(int argc, char **argv) pthread_attr_t tattr; pthread_t tid; - if (notifyRl) { + if (notifyRl != NULL) { + SCPrint(TRUE, stdout, CFSTR("already active\n")); return; } @@ -295,44 +344,6 @@ do_notify_wait(int argc, char **argv) } -static boolean_t -notificationWatcher(SCDynamicStoreRef store, void *arg) -{ - SCPrint(TRUE, stdout, CFSTR("notification callback (store address = %p).\n"), store); - SCPrint(TRUE, stdout, CFSTR(" arg = %s.\n"), (char *)arg); - return TRUE; -} - - -static boolean_t -notificationWatcherVerbose(SCDynamicStoreRef store, void *arg) -{ - SCPrint(TRUE, stdout, CFSTR("notification callback (store address = %p).\n"), store); - SCPrint(TRUE, stdout, CFSTR(" arg = %s.\n"), (char *)arg); - do_notify_changes(0, NULL); /* report the keys which changed */ - return TRUE; -} - - -__private_extern__ -void -do_notify_callback(int argc, char **argv) -{ - SCDynamicStoreCallBack_v1 func = notificationWatcher; - - if ((argc == 1) && (strcmp(argv[0], "verbose") == 0)) { - func = notificationWatcherVerbose; - } - - if (!SCDynamicStoreNotifyCallback(store, CFRunLoopGetCurrent(), func, "Changed detected by callback handler!")) { - SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); - return; - } - - return; -} - - __private_extern__ void do_notify_file(int argc, char **argv) @@ -386,6 +397,9 @@ do_notify_file(int argc, char **argv) SCPrint(TRUE, stdout, CFSTR(" Received notification, identifier = %d.\n"), buf.gotID); } + /* report the keys that changed */ + do_notify_changes(0, NULL); + /* this utility only allows processes one notification per "n.file" request */ (void) SCDynamicStoreNotifyCancel(store); @@ -412,7 +426,6 @@ do_notify_signal(int argc, char **argv) int sig; pid_t pid; struct sigaction nact; - int ret; if (isdigit(*argv[0])) { if ((sscanf(argv[0], "%d", &sig) != 1) || (sig <= 0) || (sig >= NSIG)) { @@ -451,7 +464,7 @@ do_notify_signal(int argc, char **argv) } if (oact != NULL) { - ret = sigaction(osig, oact, NULL); /* restore original signal handler */ + (void) sigaction(osig, oact, NULL); /* restore original signal handler */ } else { oact = malloc(sizeof(struct sigaction)); } @@ -459,7 +472,7 @@ do_notify_signal(int argc, char **argv) nact.sa_handler = signalCatcher; sigemptyset(&nact.sa_mask); nact.sa_flags = SA_RESTART; - ret = sigaction(sig, &nact, oact); + (void) sigaction(sig, &nact, oact); osig = sig; SCPrint(TRUE, stdout, CFSTR("signal handler started.\n")); @@ -476,26 +489,30 @@ __private_extern__ void do_notify_cancel(int argc, char **argv) { - int ret; - - if (notifyRls) { - CFRunLoopSourceInvalidate(notifyRls); - CFRelease(notifyRls); + if (notifyRls != NULL) { + if (doDispatch) { + if (!SCDynamicStoreSetDispatchQueue(store, NULL)) { + SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); + return; + } + } else { + CFRunLoopSourceInvalidate(notifyRls); + CFRelease(notifyRls); + } notifyRls = NULL; + } else { + if (!SCDynamicStoreNotifyCancel(store)) { + SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); + return; + } } - if (notifyRl) { + if (notifyRl != NULL) { CFRunLoopStop(notifyRl); - notifyRl = NULL; - } - - if (!SCDynamicStoreNotifyCancel(store)) { - SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); - return; } if (oact != NULL) { - ret = sigaction(osig, oact, NULL); /* restore original signal handler */ + (void) sigaction(osig, oact, NULL); /* restore original signal handler */ free(oact); oact = NULL; }