2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/types.h>
24 #include <sys/socket.h>
31 static struct sigaction
*oact
= NULL
;
34 do_notify_list(int argc
, char **argv
)
43 regexOptions
= kSCDRegexKey
;
45 status
= SCDNotifierList(session
, regexOptions
, &list
);
46 if (status
!= SCD_OK
) {
47 printf("SCDNotifierList: %s\n", SCDError(status
));
51 listCnt
= CFArrayGetCount(list
);
53 for (i
=0; i
<listCnt
; i
++) {
54 SCDLog(LOG_NOTICE
, CFSTR(" notifierKey [%d] = %@"), i
, CFArrayGetValueAtIndex(list
, i
));
57 SCDLog(LOG_NOTICE
, CFSTR(" no notifierKey's"));
66 do_notify_add(int argc
, char **argv
)
72 key
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingMacRoman
);
75 regexOptions
= kSCDRegexKey
;
77 status
= SCDNotifierAdd(session
, key
, regexOptions
);
79 if (status
!= SCD_OK
) {
80 printf("SCDNotifierAdd: %s\n", SCDError(status
));
87 do_notify_remove(int argc
, char **argv
)
93 key
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingMacRoman
);
96 regexOptions
= kSCDRegexKey
;
98 status
= SCDNotifierRemove(session
, key
, regexOptions
);
100 if (status
!= SCD_OK
) {
101 printf("SCDNotifierRemove: %s\n", SCDError(status
));
108 do_notify_changes(int argc
, char **argv
)
115 status
= SCDNotifierGetChanges(session
, &list
);
116 if (status
!= SCD_OK
) {
117 printf("SCDNotifierGetChanges: %s\n", SCDError(status
));
121 listCnt
= CFArrayGetCount(list
);
123 for (i
=0; i
<listCnt
; i
++) {
124 SCDLog(LOG_NOTICE
, CFSTR(" changedKey [%d] = %@"), i
, CFArrayGetValueAtIndex(list
, i
));
127 SCDLog(LOG_NOTICE
, CFSTR(" no changedKey's"));
136 do_notify_wait(int argc
, char **argv
)
140 status
= SCDNotifierWait(session
);
141 if (status
!= SCD_OK
) {
142 printf("SCDNotifierWait: %s\n", SCDError(status
));
146 printf("OK, something changed!\n");
152 notificationWatcher(SCDSessionRef session
, void *arg
)
154 printf("notification callback (session address = %p)\n", session
);
155 printf(" arg = %s\n", (char *)arg
);
161 notificationWatcherVerbose(SCDSessionRef session
, void *arg
)
163 printf("notification callback (session address = %p)\n", session
);
164 printf(" arg = %s\n", (char *)arg
);
165 do_notify_changes(0, NULL
); /* report the keys which changed */
171 do_notify_callback(int argc
, char **argv
)
174 SCDCallbackRoutine_t func
= notificationWatcher
;
176 if ((argc
== 1) && (strcmp(argv
[0], "verbose") == 0)) {
177 func
= notificationWatcherVerbose
;
180 status
= SCDNotifierInformViaCallback(session
,
182 "Changed detected by callback handler!");
183 if (status
!= SCD_OK
) {
184 printf("SCDNotifierInformViaCallback: %s\n", SCDError(status
));
193 do_notify_file(int argc
, char **argv
)
206 if ((sscanf(argv
[0], "%d", &reqID
) != 1)) {
207 printf("invalid identifier\n");
212 status
= SCDNotifierInformViaFD(session
, reqID
, &fd
);
213 if (status
!= SCD_OK
) {
214 printf("SCDNotifierInformViaFD: %s\n", SCDError(status
));
218 bzero(buf
.data
, sizeof(buf
.data
));
219 bufPtr
= &buf
.data
[0];
220 needed
= sizeof(buf
.gotID
);
224 got
= read(fd
, bufPtr
, needed
);
226 /* if error detected */
227 printf("read() failed: %s\n", strerror(errno
));
232 /* if end of file detected */
233 printf("read(): detected end of file\n");
237 printf("Received %d bytes\n", got
);
242 if (needed
!= sizeof(buf
.gotID
)) {
243 printf(" Received notification, identifier = %d\n", buf
.gotID
);
246 /* this utility only allows processes one notification per "n.file" request */
247 (void)SCDNotifierCancel(session
);
249 (void) close(fd
); /* close my side of the file descriptor */
255 static char *signames
[] = {
256 "" , "HUP" , "INT" , "QUIT", "ILL" , "TRAP", "ABRT", "EMT" ,
257 "FPE" , "KILL", "BUS" , "SEGV", "SYS" , "PIPE", "ALRM", "TERM",
258 "URG" , "STOP", "TSTP" , "CONT", "CHLD" , "TTIN", "TTOU", "IO" ,
259 "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1",
265 signalCatcher(int signum
)
269 printf("Received SIG%s (#%d)\n", signames
[signum
], n
++);
275 do_notify_signal(int argc
, char **argv
)
279 struct sigaction nact
;
283 if (isdigit(*argv
[0])) {
284 if ((sscanf(argv
[0], "%d", &sig
) != 1) || (sig
<= 0) || (sig
>= NSIG
)) {
285 printf("signal must be in the range of 1 .. %d\n", NSIG
-1);
289 for (sig
=1; sig
<NSIG
; sig
++) {
290 if (strcasecmp(argv
[0], signames
[sig
]) == 0)
294 printf("Signal must be one of the following:");
295 for (sig
=1; sig
<NSIG
; sig
++) {
298 printf(" %-6s", signames
[sig
]);
306 if ((argc
!= 2) || (sscanf(argv
[1], "%d", &pid
) != 1)) {
311 ret
= sigaction(osig
, oact
, NULL
); /* restore original signal handler */
313 oact
= malloc(sizeof(struct sigaction
));
316 nact
.sa_handler
= signalCatcher
;
317 sigemptyset(&nact
.sa_mask
);
318 nact
.sa_flags
= SA_RESTART
;
319 ret
= sigaction(sig
, &nact
, oact
);
321 printf("signal handler started\n");
323 status
= SCDNotifierInformViaSignal(session
, pid
, sig
);
324 if (status
!= SCD_OK
) {
325 printf("SCDNotifierInformViaSignal: %s\n", SCDError(status
));
334 do_notify_cancel(int argc
, char **argv
)
339 status
= SCDNotifierCancel(session
);
340 if (status
!= SCD_OK
) {
341 printf("SCDNotifierCancel: %s\n", SCDError(status
));
346 ret
= sigaction(osig
, oact
, NULL
); /* restore original signal handler */