]> git.saurik.com Git - apple/configd.git/blobdiff - scutil.tproj/notifications.c
configd-453.19.tar.gz
[apple/configd.git] / scutil.tproj / notifications.c
index 8cb779ff109c224125ea287184259c3c819815a1..a50302e85917c85c42d2d3c956d7ae7fcbdc12dd 100644 (file)
@@ -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 <pthread.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/time.h>
 #include <sys/un.h>
 #include <unistd.h>
 
@@ -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;
        }