]> git.saurik.com Git - apple/configd.git/blame - configd.tproj/_notifyviasignal.c
configd-24.1.tar.gz
[apple/configd.git] / configd.tproj / _notifyviasignal.c
CommitLineData
5958d7c0
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#include "configd.h"
24#include "configd_server.h"
25#include "session.h"
26
27SCDStatus
28_SCDNotifierInformViaSignal(SCDSessionRef session, pid_t pid, int sig)
29{
30 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
31 CFStringRef sessionKey;
32 CFDictionaryRef info;
33
34 SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierInformViaSignal:"));
35
36 if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
37 return SCD_NOSESSION; /* you must have an open session to play */
38 }
39
40 if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
41 /* sorry, you can only have one notification registered at once */
42 return SCD_NOTIFIERACTIVE;
43 }
44
45 if ((sig <= 0) || (sig > NSIG)) {
46 /* sorry, you must specify a valid signal */
47 return SCD_INVALIDARGUMENT;
48 }
49
50 /* push out a notification if any changes are pending */
51 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
52 info = CFDictionaryGetValue(sessionData, sessionKey);
53 CFRelease(sessionKey);
54 if (info && CFDictionaryContainsKey(info, kSCDChangedKeys)) {
55 CFNumberRef sessionNum;
56
57 if (needsNotification == NULL)
58 needsNotification = CFSetCreateMutable(NULL,
59 0,
60 &kCFTypeSetCallBacks);
61
62 sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
63 CFSetAddValue(needsNotification, sessionNum);
64 CFRelease(sessionNum);
65 }
66
67 return SCD_OK;
68}
69
70
71kern_return_t
72_notifyviasignal(mach_port_t server,
73 task_t task,
74 int sig,
75 int *scd_status)
76{
77 serverSessionRef mySession = getSession(server);
78 SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)mySession->session;
79#if defined(DEBUG) || defined(NOTYET)
80 kern_return_t status;
81#endif
82#ifdef NOTYET
83 mach_port_t oldNotify;
84#endif /* NOTYET */
85
86 SCDLog(LOG_DEBUG, CFSTR("Send signal when a notification key changes."));
87 SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
88 SCDLog(LOG_DEBUG, CFSTR(" task = %d"), task);
89 SCDLog(LOG_DEBUG, CFSTR(" signal = %d"), sig);
90
91 *scd_status = _SCDNotifierInformViaSignal(mySession->session, 0, sig); /* pid is N/A for server */
92 if (*scd_status != SCD_OK) {
93 if (task != TASK_NULL) {
94 (void) mach_port_destroy(mach_task_self(), task);
95 }
96 return KERN_SUCCESS;
97 }
98
99#ifdef DEBUG
100 { mach_port_type_t pt;
101
102 status = mach_port_type(mach_task_self(), task, &pt);
103 if (status == MACH_MSG_SUCCESS) {
104 char rights[8], *rp = &rights[0];
105
106 if (pt & MACH_PORT_TYPE_SEND)
107 *rp++ = 'S';
108 if (pt & MACH_PORT_TYPE_RECEIVE)
109 *rp++ = 'R';
110 if (pt & MACH_PORT_TYPE_SEND_ONCE)
111 *rp++ = 'O';
112 if (pt & MACH_PORT_TYPE_PORT_SET)
113 *rp++ = 'P';
114 if (pt & MACH_PORT_TYPE_DEAD_NAME)
115 *rp++ = 'D';
116 *rp = '\0';
117
118 SCDLog(LOG_DEBUG, CFSTR("Task %d, port rights = %s"), task, rights);
119 }
120 }
121#endif /* DEBUG */
122
123#ifdef NOTYET
124 /* Request a notification when/if the client dies */
125 status = mach_port_request_notification(mach_task_self(),
126 task,
127 MACH_NOTIFY_DEAD_NAME,
128 1,
129 task,
130 MACH_MSG_TYPE_MAKE_SEND_ONCE,
131 &oldNotify);
132 if (status != KERN_SUCCESS) {
133 SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
134 *scd_status = SCD_FAILED;
135 return KERN_SUCCESS;
136 }
137
138#ifdef DEBUG
139 if (oldNotify != MACH_PORT_NULL) {
140 SCDLog(LOG_DEBUG, CFSTR("_notifyviasignal(): why is oldNotify != MACH_PORT_NULL?"));
141 }
142#endif /* DEBUG */
143
144 SCDLog(LOG_DEBUG, CFSTR("Adding task notification port %d to the server's port set"), task);
145 status = mach_port_move_member(mach_task_self(), task, server_ports);
146 if (status != KERN_SUCCESS) {
147 SCDLog(LOG_DEBUG, CFSTR("mach_port_move_member(): %s"), mach_error_string(status));
148 *scd_status = SCD_FAILED;
149 return KERN_SUCCESS;
150 }
151#endif /* NOTYET */
152
153 sessionPrivate->notifyStatus = Using_NotifierInformViaSignal;
154 sessionPrivate->notifySignal = sig;
155 sessionPrivate->notifySignalTask = task;
156
157 return KERN_SUCCESS;
158}