/*
- * 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@
*
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <sys/un.h>
#include <unistd.h>
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;
for (i = 0; i < n; i++) {
SCPrint(TRUE,
stdout,
- CFSTR(" changed key [%d] = %@\n"),
+ CFSTR(" %s changedKey [%d] = %@\n"),
+ elapsed(),
i,
CFArrayGetValueAtIndex(changedKeys, i));
}
for (i = 0; i < listCnt; i++) {
SCPrint(TRUE,
stdout,
- CFSTR(" changedKey [%d] = %@\n"),
+ CFSTR(" %s changedKey [%d] = %@\n"),
+ elapsed(),
i,
CFArrayGetValueAtIndex(list, i));
}
_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;
}
pthread_attr_t tattr;
pthread_t tid;
- if (notifyRl) {
+ if (notifyRl != NULL) {
+ SCPrint(TRUE, stdout, CFSTR("already active\n"));
return;
}
}
-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)
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);
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)) {
}
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));
}
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"));
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;
}