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@
24 #include <mach/mach.h>
25 #include <mach/mach_error.h>
27 #include <SystemConfiguration/SCD.h>
28 #include "config.h" /* MiG generated file */
29 #include "SCDPrivate.h"
33 SCDClose(SCDSessionRef
*session
)
35 SCDSessionPrivateRef sessionPrivate
;
41 SCDLog(LOG_DEBUG
, CFSTR("SCDClose:"));
43 if ((session
== NULL
) || (*session
== NULL
)) {
44 return SCD_NOSESSION
; /* you can't do anything with a closed session */
46 sessionPrivate
= (SCDSessionPrivateRef
)*session
;
48 (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED
, &oldThreadState
);
50 scd_status
= (sessionPrivate
->server
== MACH_PORT_NULL
) ? SCD_NOSESSION
: SCD_OK
;
52 /* Remove notification keys */
53 if ((keyCnt
= CFSetGetCount(sessionPrivate
->keys
)) > 0) {
55 CFArrayRef keysToRemove
;
58 watchedKeys
= CFAllocatorAllocate(NULL
, keyCnt
* sizeof(CFStringRef
), 0);
59 CFSetGetValues(sessionPrivate
->keys
, watchedKeys
);
60 keysToRemove
= CFArrayCreate(NULL
, watchedKeys
, keyCnt
, &kCFTypeArrayCallBacks
);
61 CFAllocatorDeallocate(NULL
, watchedKeys
);
62 for (i
=0; i
<keyCnt
; i
++) {
63 if (scd_status
== SCD_OK
) {
64 scd_status
= SCDNotifierRemove(*session
,
65 CFArrayGetValueAtIndex(keysToRemove
, i
),
69 CFRelease(keysToRemove
);
72 /* Remove regex notification keys */
73 if ((keyCnt
= CFSetGetCount(sessionPrivate
->reKeys
)) > 0) {
75 CFArrayRef keysToRemove
;
78 watchedKeys
= CFAllocatorAllocate(NULL
, keyCnt
* sizeof(CFStringRef
), 0);
79 CFSetGetValues(sessionPrivate
->reKeys
, watchedKeys
);
80 keysToRemove
= CFArrayCreate(NULL
, watchedKeys
, keyCnt
, &kCFTypeArrayCallBacks
);
81 CFAllocatorDeallocate(NULL
, watchedKeys
);
82 for (i
=0; i
<keyCnt
; i
++) {
83 if (scd_status
== SCD_OK
) {
84 scd_status
= SCDNotifierRemove(*session
,
85 CFArrayGetValueAtIndex(keysToRemove
, i
),
89 CFRelease(keysToRemove
);
92 /* Remove/cancel any outstanding notification requests. */
93 (void) SCDNotifierCancel(*session
);
95 if (SCDOptionGet(*session
, kSCDOptionIsLocked
) && (scd_status
== SCD_OK
)) {
96 scd_status
= SCDUnlock(*session
); /* release the lock */
99 if (scd_status
== SCD_OK
) {
100 status
= configclose(sessionPrivate
->server
, (int *)&scd_status
);
101 if (status
!= KERN_SUCCESS
) {
102 if (status
!= MACH_SEND_INVALID_DEST
)
103 SCDLog(LOG_DEBUG
, CFSTR("configclose(): %s"), mach_error_string(status
));
104 scd_status
= SCD_NOSERVER
;
107 (void) mach_port_destroy(mach_task_self(), sessionPrivate
->server
);
108 sessionPrivate
->server
= MACH_PORT_NULL
;
111 CFAllocatorDeallocate(NULL
, sessionPrivate
);
114 (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS
, &oldThreadState
);
115 pthread_testcancel();