11/* CFUserNotification.c
2- Copyright (c) 2000-2017 , Apple Inc. All rights reserved.
2+ Copyright (c) 2000-2018 , Apple Inc. All rights reserved.
33
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
55 Licensed under Apache License v2.0 with Runtime Library Exception
66 See http://swift.org/LICENSE.txt for license information
77 See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1414#include <CoreFoundation/CFNumber.h>
1515#include <CoreFoundation/CFRunLoop.h>
1616#include "CFInternal.h"
17+ #include "CFRuntime_Internal.h"
1718#include <CoreFoundation/CFMachPort.h>
1819#include <stdlib.h>
1920#include <unistd.h>
@@ -54,13 +55,13 @@ CONST_STRING_DECL(kCFUserNotificationPopUpTitlesKey, "PopUpTitles")
5455CONST_STRING_DECL (kCFUserNotificationTextFieldTitlesKey , "TextFieldTitles" )
5556CONST_STRING_DECL (kCFUserNotificationCheckBoxTitlesKey , "CheckBoxTitles" )
5657CONST_STRING_DECL (kCFUserNotificationTextFieldValuesKey , "TextFieldValues" )
58+ #if TARGET_OS_OSX
5759CONST_STRING_DECL (kCFUserNotificationPopUpSelectionKey , "PopUpSelection" )
60+ #endif
5861CONST_STRING_DECL (kCFUserNotificationKeyboardTypesKey , "KeyboardTypes" )
5962CONST_STRING_DECL (kCFUserNotificationAlertTopMostKey , "AlertTopMost" ) // boolean value
6063
6164
62- static CFTypeID __kCFUserNotificationTypeID = _kCFRuntimeNotATypeID ;
63-
6465struct __CFUserNotification {
6566 CFRuntimeBase _base ;
6667 SInt32 _replyPort ;
@@ -86,18 +87,13 @@ static CFStringRef __CFUserNotificationCopyDescription(CFTypeRef cf) {
8687#define MAX_PORT_NAME_LENGTH 63
8788#define NOTIFICATION_PORT_NAME_SUFFIX ".session."
8889#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"
9692
9793
9894static void __CFUserNotificationDeallocate (CFTypeRef cf );
9995
100- static const CFRuntimeClass __CFUserNotificationClass = {
96+ const CFRuntimeClass __CFUserNotificationClass = {
10197 0 ,
10298 "CFUserNotification" ,
10399 NULL , // init
@@ -110,9 +106,7 @@ static const CFRuntimeClass __CFUserNotificationClass = {
110106};
111107
112108CFTypeID CFUserNotificationGetTypeID (void ) {
113- static dispatch_once_t initOnce = 0 ;
114- dispatch_once (& initOnce , ^{ __kCFUserNotificationTypeID = _CFRuntimeRegisterClass (& __CFUserNotificationClass ); });
115- return __kCFUserNotificationTypeID ;
109+ return _kCFRuntimeIDCFUserNotification ;
116110}
117111
118112static void __CFUserNotificationDeallocate (CFTypeRef cf ) {
@@ -122,7 +116,7 @@ static void __CFUserNotificationDeallocate(CFTypeRef cf) {
122116 CFRelease (userNotification -> _machPort );
123117 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>
124118 } 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 );
126120 }
127121 if (userNotification -> _sessionID ) CFRelease (userNotification -> _sessionID );
128122 if (userNotification -> _responseDictionary ) CFRelease (userNotification -> _responseDictionary );
@@ -187,12 +181,19 @@ static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringR
187181 mach_msg_base_t * msg = NULL ;
188182 mach_port_t bootstrapPort = MACH_PORT_NULL , serverPort = MACH_PORT_NULL ;
189183 CFIndex size ;
190- char namebuffer [MAX_PORT_NAME_LENGTH + 1 ];
191184
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+
193194 if (sessionID ) {
194195 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 );
196197 CFStringGetBytes (sessionID , CFRangeMake (0 , CFStringGetLength (sessionID )), kCFStringEncodingUTF8 , 0 , false, (uint8_t * )sessionid , len , & size );
197198 sessionid [len - 1 ] = '\0' ;
198199 strlcat (namebuffer , NOTIFICATION_PORT_NAME_SUFFIX , sizeof (namebuffer ));
@@ -271,7 +272,9 @@ CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeI
271272 } else {
272273 if (dictionary ) CFUserNotificationLog (CFDictionaryGetValue (dictionary , kCFUserNotificationAlertHeaderKey ), CFDictionaryGetValue (dictionary , kCFUserNotificationAlertMessageKey ));
273274 }
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+ }
275278 if (error ) * error = retval ;
276279 return userNotification ;
277280}
@@ -290,7 +293,7 @@ static void _CFUserNotificationMachPortCallBack(CFMachPortRef port, void *m, CFI
290293 CFMachPortInvalidate (userNotification -> _machPort );
291294 CFRelease (userNotification -> _machPort );
292295 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 );
294297 userNotification -> _replyPort = MACH_PORT_NULL ;
295298 userNotification -> _callout (userNotification , responseFlags );
296299}
@@ -328,7 +331,7 @@ SInt32 CFUserNotificationReceiveResponse(CFUserNotificationRef userNotification,
328331 CFRelease (userNotification -> _machPort );
329332 userNotification -> _machPort = NULL ;
330333 }
331- mach_port_destroy (mach_task_self (), userNotification -> _replyPort );
334+ mach_port_mod_refs (mach_task_self (), userNotification -> _replyPort , MACH_PORT_RIGHT_RECEIVE , -1 );
332335 userNotification -> _replyPort = MACH_PORT_NULL ;
333336 }
334337 CFAllocatorDeallocate (kCFAllocatorSystemDefault , msg );
@@ -440,7 +443,8 @@ CF_EXPORT SInt32 CFUserNotificationDisplayAlert(CFTimeInterval timeout, CFOption
440443
441444#undef MAX_STRING_LENGTH
442445#undef MAX_STRING_COUNT
443- #undef NOTIFICATION_PORT_NAME
446+ #undef NOTIFICATION_PORT_NAME_MAC
447+ #undef NOTIFICATION_PORT_NAME_IOS
444448#undef MESSAGE_TIMEOUT
445449#undef MAX_PORT_NAME_LENGTH
446450#undef NOTIFICATION_PORT_NAME_SUFFIX
0 commit comments