1
1
/* CFUserNotification.c
2
- Copyright (c) 2000-2017 , Apple Inc. All rights reserved.
2
+ Copyright (c) 2000-2018 , Apple Inc. All rights reserved.
3
3
4
- Portions Copyright (c) 2014-2017 , Apple Inc. and the Swift project authors
4
+ Portions Copyright (c) 2014-2018 , Apple Inc. and the Swift project authors
5
5
Licensed under Apache License v2.0 with Runtime Library Exception
6
6
See http://swift.org/LICENSE.txt for license information
7
7
See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
14
14
#include <CoreFoundation/CFNumber.h>
15
15
#include <CoreFoundation/CFRunLoop.h>
16
16
#include "CFInternal.h"
17
+ #include "CFRuntime_Internal.h"
17
18
#include <CoreFoundation/CFMachPort.h>
18
19
#include <stdlib.h>
19
20
#include <unistd.h>
@@ -54,13 +55,13 @@ CONST_STRING_DECL(kCFUserNotificationPopUpTitlesKey, "PopUpTitles")
54
55
CONST_STRING_DECL (kCFUserNotificationTextFieldTitlesKey , "TextFieldTitles" )
55
56
CONST_STRING_DECL (kCFUserNotificationCheckBoxTitlesKey , "CheckBoxTitles" )
56
57
CONST_STRING_DECL (kCFUserNotificationTextFieldValuesKey , "TextFieldValues" )
58
+ #if TARGET_OS_OSX
57
59
CONST_STRING_DECL (kCFUserNotificationPopUpSelectionKey , "PopUpSelection" )
60
+ #endif
58
61
CONST_STRING_DECL (kCFUserNotificationKeyboardTypesKey , "KeyboardTypes" )
59
62
CONST_STRING_DECL (kCFUserNotificationAlertTopMostKey , "AlertTopMost" ) // boolean value
60
63
61
64
62
- static CFTypeID __kCFUserNotificationTypeID = _kCFRuntimeNotATypeID ;
63
-
64
65
struct __CFUserNotification {
65
66
CFRuntimeBase _base ;
66
67
SInt32 _replyPort ;
@@ -86,18 +87,13 @@ static CFStringRef __CFUserNotificationCopyDescription(CFTypeRef cf) {
86
87
#define MAX_PORT_NAME_LENGTH 63
87
88
#define NOTIFICATION_PORT_NAME_SUFFIX ".session."
88
89
#define MESSAGE_TIMEOUT 100
89
- #if DEPLOYMENT_TARGET_MACOSX
90
- #define NOTIFICATION_PORT_NAME "com.apple.UNCUserNotification"
91
- #elif DEPLOYMENT_TARGET_EMBEDDED
92
- #define NOTIFICATION_PORT_NAME "com.apple.SBUserNotification"
93
- #else
94
- #error Unknown or unspecified DEPLOYMENT_TARGET
95
- #endif
90
+ #define NOTIFICATION_PORT_NAME_MAC "com.apple.UNCUserNotification"
91
+ #define NOTIFICATION_PORT_NAME_IOS "com.apple.SBUserNotification"
96
92
97
93
98
94
static void __CFUserNotificationDeallocate (CFTypeRef cf );
99
95
100
- static const CFRuntimeClass __CFUserNotificationClass = {
96
+ const CFRuntimeClass __CFUserNotificationClass = {
101
97
0 ,
102
98
"CFUserNotification" ,
103
99
NULL , // init
@@ -110,9 +106,7 @@ static const CFRuntimeClass __CFUserNotificationClass = {
110
106
};
111
107
112
108
CFTypeID CFUserNotificationGetTypeID (void ) {
113
- static dispatch_once_t initOnce = 0 ;
114
- dispatch_once (& initOnce , ^{ __kCFUserNotificationTypeID = _CFRuntimeRegisterClass (& __CFUserNotificationClass ); });
115
- return __kCFUserNotificationTypeID ;
109
+ return _kCFRuntimeIDCFUserNotification ;
116
110
}
117
111
118
112
static void __CFUserNotificationDeallocate (CFTypeRef cf ) {
@@ -122,7 +116,7 @@ static void __CFUserNotificationDeallocate(CFTypeRef cf) {
122
116
CFRelease (userNotification -> _machPort );
123
117
userNotification -> _machPort = NULL ; // NOTE: this is still potentially racey and should probably have a CAS (for now this is just a stop-gap to reduce an already very rare crash potential) <rdar://problem/21077032>
124
118
} else if (MACH_PORT_NULL != userNotification -> _replyPort ) {
125
- mach_port_destroy (mach_task_self (), userNotification -> _replyPort );
119
+ mach_port_mod_refs (mach_task_self (), userNotification -> _replyPort , MACH_PORT_RIGHT_RECEIVE , -1 );
126
120
}
127
121
if (userNotification -> _sessionID ) CFRelease (userNotification -> _sessionID );
128
122
if (userNotification -> _responseDictionary ) CFRelease (userNotification -> _responseDictionary );
@@ -187,12 +181,19 @@ static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringR
187
181
mach_msg_base_t * msg = NULL ;
188
182
mach_port_t bootstrapPort = MACH_PORT_NULL , serverPort = MACH_PORT_NULL ;
189
183
CFIndex size ;
190
- char namebuffer [MAX_PORT_NAME_LENGTH + 1 ];
191
184
192
- strlcpy (namebuffer , NOTIFICATION_PORT_NAME , sizeof (namebuffer ));
185
+
186
+ #if TARGET_OS_OSX
187
+ const char * namebuffer = NOTIFICATION_PORT_NAME_MAC ;
188
+ const nameLen = sizeof (NOTIFICATION_PORT_NAME_MAC );
189
+ #else
190
+ const char * namebuffer = NOTIFICATION_PORT_NAME_IOS ;
191
+ const nameLen = sizeof (NOTIFICATION_PORT_NAME_IOS );
192
+ #endif
193
+
193
194
if (sessionID ) {
194
195
char sessionid [MAX_PORT_NAME_LENGTH + 1 ];
195
- CFIndex len = MAX_PORT_NAME_LENGTH - sizeof ( NOTIFICATION_PORT_NAME ) - sizeof (NOTIFICATION_PORT_NAME_SUFFIX );
196
+ CFIndex len = MAX_PORT_NAME_LENGTH - nameLen - sizeof (NOTIFICATION_PORT_NAME_SUFFIX );
196
197
CFStringGetBytes (sessionID , CFRangeMake (0 , CFStringGetLength (sessionID )), kCFStringEncodingUTF8 , 0 , false, (uint8_t * )sessionid , len , & size );
197
198
sessionid [len - 1 ] = '\0' ;
198
199
strlcat (namebuffer , NOTIFICATION_PORT_NAME_SUFFIX , sizeof (namebuffer ));
@@ -271,7 +272,9 @@ CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeI
271
272
} else {
272
273
if (dictionary ) CFUserNotificationLog (CFDictionaryGetValue (dictionary , kCFUserNotificationAlertHeaderKey ), CFDictionaryGetValue (dictionary , kCFUserNotificationAlertMessageKey ));
273
274
}
274
- if (ERR_SUCCESS != retval && MACH_PORT_NULL != replyPort ) mach_port_destroy (mach_task_self (), replyPort );
275
+ if (ERR_SUCCESS != retval && MACH_PORT_NULL != replyPort ) {
276
+ mach_port_mod_refs (mach_task_self (), replyPort , MACH_PORT_RIGHT_RECEIVE , -1 );
277
+ }
275
278
if (error ) * error = retval ;
276
279
return userNotification ;
277
280
}
@@ -290,7 +293,7 @@ static void _CFUserNotificationMachPortCallBack(CFMachPortRef port, void *m, CFI
290
293
CFMachPortInvalidate (userNotification -> _machPort );
291
294
CFRelease (userNotification -> _machPort );
292
295
userNotification -> _machPort = NULL ;
293
- mach_port_destroy (mach_task_self (), userNotification -> _replyPort );
296
+ mach_port_mod_refs (mach_task_self (), userNotification -> _replyPort , MACH_PORT_RIGHT_RECEIVE , -1 );
294
297
userNotification -> _replyPort = MACH_PORT_NULL ;
295
298
userNotification -> _callout (userNotification , responseFlags );
296
299
}
@@ -328,7 +331,7 @@ SInt32 CFUserNotificationReceiveResponse(CFUserNotificationRef userNotification,
328
331
CFRelease (userNotification -> _machPort );
329
332
userNotification -> _machPort = NULL ;
330
333
}
331
- mach_port_destroy (mach_task_self (), userNotification -> _replyPort );
334
+ mach_port_mod_refs (mach_task_self (), userNotification -> _replyPort , MACH_PORT_RIGHT_RECEIVE , -1 );
332
335
userNotification -> _replyPort = MACH_PORT_NULL ;
333
336
}
334
337
CFAllocatorDeallocate (kCFAllocatorSystemDefault , msg );
@@ -440,7 +443,8 @@ CF_EXPORT SInt32 CFUserNotificationDisplayAlert(CFTimeInterval timeout, CFOption
440
443
441
444
#undef MAX_STRING_LENGTH
442
445
#undef MAX_STRING_COUNT
443
- #undef NOTIFICATION_PORT_NAME
446
+ #undef NOTIFICATION_PORT_NAME_MAC
447
+ #undef NOTIFICATION_PORT_NAME_IOS
444
448
#undef MESSAGE_TIMEOUT
445
449
#undef MAX_PORT_NAME_LENGTH
446
450
#undef NOTIFICATION_PORT_NAME_SUFFIX
0 commit comments