├── .gitattributes ├── .gitignore ├── Info.plist ├── README.md ├── headers ├── launch.h ├── xpc │ ├── XPC.apinotes │ ├── activity.h │ ├── availability.h │ ├── base.h │ ├── connection.h │ ├── debug.h │ ├── endpoint.h │ ├── module.modulemap │ ├── rich_error.h │ ├── session.h │ └── xpc.h └── xpc_private.h ├── jbsigs.h ├── jbsigs ├── jbsigs-1.h ├── jbsigs-10.h ├── jbsigs-11.h ├── jbsigs-12.h ├── jbsigs-13.h ├── jbsigs-14.h ├── jbsigs-15.h ├── jbsigs-16.h ├── jbsigs-2.h ├── jbsigs-3.h ├── jbsigs-4.h ├── jbsigs-5.h ├── jbsigs-6.h ├── jbsigs-7.h ├── jbsigs-8.h └── jbsigs-9.h ├── jbsigs_generator.m └── main.m /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | AppDelegate.h 4 | AppDelegate.m 5 | Assets.xcassets/AccentColor.colorset/Contents.json 6 | Assets.xcassets/AppIcon.appiconset/Contents.json 7 | Assets.xcassets/Contents.json 8 | Base.lproj/LaunchScreen.storyboard 9 | Base.lproj/Main.storyboard 10 | SceneDelegate.h 11 | SceneDelegate.m 12 | ViewController.h 13 | ViewController.m 14 | test.m 15 | jbsigfiles/* 16 | jbsigs_generator 17 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LSApplicationQueriesSchemes 6 | 7 | sileo 8 | zbra 9 | filza 10 | cydia 11 | installer 12 | apt-repo 13 | test 14 | 15 | UIApplicationSceneManifest 16 | 17 | UIApplicationSupportsMultipleScenes 18 | 19 | UISceneConfigurations 20 | 21 | UIWindowSceneSessionRoleApplication 22 | 23 | 24 | UISceneConfigurationName 25 | Default Configuration 26 | UISceneDelegateClassName 27 | SceneDelegate 28 | UISceneStoryboardFile 29 | Main 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JailbreakDetector 2 | 3 | Modern Jailbreak Detection Demo 4 | 5 | -------------------------------------------------------------------------------- /headers/launch.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_LAUNCH_H__ 2 | #define __XPC_LAUNCH_H__ 3 | 4 | /*! 5 | * @header 6 | * These interfaces were only ever documented for the purpose of allowing a 7 | * launchd job to obtain file descriptors associated with the sockets it 8 | * advertised in its launchd.plist(5). That functionality is now available in a 9 | * much more straightforward fashion through the {@link launch_activate_socket} 10 | * API. 11 | * 12 | * There are currently no replacements for other uses of the {@link launch_msg} 13 | * API, including submitting, removing, starting, stopping and listing jobs. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #if __has_feature(assume_nonnull) 25 | _Pragma("clang assume_nonnull begin") 26 | #endif 27 | __BEGIN_DECLS 28 | 29 | #define LAUNCH_KEY_SUBMITJOB "SubmitJob" 30 | #define LAUNCH_KEY_REMOVEJOB "RemoveJob" 31 | #define LAUNCH_KEY_STARTJOB "StartJob" 32 | #define LAUNCH_KEY_STOPJOB "StopJob" 33 | #define LAUNCH_KEY_GETJOB "GetJob" 34 | #define LAUNCH_KEY_GETJOBS "GetJobs" 35 | #define LAUNCH_KEY_CHECKIN "CheckIn" 36 | 37 | #define LAUNCH_JOBKEY_LABEL "Label" 38 | #define LAUNCH_JOBKEY_DISABLED "Disabled" 39 | #define LAUNCH_JOBKEY_USERNAME "UserName" 40 | #define LAUNCH_JOBKEY_GROUPNAME "GroupName" 41 | #define LAUNCH_JOBKEY_TIMEOUT "TimeOut" 42 | #define LAUNCH_JOBKEY_EXITTIMEOUT "ExitTimeOut" 43 | #define LAUNCH_JOBKEY_INITGROUPS "InitGroups" 44 | #define LAUNCH_JOBKEY_SOCKETS "Sockets" 45 | #define LAUNCH_JOBKEY_MACHSERVICES "MachServices" 46 | #define LAUNCH_JOBKEY_MACHSERVICELOOKUPPOLICIES "MachServiceLookupPolicies" 47 | #define LAUNCH_JOBKEY_INETDCOMPATIBILITY "inetdCompatibility" 48 | #define LAUNCH_JOBKEY_ENABLEGLOBBING "EnableGlobbing" 49 | #define LAUNCH_JOBKEY_PROGRAMARGUMENTS "ProgramArguments" 50 | #define LAUNCH_JOBKEY_PROGRAM "Program" 51 | #define LAUNCH_JOBKEY_ONDEMAND "OnDemand" 52 | #define LAUNCH_JOBKEY_KEEPALIVE "KeepAlive" 53 | #define LAUNCH_JOBKEY_LIMITLOADTOHOSTS "LimitLoadToHosts" 54 | #define LAUNCH_JOBKEY_LIMITLOADFROMHOSTS "LimitLoadFromHosts" 55 | #define LAUNCH_JOBKEY_LIMITLOADTOSESSIONTYPE "LimitLoadToSessionType" 56 | #define LAUNCH_JOBKEY_LIMITLOADTOHARDWARE "LimitLoadToHardware" 57 | #define LAUNCH_JOBKEY_LIMITLOADFROMHARDWARE "LimitLoadFromHardware" 58 | #define LAUNCH_JOBKEY_RUNATLOAD "RunAtLoad" 59 | #define LAUNCH_JOBKEY_ROOTDIRECTORY "RootDirectory" 60 | #define LAUNCH_JOBKEY_WORKINGDIRECTORY "WorkingDirectory" 61 | #define LAUNCH_JOBKEY_ENVIRONMENTVARIABLES "EnvironmentVariables" 62 | #define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES "UserEnvironmentVariables" 63 | #define LAUNCH_JOBKEY_UMASK "Umask" 64 | #define LAUNCH_JOBKEY_NICE "Nice" 65 | #define LAUNCH_JOBKEY_HOPEFULLYEXITSFIRST "HopefullyExitsFirst" 66 | #define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST "HopefullyExitsLast" 67 | #define LAUNCH_JOBKEY_LOWPRIORITYIO "LowPriorityIO" 68 | #define LAUNCH_JOBKEY_LOWPRIORITYBACKGROUNDIO "LowPriorityBackgroundIO" 69 | #define LAUNCH_JOBKEY_MATERIALIZEDATALESSFILES "MaterializeDatalessFiles" 70 | #define LAUNCH_JOBKEY_SESSIONCREATE "SessionCreate" 71 | #define LAUNCH_JOBKEY_STARTONMOUNT "StartOnMount" 72 | #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS "SoftResourceLimits" 73 | #define LAUNCH_JOBKEY_HARDRESOURCELIMITS "HardResourceLimits" 74 | #define LAUNCH_JOBKEY_STANDARDINPATH "StandardInPath" 75 | #define LAUNCH_JOBKEY_STANDARDOUTPATH "StandardOutPath" 76 | #define LAUNCH_JOBKEY_STANDARDERRORPATH "StandardErrorPath" 77 | #define LAUNCH_JOBKEY_DEBUG "Debug" 78 | #define LAUNCH_JOBKEY_WAITFORDEBUGGER "WaitForDebugger" 79 | #define LAUNCH_JOBKEY_QUEUEDIRECTORIES "QueueDirectories" 80 | #define LAUNCH_JOBKEY_HOMERELATIVEQUEUEDIRECTORIES "HomeRelativeQueueDirectories" 81 | #define LAUNCH_JOBKEY_WATCHPATHS "WatchPaths" 82 | #define LAUNCH_JOBKEY_STARTINTERVAL "StartInterval" 83 | #define LAUNCH_JOBKEY_STARTCALENDARINTERVAL "StartCalendarInterval" 84 | #define LAUNCH_JOBKEY_BONJOURFDS "BonjourFDs" 85 | #define LAUNCH_JOBKEY_LASTEXITSTATUS "LastExitStatus" 86 | #define LAUNCH_JOBKEY_PID "PID" 87 | #define LAUNCH_JOBKEY_THROTTLEINTERVAL "ThrottleInterval" 88 | #define LAUNCH_JOBKEY_LAUNCHONLYONCE "LaunchOnlyOnce" 89 | #define LAUNCH_JOBKEY_ABANDONPROCESSGROUP "AbandonProcessGroup" 90 | #define LAUNCH_JOBKEY_IGNOREPROCESSGROUPATSHUTDOWN \ 91 | "IgnoreProcessGroupAtShutdown" 92 | #define LAUNCH_JOBKEY_LEGACYTIMERS "LegacyTimers" 93 | #define LAUNCH_JOBKEY_ENABLEPRESSUREDEXIT "EnablePressuredExit" 94 | #define LAUNCH_JOBKEY_ENABLETRANSACTIONS "EnableTransactions" 95 | #define LAUNCH_JOBKEY_DRAINMESSAGESONFAILEDINIT "DrainMessagesOnFailedInit" 96 | #define LAUNCH_JOBKEY_POLICIES "Policies" 97 | #define LAUNCH_JOBKEY_BUNDLEPROGRAM "BundleProgram" 98 | #define LAUNCH_JOBKEY_ASSOCIATEDBUNDLEIDENTIFIERS "AssociatedBundleIdentifiers" 99 | 100 | #define LAUNCH_JOBKEY_PUBLISHESEVENTS "PublishesEvents" 101 | #define LAUNCH_KEY_PUBLISHESEVENTS_DOMAININTERNAL "DomainInternal" 102 | 103 | #define LAUNCH_JOBPOLICY_DENYCREATINGOTHERJOBS "DenyCreatingOtherJobs" 104 | 105 | #define LAUNCH_JOBINETDCOMPATIBILITY_WAIT "Wait" 106 | #define LAUNCH_JOBINETDCOMPATIBILITY_INSTANCES "Instances" 107 | 108 | #define LAUNCH_JOBKEY_MACH_RESETATCLOSE "ResetAtClose" 109 | #define LAUNCH_JOBKEY_MACH_HIDEUNTILCHECKIN "HideUntilCheckIn" 110 | 111 | #define LAUNCH_JOBKEY_KEEPALIVE_SUCCESSFULEXIT "SuccessfulExit" 112 | #define LAUNCH_JOBKEY_KEEPALIVE_NETWORKSTATE "NetworkState" 113 | #define LAUNCH_JOBKEY_KEEPALIVE_PATHSTATE "PathState" 114 | #define LAUNCH_JOBKEY_KEEPALIVE_HOMERELATIVEPATHSTATE "HomeRelativePathState" 115 | #define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBACTIVE "OtherJobActive" 116 | #define LAUNCH_JOBKEY_KEEPALIVE_OTHERJOBENABLED "OtherJobEnabled" 117 | #define LAUNCH_JOBKEY_KEEPALIVE_AFTERINITIALDEMAND "AfterInitialDemand" 118 | #define LAUNCH_JOBKEY_KEEPALIVE_CRASHED "Crashed" 119 | 120 | #define LAUNCH_JOBKEY_LAUNCHEVENTS "LaunchEvents" 121 | 122 | #define LAUNCH_JOBKEY_CAL_MINUTE "Minute" 123 | #define LAUNCH_JOBKEY_CAL_HOUR "Hour" 124 | #define LAUNCH_JOBKEY_CAL_DAY "Day" 125 | #define LAUNCH_JOBKEY_CAL_WEEKDAY "Weekday" 126 | #define LAUNCH_JOBKEY_CAL_MONTH "Month" 127 | 128 | #define LAUNCH_JOBKEY_RESOURCELIMIT_CORE "Core" 129 | #define LAUNCH_JOBKEY_RESOURCELIMIT_CPU "CPU" 130 | #define LAUNCH_JOBKEY_RESOURCELIMIT_DATA "Data" 131 | #define LAUNCH_JOBKEY_RESOURCELIMIT_FSIZE "FileSize" 132 | #define LAUNCH_JOBKEY_RESOURCELIMIT_MEMLOCK "MemoryLock" 133 | #define LAUNCH_JOBKEY_RESOURCELIMIT_NOFILE "NumberOfFiles" 134 | #define LAUNCH_JOBKEY_RESOURCELIMIT_NPROC "NumberOfProcesses" 135 | #define LAUNCH_JOBKEY_RESOURCELIMIT_RSS "ResidentSetSize" 136 | #define LAUNCH_JOBKEY_RESOURCELIMIT_STACK "Stack" 137 | 138 | #define LAUNCH_JOBKEY_DISABLED_MACHINETYPE "MachineType" 139 | #define LAUNCH_JOBKEY_DISABLED_MODELNAME "ModelName" 140 | 141 | #define LAUNCH_JOBKEY_DATASTORES "Datastores" 142 | #define LAUNCH_JOBKEY_DATASTORES_SIZELIMIT "SizeLimit" 143 | 144 | #define LAUNCH_JOBSOCKETKEY_TYPE "SockType" 145 | #define LAUNCH_JOBSOCKETKEY_PASSIVE "SockPassive" 146 | #define LAUNCH_JOBSOCKETKEY_BONJOUR "Bonjour" 147 | #define LAUNCH_JOBSOCKETKEY_SECUREWITHKEY "SecureSocketWithKey" 148 | #define LAUNCH_JOBSOCKETKEY_PATHNAME "SockPathName" 149 | #define LAUNCH_JOBSOCKETKEY_PATHMODE "SockPathMode" 150 | #define LAUNCH_JOBSOCKETKEY_PATHOWNER "SockPathOwner" 151 | #define LAUNCH_JOBSOCKETKEY_PATHGROUP "SockPathGroup" 152 | #define LAUNCH_JOBSOCKETKEY_NODENAME "SockNodeName" 153 | #define LAUNCH_JOBSOCKETKEY_SERVICENAME "SockServiceName" 154 | #define LAUNCH_JOBSOCKETKEY_FAMILY "SockFamily" 155 | #define LAUNCH_JOBSOCKETKEY_PROTOCOL "SockProtocol" 156 | #define LAUNCH_JOBSOCKETKEY_MULTICASTGROUP "MulticastGroup" 157 | 158 | #define LAUNCH_JOBKEY_PROCESSTYPE "ProcessType" 159 | #define LAUNCH_KEY_PROCESSTYPE_APP "App" 160 | #define LAUNCH_KEY_PROCESSTYPE_STANDARD "Standard" 161 | #define LAUNCH_KEY_PROCESSTYPE_BACKGROUND "Background" 162 | #define LAUNCH_KEY_PROCESSTYPE_INTERACTIVE "Interactive" 163 | #define LAUNCH_KEY_PROCESSTYPE_ADAPTIVE "Adaptive" 164 | 165 | /*! 166 | * @function launch_activate_socket 167 | * 168 | * @abstract 169 | * Retrieves the file descriptors for sockets specified in the process' 170 | * launchd.plist(5). 171 | * 172 | * @param name 173 | * The name of the socket entry in the service's Sockets dictionary. 174 | * 175 | * @param fds 176 | * On return, this parameter will be populated with an array of file 177 | * descriptors. One socket can have many descriptors associated with it 178 | * depending on the characteristics of the network interfaces on the system. 179 | * The descriptors in this array are the results of calling getaddrinfo(3) with 180 | * the parameters described in launchd.plist(5). 181 | * 182 | * The caller is responsible for calling free(3) on the returned pointer. 183 | * 184 | * @param cnt 185 | * The number of file descriptor entries in the returned array. 186 | * 187 | * @result 188 | * On success, zero is returned. Otherwise, an appropriate POSIX-domain is 189 | * returned. Possible error codes are: 190 | * 191 | * ENOENT -> There was no socket of the specified name owned by the caller. 192 | * ESRCH -> The caller is not a process managed by launchd. 193 | * EALREADY -> The socket has already been activated by the caller. 194 | */ 195 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 196 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 197 | int 198 | launch_activate_socket(const char *name, 199 | int * _Nonnull * _Nullable fds, size_t *cnt); 200 | 201 | typedef struct _launch_data *launch_data_t; 202 | typedef void (*launch_data_dict_iterator_t)(const launch_data_t lval, 203 | const char *key, void * _Nullable ctx); 204 | 205 | typedef enum { 206 | LAUNCH_DATA_DICTIONARY = 1, 207 | LAUNCH_DATA_ARRAY, 208 | LAUNCH_DATA_FD, 209 | LAUNCH_DATA_INTEGER, 210 | LAUNCH_DATA_REAL, 211 | LAUNCH_DATA_BOOL, 212 | LAUNCH_DATA_STRING, 213 | LAUNCH_DATA_OPAQUE, 214 | LAUNCH_DATA_ERRNO, 215 | LAUNCH_DATA_MACHPORT, 216 | } launch_data_type_t; 217 | 218 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 219 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 220 | launch_data_t 221 | launch_data_alloc(launch_data_type_t type); 222 | 223 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 224 | OS_EXPORT OS_MALLOC OS_WARN_RESULT OS_NONNULL1 225 | launch_data_t 226 | launch_data_copy(launch_data_t ld); 227 | 228 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 229 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 230 | launch_data_type_t 231 | launch_data_get_type(const launch_data_t ld); 232 | 233 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 234 | OS_EXPORT OS_NONNULL1 235 | void 236 | launch_data_free(launch_data_t ld); 237 | 238 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 239 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 240 | bool 241 | launch_data_dict_insert(launch_data_t ldict, const launch_data_t lval, 242 | const char *key); 243 | 244 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 245 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2 246 | launch_data_t _Nullable 247 | launch_data_dict_lookup(const launch_data_t ldict, const char *key); 248 | 249 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 250 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 251 | bool 252 | launch_data_dict_remove(launch_data_t ldict, const char *key); 253 | 254 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 255 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 256 | void 257 | launch_data_dict_iterate(const launch_data_t ldict, 258 | launch_data_dict_iterator_t iterator, void * _Nullable ctx); 259 | 260 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 261 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 262 | size_t 263 | launch_data_dict_get_count(const launch_data_t ldict); 264 | 265 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 266 | OS_EXPORT OS_NONNULL1 OS_NONNULL2 267 | bool 268 | launch_data_array_set_index(launch_data_t larray, const launch_data_t lval, 269 | size_t idx); 270 | 271 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 272 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 273 | launch_data_t 274 | launch_data_array_get_index(const launch_data_t larray, size_t idx); 275 | 276 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 277 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 278 | size_t 279 | launch_data_array_get_count(const launch_data_t larray); 280 | 281 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 282 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 283 | launch_data_t 284 | launch_data_new_fd(int fd); 285 | 286 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 287 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 288 | launch_data_t 289 | launch_data_new_machport(mach_port_t val); 290 | 291 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 292 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 293 | launch_data_t 294 | launch_data_new_integer(long long val); 295 | 296 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 297 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 298 | launch_data_t 299 | launch_data_new_bool(bool val); 300 | 301 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 302 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 303 | launch_data_t 304 | launch_data_new_real(double val); 305 | 306 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 307 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 308 | launch_data_t 309 | launch_data_new_string(const char *val); 310 | 311 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 312 | OS_EXPORT OS_MALLOC OS_WARN_RESULT 313 | launch_data_t 314 | launch_data_new_opaque(const void *bytes, size_t sz); 315 | 316 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 317 | OS_EXPORT OS_NONNULL1 318 | bool 319 | launch_data_set_fd(launch_data_t ld, int fd); 320 | 321 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 322 | OS_EXPORT OS_NONNULL1 323 | bool 324 | launch_data_set_machport(launch_data_t ld, mach_port_t mp); 325 | 326 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 327 | OS_EXPORT OS_NONNULL1 328 | bool 329 | launch_data_set_integer(launch_data_t ld, long long val); 330 | 331 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 332 | OS_EXPORT OS_NONNULL1 333 | bool 334 | launch_data_set_bool(launch_data_t ld, bool val); 335 | 336 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 337 | OS_EXPORT OS_NONNULL1 338 | bool 339 | launch_data_set_real(launch_data_t ld, double val); 340 | 341 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 342 | OS_EXPORT OS_NONNULL1 343 | bool 344 | launch_data_set_string(launch_data_t ld, const char *val); 345 | 346 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 347 | OS_EXPORT OS_NONNULL1 348 | bool 349 | launch_data_set_opaque(launch_data_t ld, const void *bytes, size_t sz); 350 | 351 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 352 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 353 | int 354 | launch_data_get_fd(const launch_data_t ld); 355 | 356 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 357 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 358 | mach_port_t 359 | launch_data_get_machport(const launch_data_t ld); 360 | 361 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 362 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 363 | long long 364 | launch_data_get_integer(const launch_data_t ld); 365 | 366 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 367 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 368 | bool 369 | launch_data_get_bool(const launch_data_t ld); 370 | 371 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 372 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 373 | double 374 | launch_data_get_real(const launch_data_t ld); 375 | 376 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 377 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 378 | const char * 379 | launch_data_get_string(const launch_data_t ld); 380 | 381 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 382 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 383 | void * _Nullable 384 | launch_data_get_opaque(const launch_data_t ld); 385 | 386 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 387 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 388 | size_t 389 | launch_data_get_opaque_size(const launch_data_t ld); 390 | 391 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 392 | OS_EXPORT OS_WARN_RESULT OS_NONNULL1 393 | int 394 | launch_data_get_errno(const launch_data_t ld); 395 | 396 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 397 | OS_EXPORT OS_WARN_RESULT 398 | int 399 | launch_get_fd(void); 400 | 401 | __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_8_0) 402 | OS_EXPORT OS_MALLOC OS_WARN_RESULT OS_NONNULL1 403 | launch_data_t 404 | launch_msg(const launch_data_t request); 405 | 406 | __END_DECLS 407 | #if __has_feature(assume_nonnull) 408 | _Pragma("clang assume_nonnull end") 409 | #endif 410 | 411 | #endif // __XPC_LAUNCH_H__ 412 | -------------------------------------------------------------------------------- /headers/xpc/XPC.apinotes: -------------------------------------------------------------------------------- 1 | Name: XPC 2 | Functions: 3 | # xpc_object 4 | - Name: xpc_retain 5 | Availability: nonswift 6 | - Name: xpc_release 7 | Availability: nonswift 8 | -------------------------------------------------------------------------------- /headers/xpc/activity.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_ACTIVITY_H__ 2 | #define __XPC_ACTIVITY_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifdef __BLOCKS__ 11 | 12 | XPC_ASSUME_NONNULL_BEGIN 13 | __BEGIN_DECLS 14 | 15 | /* 16 | * The following are a collection of keys and values used to set an activity's 17 | * execution criteria. 18 | */ 19 | 20 | /*! 21 | * @constant XPC_ACTIVITY_INTERVAL 22 | * An integer property indicating the desired time interval (in seconds) of the 23 | * activity. The activity will not be run more than once per time interval. 24 | * Due to the nature of XPC Activity finding an opportune time to run 25 | * the activity, any two occurrences may be more or less than 'interval' 26 | * seconds apart, but on average will be 'interval' seconds apart. 27 | * The presence of this key implies the following, unless overridden: 28 | * - XPC_ACTIVITY_REPEATING with a value of true 29 | * - XPC_ACTIVITY_DELAY with a value of half the 'interval' 30 | * The delay enforces a minimum distance between any two occurrences. 31 | * - XPC_ACTIVITY_GRACE_PERIOD with a value of half the 'interval'. 32 | * The grace period is the amount of time allowed to pass after the end of 33 | * the interval before more aggressive scheduling occurs. The grace period 34 | * does not increase the size of the interval. 35 | */ 36 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 37 | XPC_EXPORT 38 | const char * const XPC_ACTIVITY_INTERVAL; 39 | 40 | /*! 41 | * @constant XPC_ACTIVITY_REPEATING 42 | * A boolean property indicating whether this is a repeating activity. 43 | */ 44 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 45 | XPC_EXPORT 46 | const char * const XPC_ACTIVITY_REPEATING; 47 | 48 | /*! 49 | * @constant XPC_ACTIVITY_DELAY 50 | * An integer property indicating the number of seconds to delay before 51 | * beginning the activity. 52 | */ 53 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 54 | XPC_EXPORT 55 | const char * const XPC_ACTIVITY_DELAY; 56 | 57 | /*! 58 | * @constant XPC_ACTIVITY_GRACE_PERIOD 59 | * An integer property indicating the number of seconds to allow as a grace 60 | * period before the scheduling of the activity becomes more aggressive. 61 | */ 62 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 63 | XPC_EXPORT 64 | const char * const XPC_ACTIVITY_GRACE_PERIOD; 65 | 66 | 67 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 68 | XPC_EXPORT 69 | const int64_t XPC_ACTIVITY_INTERVAL_1_MIN; 70 | 71 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 72 | XPC_EXPORT 73 | const int64_t XPC_ACTIVITY_INTERVAL_5_MIN; 74 | 75 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 76 | XPC_EXPORT 77 | const int64_t XPC_ACTIVITY_INTERVAL_15_MIN; 78 | 79 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 80 | XPC_EXPORT 81 | const int64_t XPC_ACTIVITY_INTERVAL_30_MIN; 82 | 83 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 84 | XPC_EXPORT 85 | const int64_t XPC_ACTIVITY_INTERVAL_1_HOUR; 86 | 87 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 88 | XPC_EXPORT 89 | const int64_t XPC_ACTIVITY_INTERVAL_4_HOURS; 90 | 91 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 92 | XPC_EXPORT 93 | const int64_t XPC_ACTIVITY_INTERVAL_8_HOURS; 94 | 95 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 96 | XPC_EXPORT 97 | const int64_t XPC_ACTIVITY_INTERVAL_1_DAY; 98 | 99 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 100 | XPC_EXPORT 101 | const int64_t XPC_ACTIVITY_INTERVAL_7_DAYS; 102 | 103 | /*! 104 | * @constant XPC_ACTIVITY_PRIORITY 105 | * A string property indicating the priority of the activity. 106 | */ 107 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 108 | XPC_EXPORT 109 | const char * const XPC_ACTIVITY_PRIORITY; 110 | 111 | /*! 112 | * @constant XPC_ACTIVITY_PRIORITY_MAINTENANCE 113 | * A string indicating activity is maintenance priority. 114 | * 115 | * Maintenance priority is intended for user-invisible maintenance tasks 116 | * such as garbage collection or optimization. 117 | * 118 | * Maintenance activities are not permitted to run if the device thermal 119 | * condition exceeds a nominal level or if the battery level is lower than 20%. 120 | * In Low Power Mode (on supported devices), maintenance activities are not 121 | * permitted to run while the device is on battery, or plugged in and the 122 | * battery level is lower than 30%. 123 | */ 124 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 125 | XPC_EXPORT 126 | const char * const XPC_ACTIVITY_PRIORITY_MAINTENANCE; 127 | 128 | /*! 129 | * @constant XPC_ACTIVITY_PRIORITY_UTILITY 130 | * A string indicating activity is utility priority. 131 | * 132 | * Utility priority is intended for user-visible tasks such as fetching data 133 | * from the network, copying files, or importing data. 134 | * 135 | * Utility activities are not permitted to run if the device thermal condition 136 | * exceeds a moderate level or if the battery level is less than 10%. In Low 137 | * Power Mode (on supported devices) when on battery power, utility activities 138 | * are only permitted when they are close to their deadline (90% of their time 139 | * window has elapsed). 140 | */ 141 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 142 | XPC_EXPORT 143 | const char * const XPC_ACTIVITY_PRIORITY_UTILITY; 144 | 145 | /*! 146 | * @constant XPC_ACTIVITY_ALLOW_BATTERY 147 | * A Boolean value indicating whether the activity should be allowed to run 148 | * while the computer is on battery power. The default value is false for 149 | * maintenance priority activity and true for utility priority activity. 150 | */ 151 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 152 | XPC_EXPORT 153 | const char * const XPC_ACTIVITY_ALLOW_BATTERY; 154 | 155 | /*! 156 | * @constant XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP 157 | * A Boolean value indicating whether the activity should only be performed 158 | * while device appears to be asleep. Note that the definition of screen sleep 159 | * may vary by platform and may include states where the device is known to be 160 | * idle despite the fact that the display itself is still powered. Defaults to 161 | * false. 162 | */ 163 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 164 | XPC_EXPORT 165 | const char * const XPC_ACTIVITY_REQUIRE_SCREEN_SLEEP; // bool 166 | 167 | /*! 168 | * @constant XPC_ACTIVITY_PREVENT_DEVICE_SLEEP 169 | * A Boolean value indicating whether the activity should prevent system sleep while 170 | * running on battery. 171 | * If this property is set, the activity scheduler will take the appropriate power 172 | * assertion to keep the device (but not the screen) awake while the activity is running. 173 | * Only activities which perform critical system functions that do not want to be 174 | * interrupted by system sleep should set this. 175 | * Setting this property can impact battery life. 176 | */ 177 | __API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0)) 178 | XPC_EXPORT 179 | const char * const XPC_ACTIVITY_PREVENT_DEVICE_SLEEP; // bool 180 | 181 | /*! 182 | * @constant XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL 183 | * An integer percentage of minimum battery charge required to allow the 184 | * activity to run. A default minimum battery level is determined by the 185 | * system. 186 | */ 187 | __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, 188 | "REQUIRE_BATTERY_LEVEL is not implemented") 189 | XPC_EXPORT 190 | const char * const XPC_ACTIVITY_REQUIRE_BATTERY_LEVEL; // int (%) 191 | 192 | /*! 193 | * @constant XPC_ACTIVITY_REQUIRE_HDD_SPINNING 194 | * A Boolean value indicating whether the activity should only be performed 195 | * while the hard disk drive (HDD) is spinning. Computers with flash storage 196 | * are considered to be equivalent to HDD spinning. Defaults to false. 197 | */ 198 | __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_9, __MAC_10_9, __IPHONE_7_0, __IPHONE_7_0, 199 | "REQUIRE_HDD_SPINNING is not implemented") 200 | XPC_EXPORT 201 | const char * const XPC_ACTIVITY_REQUIRE_HDD_SPINNING; // bool 202 | 203 | /*! 204 | * @define XPC_TYPE_ACTIVITY 205 | * A type representing the XPC activity object. 206 | */ 207 | #define XPC_TYPE_ACTIVITY (&_xpc_type_activity) 208 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 209 | XPC_EXPORT 210 | XPC_TYPE(_xpc_type_activity); 211 | 212 | /*! 213 | * @typedef xpc_activity_t 214 | * 215 | * @abstract 216 | * An XPC activity object. 217 | * 218 | * @discussion 219 | * This object represents a set of execution criteria and a current execution 220 | * state for background activity on the system. Once an activity is registered, 221 | * the system will evaluate its criteria to determine whether the activity is 222 | * eligible to run under current system conditions. When an activity becomes 223 | * eligible to run, its execution state will be updated and an invocation of 224 | * its handler block will be made. 225 | */ 226 | XPC_DECL(xpc_activity); 227 | 228 | /*! 229 | * @typedef xpc_activity_handler_t 230 | * 231 | * @abstract 232 | * A block that is called when an XPC activity becomes eligible to run. 233 | */ 234 | XPC_NONNULL1 235 | typedef void (^xpc_activity_handler_t)(xpc_activity_t activity); 236 | 237 | /*! 238 | * @constant XPC_ACTIVITY_CHECK_IN 239 | * This constant may be passed to xpc_activity_register() as the criteria 240 | * dictionary in order to check in with the system for previously registered 241 | * activity using the same identifier (for example, an activity taken from a 242 | * launchd property list). 243 | */ 244 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 245 | XPC_EXPORT 246 | const xpc_object_t XPC_ACTIVITY_CHECK_IN; 247 | 248 | /*! 249 | * @function xpc_activity_register 250 | * 251 | * @abstract 252 | * Registers an activity with the system. 253 | * 254 | * @discussion 255 | * Registers a new activity with the system. The criteria of the activity are 256 | * described by the dictionary passed to this function. If an activity with the 257 | * same identifier already exists, the criteria provided override the existing 258 | * criteria unless the special dictionary XPC_ACTIVITY_CHECK_IN is used. The 259 | * XPC_ACTIVITY_CHECK_IN dictionary instructs the system to first look up an 260 | * existing activity without modifying its criteria. Once the existing activity 261 | * is found (or a new one is created with an empty set of criteria) the handler 262 | * will be called with an activity object in the XPC_ACTIVITY_STATE_CHECK_IN 263 | * state. 264 | * 265 | * @param identifier 266 | * A unique identifier for the activity. Each application has its own namespace. 267 | * The identifier should remain constant across registrations, relaunches of 268 | * the application, and reboots. It should identify the kind of work being done, 269 | * not a particular invocation of the work. 270 | * 271 | * @param criteria 272 | * A dictionary of criteria for the activity. 273 | * 274 | * @param handler 275 | * The handler block to be called when the activity changes state to one of the 276 | * following states: 277 | * - XPC_ACTIVITY_STATE_CHECK_IN (optional) 278 | * - XPC_ACTIVITY_STATE_RUN 279 | * 280 | * The handler block is never invoked reentrantly. It will be invoked on a 281 | * dispatch queue with an appropriate priority to perform the activity. 282 | */ 283 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 284 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL3 285 | void 286 | xpc_activity_register(const char *identifier, xpc_object_t criteria, 287 | xpc_activity_handler_t handler); 288 | 289 | /*! 290 | * @function xpc_activity_copy_criteria 291 | * 292 | * @abstract 293 | * Returns an XPC dictionary describing the execution criteria of an activity. 294 | * This will return NULL in cases where the activity has already completed, e.g. 295 | * when checking in to an event that finished and was not rescheduled. 296 | */ 297 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 298 | XPC_EXPORT XPC_WARN_RESULT XPC_RETURNS_RETAINED XPC_NONNULL1 299 | xpc_object_t _Nullable 300 | xpc_activity_copy_criteria(xpc_activity_t activity); 301 | 302 | /*! 303 | * @function xpc_activity_set_criteria 304 | * 305 | * @abstract 306 | * Modifies the execution criteria of an activity. 307 | */ 308 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 309 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 310 | void 311 | xpc_activity_set_criteria(xpc_activity_t activity, xpc_object_t criteria); 312 | 313 | /*! 314 | * @enum xpc_activity_state_t 315 | * An activity is defined to be in one of the following states. Applications 316 | * may check the current state of the activity using xpc_activity_get_state() 317 | * in the handler block provided to xpc_activity_register(). 318 | * 319 | * The application can modify the state of the activity by calling 320 | * xpc_activity_set_state() with one of the following: 321 | * - XPC_ACTIVITY_STATE_DEFER 322 | * - XPC_ACTIVITY_STATE_CONTINUE 323 | * - XPC_ACTIVITY_STATE_DONE 324 | * 325 | * @constant XPC_ACTIVITY_STATE_CHECK_IN 326 | * An activity in this state has just completed a checkin with the system after 327 | * XPC_ACTIVITY_CHECK_IN was provided as the criteria dictionary to 328 | * xpc_activity_register. The state gives the application an opportunity to 329 | * inspect and modify the activity's criteria. 330 | * 331 | * @constant XPC_ACTIVITY_STATE_WAIT 332 | * An activity in this state is waiting for an opportunity to run. This value 333 | * is never returned within the activity's handler block, as the block is 334 | * invoked in response to XPC_ACTIVITY_STATE_CHECK_IN or XPC_ACTIVITY_STATE_RUN. 335 | * 336 | * Note: 337 | * A launchd job may idle exit while an activity is in the wait state and be 338 | * relaunched in response to the activity becoming runnable. The launchd job 339 | * simply needs to re-register for the activity on its next launch by passing 340 | * XPC_ACTIVITY_STATE_CHECK_IN to xpc_activity_register(). 341 | * 342 | * @constant XPC_ACTIVITY_STATE_RUN 343 | * An activity in this state is eligible to run based on its criteria. 344 | * 345 | * @constant XPC_ACTIVITY_STATE_DEFER 346 | * An application may pass this value to xpc_activity_set_state() to indicate 347 | * that the activity should be deferred (placed back into the WAIT state) until 348 | * a time when its criteria are met again. Deferring an activity does not reset 349 | * any of its time-based criteria (in other words, it will remain past due). 350 | * 351 | * IMPORTANT: 352 | * This should be done in response to observing xpc_activity_should_defer(). 353 | * It should not be done unilaterally. If you determine that conditions are bad 354 | * to do your activity's work for reasons you can't express in a criteria 355 | * dictionary, you should set the activity's state to XPC_ACTIVITY_STATE_DONE. 356 | * 357 | * 358 | * @constant XPC_ACTIVITY_STATE_CONTINUE 359 | * An application may pass this value to xpc_activity_set_state() to indicate 360 | * that the activity will continue its operation beyond the return of its 361 | * handler block. This can be used to extend an activity to include asynchronous 362 | * operations. The activity's handler block will not be invoked again until the 363 | * state has been updated to either XPC_ACTIVITY_STATE_DEFER or, in the case 364 | * of repeating activity, XPC_ACTIVITY_STATE_DONE. 365 | * 366 | * @constant XPC_ACTIVITY_STATE_DONE 367 | * An application may pass this value to xpc_activity_set_state() to indicate 368 | * that the activity has completed. For non-repeating activity, the resources 369 | * associated with the activity will be automatically released upon return from 370 | * the handler block. For repeating activity, timers present in the activity's 371 | * criteria will be reset. 372 | */ 373 | enum { 374 | XPC_ACTIVITY_STATE_CHECK_IN, 375 | XPC_ACTIVITY_STATE_WAIT, 376 | XPC_ACTIVITY_STATE_RUN, 377 | XPC_ACTIVITY_STATE_DEFER, 378 | XPC_ACTIVITY_STATE_CONTINUE, 379 | XPC_ACTIVITY_STATE_DONE, 380 | }; 381 | typedef long xpc_activity_state_t; 382 | 383 | /*! 384 | * @function xpc_activity_get_state 385 | * 386 | * @abstract 387 | * Returns the current state of an activity. 388 | */ 389 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 390 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 391 | xpc_activity_state_t 392 | xpc_activity_get_state(xpc_activity_t activity); 393 | 394 | /*! 395 | * @function xpc_activity_set_state 396 | * 397 | * @abstract 398 | * Updates the current state of an activity. 399 | * 400 | * @return 401 | * Returns true if the state was successfully updated; otherwise, returns 402 | * false if the requested state transition is not valid. 403 | */ 404 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 405 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 406 | bool 407 | xpc_activity_set_state(xpc_activity_t activity, xpc_activity_state_t state); 408 | 409 | /*! 410 | * @function xpc_activity_should_defer 411 | * 412 | * @abstract 413 | * Test whether an activity should be deferred. 414 | * 415 | * @discussion 416 | * This function may be used to test whether the criteria of a long-running 417 | * activity are still satisfied. If not, the system indicates that the 418 | * application should defer the activity. The application may acknowledge the 419 | * deferral by calling xpc_activity_set_state() with XPC_ACTIVITY_STATE_DEFER. 420 | * Once deferred, the system will place the activity back into the WAIT state 421 | * and re-invoke the handler block at the earliest opportunity when the criteria 422 | * are once again satisfied. 423 | * 424 | * @return 425 | * Returns true if the activity should be deferred. 426 | */ 427 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 428 | XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL1 429 | bool 430 | xpc_activity_should_defer(xpc_activity_t activity); 431 | 432 | /*! 433 | * @function xpc_activity_unregister 434 | * 435 | * @abstract 436 | * Unregisters an activity found by its identifier. 437 | * 438 | * @discussion 439 | * A dynamically registered activity will be deleted in response to this call. 440 | * Statically registered activity (from a launchd property list) will be 441 | * deleted until the job is next loaded (e.g. at next boot). 442 | * 443 | * Unregistering an activity has no effect on any outstanding xpc_activity_t 444 | * objects or any currently executing xpc_activity_handler_t blocks; however, 445 | * no new handler block invocations will be made after it is unregistered. 446 | * 447 | * @param identifier 448 | * The identifier of the activity to unregister. 449 | */ 450 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 451 | XPC_EXPORT XPC_NONNULL1 452 | void 453 | xpc_activity_unregister(const char *identifier); 454 | 455 | __END_DECLS 456 | XPC_ASSUME_NONNULL_END 457 | 458 | #endif // __BLOCKS__ 459 | 460 | #endif // __XPC_ACTIVITY_H__ 461 | 462 | -------------------------------------------------------------------------------- /headers/xpc/availability.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_AVAILABILITY_H__ 2 | #define __XPC_AVAILABILITY_H__ 3 | 4 | #include 5 | 6 | // Certain parts of the project use all the project's headers but have to build 7 | // against newer OSX SDKs than ebuild uses -- liblaunch_host being the example. 8 | // So we need to define these. 9 | #ifndef __MAC_10_16 10 | #define __MAC_10_16 101600 11 | #endif // __MAC_10_16 12 | 13 | #ifndef __MAC_10_15 14 | #define __MAC_10_15 101500 15 | #define __AVAILABILITY_INTERNAL__MAC_10_15 \ 16 | __attribute__((availability(macosx, introduced=10.15))) 17 | #endif // __MAC_10_15 18 | 19 | #ifndef __MAC_10_14 20 | #define __MAC_10_14 101400 21 | #define __AVAILABILITY_INTERNAL__MAC_10_14 \ 22 | __attribute__((availability(macosx, introduced=10.14))) 23 | #endif // __MAC_10_14 24 | 25 | #ifndef __MAC_10_13 26 | #define __MAC_10_13 101300 27 | #define __AVAILABILITY_INTERNAL__MAC_10_13 \ 28 | __attribute__((availability(macosx, introduced=10.13))) 29 | #endif // __MAC_10_13 30 | 31 | #ifndef __MAC_10_12 32 | #define __MAC_10_12 101200 33 | #define __AVAILABILITY_INTERNAL__MAC_10_12 \ 34 | __attribute__((availability(macosx, introduced=10.12))) 35 | #endif // __MAC_10_12 36 | 37 | #ifndef __MAC_10_11 38 | #define __MAC_10_11 101100 39 | #define __AVAILABILITY_INTERNAL__MAC_10_11 \ 40 | __attribute__((availability(macosx, introduced=10.11))) 41 | #endif // __MAC_10_11 42 | 43 | #ifndef __MAC_12_0 44 | #define __MAC_12_0 120000 45 | #define __AVAILABILITY_INTERNAL__MAC_12_0 \ 46 | __attribute__((availability(macosx, introduced=12.0))) 47 | #endif // __MAC_12_0 48 | 49 | #ifndef __MAC_13_3 50 | #define __MAC_13_3 130300 51 | #endif // __MAC_13_3 52 | 53 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 54 | #define __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 55 | #endif // __AVAILABILITY_INTERNAL__MAC_10_2_DEP__MAC_10_11 56 | 57 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 58 | #define __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 59 | #endif // __AVAILABILITY_INTERNAL__MAC_10_3_DEP__MAC_10_11 60 | 61 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 62 | #define __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 63 | #endif // __AVAILABILITY_INTERNAL__MAC_10_4_DEP__MAC_10_11 64 | 65 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 66 | #define __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 67 | #endif // __AVAILABILITY_INTERNAL__MAC_10_5_DEP__MAC_10_11 68 | 69 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 70 | #define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 71 | #endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_11 72 | 73 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 74 | #define __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 75 | #endif // __AVAILABILITY_INTERNAL__MAC_10_7_DEP__MAC_10_11 76 | 77 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 78 | #define __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 79 | #endif // __AVAILABILITY_INTERNAL__MAC_10_8_DEP__MAC_10_11 80 | 81 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 82 | #define __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 83 | #endif // __AVAILABILITY_INTERNAL__MAC_10_9_DEP__MAC_10_11 84 | 85 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 86 | #define __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 87 | #endif // __AVAILABILITY_INTERNAL__MAC_10_10_DEP__MAC_10_11 88 | 89 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 90 | #define __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 91 | #endif // __AVAILABILITY_INTERNAL__MAC_10_11_DEP__MAC_10_11 92 | 93 | #ifndef __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 94 | #define __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 95 | #endif // __AVAILABILITY_INTERNAL__MAC_10_6_DEP__MAC_10_13 96 | 97 | #if __has_include() 98 | #include 99 | #else // __has_include() 100 | #ifndef IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 101 | #define IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 999999 102 | #endif // IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED 103 | #endif // __has_include() 104 | 105 | #ifndef __WATCHOS_UNAVAILABLE 106 | #define __WATCHOS_UNAVAILABLE 107 | #endif 108 | 109 | #ifndef __TVOS_UNAVAILABLE 110 | #define __TVOS_UNAVAILABLE 111 | #endif 112 | 113 | // simulator host-side bits build against SDKs not having __*_AVAILABLE() yet 114 | #ifndef __OSX_AVAILABLE 115 | #define __OSX_AVAILABLE(...) 116 | #endif 117 | 118 | #ifndef __IOS_AVAILABLE 119 | #define __IOS_AVAILABLE(...) 120 | #endif 121 | 122 | #ifndef __TVOS_AVAILABLE 123 | #define __TVOS_AVAILABLE(...) 124 | #endif 125 | 126 | #ifndef __WATCHOS_AVAILABLE 127 | #define __WATCHOS_AVAILABLE(...) 128 | #endif 129 | 130 | #ifndef __API_AVAILABLE 131 | #define __API_AVAILABLE(...) 132 | #endif 133 | 134 | #endif // __XPC_AVAILABILITY_H__ 135 | -------------------------------------------------------------------------------- /headers/xpc/base.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009-2011 Apple Inc. All rights reserved. 2 | 3 | #ifndef __XPC_BASE_H__ 4 | #define __XPC_BASE_H__ 5 | 6 | #include 7 | 8 | __BEGIN_DECLS 9 | 10 | #if !defined(__has_include) 11 | #define __has_include(x) 0 12 | #endif // !defined(__has_include) 13 | 14 | #if !defined(__has_attribute) 15 | #define __has_attribute(x) 0 16 | #endif // !defined(__has_attribute) 17 | 18 | #if !defined(__has_feature) 19 | #define __has_feature(x) 0 20 | #endif // !defined(__has_feature) 21 | 22 | #if !defined(__has_extension) 23 | #define __has_extension(x) 0 24 | #endif // !defined(__has_extension) 25 | 26 | #if __has_include() 27 | #include 28 | #else // __has_include() 29 | #include 30 | #endif // __has_include() 31 | 32 | #include 33 | 34 | #ifndef __XPC_INDIRECT__ 35 | #error "Please #include instead of this file directly." 36 | #endif // __XPC_INDIRECT__ 37 | 38 | #pragma mark Attribute Shims 39 | #ifdef __GNUC__ 40 | #define XPC_CONSTRUCTOR __attribute__((constructor)) 41 | #define XPC_NORETURN __attribute__((__noreturn__)) 42 | #define XPC_NOTHROW __attribute__((__nothrow__)) 43 | #define XPC_NONNULL1 __attribute__((__nonnull__(1))) 44 | #define XPC_NONNULL2 __attribute__((__nonnull__(2))) 45 | #define XPC_NONNULL3 __attribute__((__nonnull__(3))) 46 | #define XPC_NONNULL4 __attribute__((__nonnull__(4))) 47 | #define XPC_NONNULL5 __attribute__((__nonnull__(5))) 48 | #define XPC_NONNULL6 __attribute__((__nonnull__(6))) 49 | #define XPC_NONNULL7 __attribute__((__nonnull__(7))) 50 | #define XPC_NONNULL8 __attribute__((__nonnull__(8))) 51 | #define XPC_NONNULL9 __attribute__((__nonnull__(9))) 52 | #define XPC_NONNULL10 __attribute__((__nonnull__(10))) 53 | #define XPC_NONNULL11 __attribute__((__nonnull__(11))) 54 | #define XPC_NONNULL_ALL __attribute__((__nonnull__)) 55 | #define XPC_SENTINEL __attribute__((__sentinel__)) 56 | #define XPC_PURE __attribute__((__pure__)) 57 | #define XPC_WARN_RESULT __attribute__((__warn_unused_result__)) 58 | #define XPC_MALLOC __attribute__((__malloc__)) 59 | #define XPC_UNUSED __attribute__((__unused__)) 60 | #define XPC_USED __attribute__((__used__)) 61 | #define XPC_PACKED __attribute__((__packed__)) 62 | #define XPC_PRINTF(m, n) __attribute__((format(printf, m, n))) 63 | #define XPC_INLINE static __inline__ __attribute__((__always_inline__)) 64 | #define XPC_NOINLINE __attribute__((noinline)) 65 | #define XPC_NOIMPL __attribute__((unavailable)) 66 | 67 | #if __has_attribute(noescape) 68 | #define XPC_NOESCAPE __attribute__((__noescape__)) 69 | #else 70 | #define XPC_NOESCAPE 71 | #endif 72 | 73 | #if __has_extension(attribute_unavailable_with_message) 74 | #define XPC_UNAVAILABLE(m) __attribute__((unavailable(m))) 75 | #else // __has_extension(attribute_unavailable_with_message) 76 | #define XPC_UNAVAILABLE(m) XPC_NOIMPL 77 | #endif // __has_extension(attribute_unavailable_with_message) 78 | 79 | #define XPC_EXPORT extern __attribute__((visibility("default"))) 80 | #define XPC_NOEXPORT __attribute__((visibility("hidden"))) 81 | #define XPC_WEAKIMPORT extern __attribute__((weak_import)) 82 | #define XPC_DEBUGGER_EXCL XPC_NOEXPORT XPC_USED 83 | #define XPC_TRANSPARENT_UNION __attribute__((transparent_union)) 84 | #if __clang__ 85 | #define XPC_DEPRECATED(m) __attribute__((deprecated(m))) 86 | #else // __clang__ 87 | #define XPC_DEPRECATED(m) __attribute__((deprecated)) 88 | #endif // __clang 89 | #ifndef XPC_TESTEXPORT 90 | #define XPC_TESTEXPORT XPC_NOEXPORT 91 | #endif // XPC_TESTEXPORT 92 | 93 | #if defined(__XPC_TEST__) && __XPC_TEST__ 94 | #define XPC_TESTSTATIC 95 | #define XPC_TESTEXTERN extern 96 | #else // defined(__XPC_TEST__) && __XPC_TEST__ 97 | #define XPC_TESTSTATIC static 98 | #endif // defined(__XPC_TEST__) && __XPC_TEST__ 99 | 100 | #if __has_feature(objc_arc) 101 | #define XPC_GIVES_REFERENCE __strong 102 | #define XPC_UNRETAINED __unsafe_unretained 103 | #define XPC_BRIDGE(xo) ((__bridge void *)(xo)) 104 | #define XPC_BRIDGEREF_BEGIN(xo) ((__bridge_retained void *)(xo)) 105 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) ((__bridge void *)(xo)) 106 | #define XPC_BRIDGEREF_MIDDLE(xo) ((__bridge id)(xo)) 107 | #define XPC_BRIDGEREF_END(xo) ((__bridge_transfer id)(xo)) 108 | #else // __has_feature(objc_arc) 109 | #define XPC_GIVES_REFERENCE 110 | #define XPC_UNRETAINED 111 | #define XPC_BRIDGE(xo) (xo) 112 | #define XPC_BRIDGEREF_BEGIN(xo) (xo) 113 | #define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) (xo) 114 | #define XPC_BRIDGEREF_MIDDLE(xo) (xo) 115 | #define XPC_BRIDGEREF_END(xo) (xo) 116 | #endif // __has_feature(objc_arc) 117 | 118 | #define _xpc_unreachable() __builtin_unreachable() 119 | #else // __GNUC__ 120 | /*! @parseOnly */ 121 | #define XPC_CONSTRUCTOR 122 | /*! @parseOnly */ 123 | #define XPC_NORETURN 124 | /*! @parseOnly */ 125 | #define XPC_NOTHROW 126 | /*! @parseOnly */ 127 | #define XPC_NONNULL1 128 | /*! @parseOnly */ 129 | #define XPC_NONNULL2 130 | /*! @parseOnly */ 131 | #define XPC_NONNULL3 132 | /*! @parseOnly */ 133 | #define XPC_NONNULL4 134 | /*! @parseOnly */ 135 | #define XPC_NONNULL5 136 | /*! @parseOnly */ 137 | #define XPC_NONNULL6 138 | /*! @parseOnly */ 139 | #define XPC_NONNULL7 140 | /*! @parseOnly */ 141 | #define XPC_NONNULL8 142 | /*! @parseOnly */ 143 | #define XPC_NONNULL9 144 | /*! @parseOnly */ 145 | #define XPC_NONNULL10 146 | /*! @parseOnly */ 147 | #define XPC_NONNULL11 148 | /*! @parseOnly */ 149 | #define XPC_NONNULL(n) 150 | /*! @parseOnly */ 151 | #define XPC_NONNULL_ALL 152 | /*! @parseOnly */ 153 | #define XPC_SENTINEL 154 | /*! @parseOnly */ 155 | #define XPC_PURE 156 | /*! @parseOnly */ 157 | #define XPC_WARN_RESULT 158 | /*! @parseOnly */ 159 | #define XPC_MALLOC 160 | /*! @parseOnly */ 161 | #define XPC_UNUSED 162 | /*! @parseOnly */ 163 | #define XPC_PACKED 164 | /*! @parseOnly */ 165 | #define XPC_PRINTF(m, n) 166 | /*! @parseOnly */ 167 | #define XPC_INLINE static inline 168 | /*! @parseOnly */ 169 | #define XPC_NOINLINE 170 | /*! @parseOnly */ 171 | #define XPC_NOIMPL 172 | /*! @parseOnly */ 173 | #define XPC_EXPORT extern 174 | /*! @parseOnly */ 175 | #define XPC_WEAKIMPORT 176 | /*! @parseOnly */ 177 | #define XPC_DEPRECATED 178 | /*! @parseOnly */ 179 | #define XPC_UNAVAILABLE(m) 180 | /*! @parseOnly */ 181 | #define XPC_NOESCAPE 182 | #endif // __GNUC__ 183 | 184 | #if __has_feature(assume_nonnull) 185 | #define XPC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") 186 | #define XPC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") 187 | #else 188 | #define XPC_ASSUME_NONNULL_BEGIN 189 | #define XPC_ASSUME_NONNULL_END 190 | #endif 191 | 192 | #if __has_feature(nullability_on_arrays) 193 | #define XPC_NONNULL_ARRAY _Nonnull 194 | #else 195 | #define XPC_NONNULL_ARRAY 196 | #endif 197 | 198 | #if defined(__has_ptrcheck) && __has_ptrcheck 199 | #define XPC_PTR_ASSUMES_SINGLE __ptrcheck_abi_assume_single() 200 | #define XPC_SINGLE __single 201 | #define XPC_UNSAFE_INDEXABLE __unsafe_indexable 202 | #define XPC_CSTRING XPC_UNSAFE_INDEXABLE 203 | #define XPC_SIZEDBY(N) __sized_by(N) 204 | #define XPC_COUNTEDBY(N) __counted_by(N) 205 | #define XPC_UNSAFE_FORGE_SIZED_BY(_type, _ptr, _size) \ 206 | __unsafe_forge_bidi_indexable(_type, _ptr, _size) 207 | #define XPC_UNSAFE_FORGE_SINGLE(_type, _ptr) \ 208 | __unsafe_forge_single(_type, _ptr) 209 | #else // defined(__has_ptrcheck) ** __has_ptrcheck 210 | #define XPC_PTR_ASSUMES_SINGLE 211 | #define XPC_SINGLE 212 | #define XPC_UNSAFE_INDEXABLE 213 | #define XPC_CSTRING 214 | #define XPC_SIZEDBY(N) 215 | #define XPC_COUNTEDBY(N) 216 | #define XPC_UNSAFE_FORGE_SIZED_BY(_type, _ptr, _size) ((_type)(_ptr)) 217 | #define XPC_UNSAFE_FORGE_SINGLE(_type, _ptr) ((_type)(_ptr)) 218 | #endif // defined(__has_ptrcheck) ** __has_ptrcheck 219 | 220 | #ifdef OS_CLOSED_OPTIONS 221 | #define XPC_FLAGS_ENUM(_name, _type, ...) \ 222 | OS_CLOSED_OPTIONS(_name, _type, __VA_ARGS__) 223 | #else // OS_CLOSED_ENUM 224 | #define XPC_FLAGS_ENUM(_name, _type, ...) \ 225 | OS_ENUM(_name, _type, __VA_ARGS__) 226 | #endif // OS_CLOSED_ENUM 227 | 228 | #ifdef OS_CLOSED_ENUM 229 | #define XPC_ENUM(_name, _type, ...) \ 230 | OS_CLOSED_ENUM(_name, _type, __VA_ARGS__) 231 | #else // OS_CLOSED_ENUM 232 | #define XPC_ENUM(_name, _type, ...) \ 233 | OS_ENUM(_name, _type, __VA_ARGS__) 234 | #endif // OS_CLOSED_ENUM 235 | 236 | #if __has_attribute(swift_name) 237 | # define XPC_SWIFT_NAME(_name) __attribute__((swift_name(_name))) 238 | #else 239 | # define XPC_SWIFT_NAME(_name) // __has_attribute(swift_name) 240 | #endif 241 | 242 | __END_DECLS 243 | 244 | #endif // __XPC_BASE_H__ 245 | -------------------------------------------------------------------------------- /headers/xpc/connection.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_CONNECTION_H__ 2 | #define __XPC_CONNECTION_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC connections require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | /*! 18 | * @constant XPC_ERROR_CONNECTION_INTERRUPTED 19 | * Will be delivered to the connection's event handler if the remote service 20 | * exited. The connection is still live even in this case, and resending a 21 | * message will cause the service to be launched on-demand. This error serves 22 | * as a client's indication that it should resynchronize any state that it had 23 | * given the service. 24 | * 25 | * Any messages in the queue to be sent will be unwound and canceled when this 26 | * error occurs. In the case where a message waiting to be sent has a reply 27 | * handler, that handler will be invoked with this error. In the context of the 28 | * reply handler, this error indicates that a reply to the message will never 29 | * arrive. 30 | * 31 | * Messages that do not have reply handlers associated with them will be 32 | * silently disposed of. This error will only be given to peer connections. 33 | */ 34 | #define XPC_ERROR_CONNECTION_INTERRUPTED \ 35 | XPC_GLOBAL_OBJECT(_xpc_error_connection_interrupted) 36 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 37 | XPC_EXPORT 38 | const struct _xpc_dictionary_s _xpc_error_connection_interrupted; 39 | 40 | /*! 41 | * @constant XPC_ERROR_CONNECTION_INVALID 42 | * Will be delivered to the connection's event handler if the named service 43 | * provided to xpc_connection_create() could not be found in the XPC service 44 | * namespace. The connection is useless and should be disposed of. 45 | * 46 | * Any messages in the queue to be sent will be unwound and canceled when this 47 | * error occurs, similarly to the behavior when XPC_ERROR_CONNECTION_INTERRUPTED 48 | * occurs. The only difference is that the XPC_ERROR_CONNECTION_INVALID will be 49 | * given to outstanding reply handlers and the connection's event handler. 50 | * 51 | * This error may be given to any type of connection. 52 | */ 53 | #define XPC_ERROR_CONNECTION_INVALID \ 54 | XPC_GLOBAL_OBJECT(_xpc_error_connection_invalid) 55 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 56 | XPC_EXPORT 57 | const struct _xpc_dictionary_s _xpc_error_connection_invalid; 58 | 59 | /*! 60 | * @constant XPC_ERROR_TERMINATION_IMMINENT 61 | * On macOS, this error will be delivered to a peer connection's event handler 62 | * when the XPC runtime has determined that the program should exit and that 63 | * all outstanding transactions must be wound down, and no new transactions can 64 | * be opened. 65 | * 66 | * After this error has been delivered to the event handler, no more messages 67 | * will be received by the connection. The runtime will still attempt to deliver 68 | * outgoing messages, but this error should be treated as an indication that 69 | * the program will exit very soon, and any outstanding business over the 70 | * connection should be wrapped up as quickly as possible and the connection 71 | * canceled shortly thereafter. 72 | * 73 | * This error will only be delivered to peer connections received through a 74 | * listener or the xpc_main() event handler. 75 | */ 76 | #define XPC_ERROR_TERMINATION_IMMINENT \ 77 | XPC_GLOBAL_OBJECT(_xpc_error_termination_imminent) 78 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 79 | XPC_EXPORT 80 | const struct _xpc_dictionary_s _xpc_error_termination_imminent; 81 | 82 | /*! 83 | * @constant XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT 84 | * On macOS, this error will be delivered to a peer connection's event handler 85 | * when the XPC runtime has detected that a peer connection does not 86 | * satisfy the code signing requirement specified for the connection. 87 | * 88 | * See {@link xpc_connection_set_peer_code_signing_requirement} 89 | */ 90 | #define XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT \ 91 | XPC_GLOBAL_OBJECT(_xpc_error_peer_code_signing_requirement) 92 | __API_AVAILABLE(macos(12.0)) 93 | XPC_EXPORT 94 | const struct _xpc_dictionary_s _xpc_error_peer_code_signing_requirement; 95 | 96 | /*! 97 | * @constant XPC_CONNECTION_MACH_SERVICE_LISTENER 98 | * Passed to xpc_connection_create_mach_service(). This flag indicates that the 99 | * caller is the listener for the named service. This flag may only be passed 100 | * for services which are advertised in the process' launchd.plist(5). You may 101 | * not use this flag to dynamically add services to the Mach bootstrap 102 | * namespace. 103 | */ 104 | #define XPC_CONNECTION_MACH_SERVICE_LISTENER (1 << 0) 105 | 106 | /*! 107 | * @constant XPC_CONNECTION_MACH_SERVICE_PRIVILEGED 108 | * Passed to xpc_connection_create_mach_service(). This flag indicates that the 109 | * job advertising the service name in its launchd.plist(5) should be in the 110 | * privileged Mach bootstrap. This is typically accomplished by placing your 111 | * launchd.plist(5) in /Library/LaunchDaemons. If specified alongside the 112 | * XPC_CONNECTION_MACH_SERVICE_LISTENER flag, this flag is a no-op. 113 | */ 114 | #define XPC_CONNECTION_MACH_SERVICE_PRIVILEGED (1 << 1) 115 | 116 | /*! 117 | * @typedef xpc_finalizer_f 118 | * A function that is invoked when a connection is being torn down and its 119 | * context needs to be freed. The sole argument is the value that was given to 120 | * {@link xpc_connection_set_context} or NULL if no context has been set. It is 121 | * not safe to reference the connection from within this function. 122 | * 123 | * @param value 124 | * The context object that is to be disposed of. 125 | */ 126 | typedef void (*xpc_finalizer_t)(void * _Nullable value); 127 | 128 | /*! 129 | * @function xpc_connection_create 130 | * Creates a new connection object. 131 | * 132 | * @param name 133 | * If non-NULL, the name of the service with which to connect. The returned 134 | * connection will be a peer. 135 | * 136 | * If NULL, an anonymous listener connection will be created. You can embed the 137 | * ability to create new peer connections in an endpoint, which can be inserted 138 | * into a message and sent to another process . 139 | * 140 | * @param targetq 141 | * The GCD queue to which the event handler block will be submitted. This 142 | * parameter may be NULL, in which case the connection's target queue will be 143 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 144 | * The target queue may be changed later with a call to 145 | * xpc_connection_set_target_queue(). 146 | * 147 | * @result 148 | * A new connection object. The caller is responsible for disposing of the 149 | * returned object with {@link xpc_release} when it is no longer needed. 150 | * 151 | * @discussion 152 | * This method will succeed even if the named service does not exist. This is 153 | * because the XPC namespace is not queried for the service name until the 154 | * connection has been activated. See {@link xpc_connection_activate()}. 155 | * 156 | * XPC connections, like dispatch sources, are returned in an inactive state, so 157 | * you must call {@link xpc_connection_activate()} in order to begin receiving 158 | * events from the connection. Also like dispatch sources, connections must be 159 | * activated and not suspended in order to be safely released. It is 160 | * a programming error to release an inactive or suspended connection. 161 | */ 162 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 163 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT 164 | xpc_connection_t 165 | xpc_connection_create(const char * _Nullable name, 166 | dispatch_queue_t _Nullable targetq); 167 | 168 | /*! 169 | * @function xpc_connection_create_mach_service 170 | * Creates a new connection object representing a Mach service. 171 | * 172 | * @param name 173 | * The name of the remote service with which to connect. The service name must 174 | * exist in a Mach bootstrap that is accessible to the process and be advertised 175 | * in a launchd.plist. 176 | * 177 | * @param targetq 178 | * The GCD queue to which the event handler block will be submitted. This 179 | * parameter may be NULL, in which case the connection's target queue will be 180 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 181 | * The target queue may be changed later with a call to 182 | * xpc_connection_set_target_queue(). 183 | * 184 | * @param flags 185 | * Additional attributes with which to create the connection. 186 | * 187 | * @result 188 | * A new connection object. 189 | * 190 | * @discussion 191 | * If the XPC_CONNECTION_MACH_SERVICE_LISTENER flag is given to this method, 192 | * then the connection returned will be a listener connection. Otherwise, a peer 193 | * connection will be returned. See the documentation for 194 | * {@link xpc_connection_set_event_handler()} for the semantics of listener 195 | * connections versus peer connections. 196 | * 197 | * This method will succeed even if the named service does not exist. This is 198 | * because the Mach namespace is not queried for the service name until the 199 | * connection has been activated. See {@link xpc_connection_activate()}. 200 | */ 201 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 202 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 203 | xpc_connection_t 204 | xpc_connection_create_mach_service(const char *name, 205 | dispatch_queue_t _Nullable targetq, uint64_t flags); 206 | 207 | /*! 208 | * @function xpc_connection_create_from_endpoint 209 | * Creates a new connection from the given endpoint. 210 | * 211 | * @param endpoint 212 | * The endpoint from which to create the new connection. 213 | * 214 | * @result 215 | * A new peer connection to the listener represented by the given endpoint. 216 | * 217 | * The same responsibilities of setting an event handler and activating the 218 | * connection after calling xpc_connection_create() apply to the connection 219 | * returned by this API. Since the connection yielded by this API is not 220 | * associated with a name (and therefore is not rediscoverable), this connection 221 | * will receive XPC_ERROR_CONNECTION_INVALID if the listening side crashes, 222 | * exits or cancels the listener connection. 223 | */ 224 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 225 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL_ALL 226 | xpc_connection_t 227 | xpc_connection_create_from_endpoint(xpc_endpoint_t endpoint); 228 | 229 | /*! 230 | * @function xpc_connection_set_target_queue 231 | * Sets the target queue of the given connection. 232 | * 233 | * @param connection 234 | * The connection object which is to be manipulated. 235 | * 236 | * @param targetq 237 | * The GCD queue to which the event handler block will be submitted. This 238 | * parameter may be NULL, in which case the connection's target queue will be 239 | * libdispatch's default target queue, defined as DISPATCH_TARGET_QUEUE_DEFAULT. 240 | * 241 | * @discussion 242 | * Setting the target queue is asynchronous and non-preemptive and therefore 243 | * this method will not interrupt the execution of an already-running event 244 | * handler block. Setting the target queue may be likened to issuing a barrier 245 | * to the connection which does the actual work of changing the target queue. 246 | * 247 | * The XPC runtime guarantees this non-preemptiveness even for concurrent target 248 | * queues. If the target queue is a concurrent queue, then XPC still guarantees 249 | * that there will never be more than one invocation of the connection's event 250 | * handler block executing concurrently. If you wish to process events 251 | * concurrently, you can dispatch_async(3) to a concurrent queue from within 252 | * the event handler. 253 | * 254 | * IMPORTANT: When called from within the event handler block, 255 | * dispatch_get_current_queue(3) is NOT guaranteed to return a pointer to the 256 | * queue set with this method. 257 | * 258 | * Despite this seeming inconsistency, the XPC runtime guarantees that, when the 259 | * target queue is a serial queue, the event handler block will execute 260 | * synchronously with respect to other blocks submitted to that same queue. When 261 | * the target queue is a concurrent queue, the event handler block may run 262 | * concurrently with other blocks submitted to that queue, but it will never run 263 | * concurrently with other invocations of itself for the same connection, as 264 | * discussed previously. 265 | */ 266 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 267 | XPC_EXPORT XPC_NONNULL1 268 | void 269 | xpc_connection_set_target_queue(xpc_connection_t connection, 270 | dispatch_queue_t _Nullable targetq); 271 | 272 | /*! 273 | * @function xpc_connection_set_event_handler 274 | * Sets the event handler block for the connection. 275 | * 276 | * @param connection 277 | * The connection object which is to be manipulated. 278 | * 279 | * @param handler 280 | * The event handler block. 281 | * 282 | * @discussion 283 | * Setting the event handler is asynchronous and non-preemptive, and therefore 284 | * this method will not interrupt the execution of an already-running event 285 | * handler block. If the event handler is executing at the time of this call, it 286 | * will finish, and then the connection's event handler will be changed before 287 | * the next invocation of the event handler. The XPC runtime guarantees this 288 | * non-preemptiveness even for concurrent target queues. 289 | * 290 | * Connection event handlers are non-reentrant, so it is safe to call 291 | * xpc_connection_set_event_handler() from within the event handler block. 292 | * 293 | * The event handler's execution should be treated as a barrier to all 294 | * connection activity. When it is executing, the connection will not attempt to 295 | * send or receive messages, including reply messages. Thus, it is not safe to 296 | * call xpc_connection_send_message_with_reply_sync() on the connection from 297 | * within the event handler. 298 | * 299 | * You do not hold a reference on the object received as the event handler's 300 | * only argument. Regardless of the type of object received, it is safe to call 301 | * xpc_retain() on the object to obtain a reference to it. 302 | * 303 | * A connection may receive different events depending upon whether it is a 304 | * listener or not. Any connection may receive an error in its event handler. 305 | * But while normal connections may receive messages in addition to errors, 306 | * listener connections will receive connections and and not messages. 307 | * 308 | * Connections received by listeners are equivalent to those returned by 309 | * xpc_connection_create() with a non-NULL name argument and a NULL targetq 310 | * argument with the exception that you do not hold a reference on them. 311 | * You must set an event handler and activate the connection. If you do not wish 312 | * to accept the connection, you may simply call xpc_connection_cancel() on it 313 | * and return. The runtime will dispose of it for you. 314 | * 315 | * If there is an error in the connection, this handler will be invoked with the 316 | * error dictionary as its argument. This dictionary will be one of the well- 317 | * known XPC_ERROR_* dictionaries. 318 | * 319 | * Regardless of the type of event, ownership of the event object is NOT 320 | * implicitly transferred. Thus, the object will be released and deallocated at 321 | * some point in the future after the event handler returns. If you wish the 322 | * event's lifetime to persist, you must retain it with xpc_retain(). 323 | * 324 | * Connections received through the event handler will be released and 325 | * deallocated after the connection has gone invalid and delivered that event to 326 | * its event handler. 327 | */ 328 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 329 | XPC_EXPORT XPC_NONNULL_ALL 330 | void 331 | xpc_connection_set_event_handler(xpc_connection_t connection, 332 | xpc_handler_t handler); 333 | 334 | /*! 335 | * @function xpc_connection_activate 336 | * Activates the connection. Connections start in an inactive state, so you must 337 | * call xpc_connection_activate() on a connection before it will send or receive 338 | * any messages. 339 | * 340 | * @param connection 341 | * The connection object which is to be manipulated. 342 | * 343 | * @discussion 344 | * Calling xpc_connection_activate() on an active connection has no effect. 345 | * Releasing the last reference on an inactive connection that was created with 346 | * an xpc_connection_create*() call is undefined. 347 | * 348 | * For backward compatibility reasons, xpc_connection_resume() on an inactive 349 | * and not otherwise suspended xpc connection has the same effect as calling 350 | * xpc_connection_activate(). For new code, using xpc_connection_activate() 351 | * is preferred. 352 | */ 353 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 354 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) 355 | XPC_EXPORT XPC_NONNULL_ALL 356 | void 357 | xpc_connection_activate(xpc_connection_t connection); 358 | 359 | /*! 360 | * @function xpc_connection_suspend 361 | * Suspends the connection so that the event handler block will not fire and 362 | * that the connection will not attempt to send any messages it has in its 363 | * queue. All calls to xpc_connection_suspend() must be balanced with calls to 364 | * xpc_connection_resume() before releasing the last reference to the 365 | * connection. 366 | * 367 | * @param connection 368 | * The connection object which is to be manipulated. 369 | * 370 | * @discussion 371 | * Suspension is asynchronous and non-preemptive, and therefore this method will 372 | * not interrupt the execution of an already-running event handler block. If 373 | * the event handler is executing at the time of this call, it will finish, and 374 | * then the connection will be suspended before the next scheduled invocation 375 | * of the event handler. The XPC runtime guarantees this non-preemptiveness even 376 | * for concurrent target queues. 377 | * 378 | * Connection event handlers are non-reentrant, so it is safe to call 379 | * xpc_connection_suspend() from within the event handler block. 380 | */ 381 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 382 | XPC_EXPORT XPC_NONNULL_ALL 383 | void 384 | xpc_connection_suspend(xpc_connection_t connection); 385 | 386 | /*! 387 | * @function xpc_connection_resume 388 | * Resumes the connection. 389 | * 390 | * @param connection 391 | * The connection object which is to be manipulated. 392 | * 393 | * @discussion 394 | * In order for a connection to become live, every call to 395 | * xpc_connection_suspend() must be balanced with a call to 396 | * xpc_connection_resume(). 397 | * 398 | * For backward compatibility reasons, xpc_connection_resume() on an inactive 399 | * and not otherwise suspended xpc connection has the same effect as calling 400 | * xpc_connection_activate(). For new code, using xpc_connection_activate() 401 | * is preferred. 402 | * 403 | * Calling xpc_connection_resume() more times than xpc_connection_suspend() 404 | * has been called is otherwise considered an error. 405 | */ 406 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 407 | XPC_EXPORT XPC_NONNULL_ALL 408 | void 409 | xpc_connection_resume(xpc_connection_t connection); 410 | 411 | /*! 412 | * @function xpc_connection_send_message 413 | * Sends a message over the connection to the destination service. 414 | * 415 | * @param connection 416 | * The connection over which the message shall be sent. 417 | * 418 | * @param message 419 | * The message to send. This must be a dictionary object. This dictionary is 420 | * logically copied by the connection, so it is safe to modify the dictionary 421 | * after this call. 422 | * 423 | * @discussion 424 | * Messages are delivered in FIFO order. This API is safe to call from multiple 425 | * GCD queues. There is no indication that a message was delivered successfully. 426 | * This is because even once the message has been successfully enqueued on the 427 | * remote end, there are no guarantees about when the runtime will dequeue the 428 | * message and invoke the other connection's event handler block. 429 | * 430 | * If this API is used to send a message that is in reply to another message, 431 | * there is no guarantee of ordering between the invocations of the connection's 432 | * event handler and the reply handler for that message, even if they are 433 | * targeted to the same queue. 434 | * 435 | * After extensive study, we have found that clients who are interested in 436 | * the state of the message on the server end are typically holding open 437 | * transactions related to that message. And the only reliable way to track the 438 | * lifetime of that transaction is at the protocol layer. So the server should 439 | * send a reply message, which upon receiving, will cause the client to close 440 | * its transaction. 441 | */ 442 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 443 | XPC_EXPORT XPC_NONNULL_ALL 444 | void 445 | xpc_connection_send_message(xpc_connection_t connection, xpc_object_t message); 446 | 447 | /*! 448 | * @function xpc_connection_send_barrier 449 | * Issues a barrier against the connection's message-send activity. 450 | * 451 | * @param connection 452 | * The connection against which the barrier is to be issued. 453 | * 454 | * @param barrier 455 | * The barrier block to issue. This barrier prevents concurrent message-send 456 | * activity on the connection. No messages will be sent while the barrier block 457 | * is executing. 458 | * 459 | * @discussion 460 | * XPC guarantees that, even if the connection's target queue is a concurrent 461 | * queue, there are no other messages being sent concurrently while the barrier 462 | * block is executing. XPC does not guarantee that the receipt of messages 463 | * (either through the connection's event handler or through reply handlers) 464 | * will be suspended while the barrier is executing. 465 | * 466 | * A barrier is issued relative to the message-send queue. Thus, if you call 467 | * xpc_connection_send_message() five times and then call 468 | * xpc_connection_send_barrier(), the barrier will be invoked after the fifth 469 | * message has been sent and its memory disposed of. You may safely cancel a 470 | * connection from within a barrier block. 471 | * 472 | * If a barrier is issued after sending a message which expects a reply, the 473 | * behavior is the same as described above. The receipt of a reply message will 474 | * not influence when the barrier runs. 475 | * 476 | * A barrier block can be useful for throttling resource consumption on the 477 | * connected side of a connection. For example, if your connection sends many 478 | * large messages, you can use a barrier to limit the number of messages that 479 | * are inflight at any given time. This can be particularly useful for messages 480 | * that contain kernel resources (like file descriptors) which have a system- 481 | * wide limit. 482 | * 483 | * If a barrier is issued on a canceled connection, it will be invoked 484 | * immediately. If a connection has been canceled and still has outstanding 485 | * barriers, those barriers will be invoked as part of the connection's 486 | * unwinding process. 487 | * 488 | * It is important to note that a barrier block's execution order is not 489 | * guaranteed with respect to other blocks that have been scheduled on the 490 | * target queue of the connection. Or said differently, 491 | * xpc_connection_send_barrier(3) is not equivalent to dispatch_async(3). 492 | */ 493 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 494 | XPC_EXPORT XPC_NONNULL_ALL 495 | void 496 | xpc_connection_send_barrier(xpc_connection_t connection, 497 | dispatch_block_t barrier); 498 | 499 | /*! 500 | * @function xpc_connection_send_message_with_reply 501 | * Sends a message over the connection to the destination service and associates 502 | * a handler to be invoked when the remote service sends a reply message. 503 | * 504 | * @param connection 505 | * The connection over which the message shall be sent. 506 | * 507 | * @param message 508 | * The message to send. This must be a dictionary object. 509 | * 510 | * @param replyq 511 | * The GCD queue to which the reply handler will be submitted. This may be a 512 | * concurrent queue. 513 | * 514 | * @param handler 515 | * The handler block to invoke when a reply to the message is received from 516 | * the connection. If the remote service exits prematurely before the reply was 517 | * received, the XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. 518 | * If the connection went invalid before the message could be sent, the 519 | * XPC_ERROR_CONNECTION_INVALID error will be returned. 520 | * 521 | * @discussion 522 | * If the given GCD queue is a concurrent queue, XPC cannot guarantee that there 523 | * will not be multiple reply handlers being invoked concurrently. XPC does not 524 | * guarantee any ordering for the invocation of reply handlers. So if multiple 525 | * messages are waiting for replies and the connection goes invalid, there is no 526 | * guarantee that the reply handlers will be invoked in FIFO order. Similarly, 527 | * XPC does not guarantee that reply handlers will not run concurrently with 528 | * the connection's event handler in the case that the reply queue and the 529 | * connection's target queue are the same concurrent queue. 530 | */ 531 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 532 | XPC_EXPORT XPC_NONNULL1 XPC_NONNULL2 XPC_NONNULL4 533 | void 534 | xpc_connection_send_message_with_reply(xpc_connection_t connection, 535 | xpc_object_t message, dispatch_queue_t _Nullable replyq, 536 | xpc_handler_t handler); 537 | 538 | /*! 539 | * @function xpc_connection_send_message_with_reply_sync 540 | * Sends a message over the connection and blocks the caller until a reply is 541 | * received. 542 | * 543 | * @param connection 544 | * The connection over which the message shall be sent. 545 | * 546 | * @param message 547 | * The message to send. This must be a dictionary object. 548 | * 549 | * @result 550 | * The message that the remote service sent in reply to the original message. 551 | * If the remote service exits prematurely before the reply was received, the 552 | * XPC_ERROR_CONNECTION_INTERRUPTED error will be returned. If the connection 553 | * went invalid before the message could be sent, the 554 | * XPC_ERROR_CONNECTION_INVALID error will be returned. 555 | * 556 | * You are responsible for releasing the returned object. 557 | * 558 | * @discussion 559 | * This API supports priority inversion avoidance, and should be used instead of 560 | * combining xpc_connection_send_message_with_reply() with a semaphore. 561 | * 562 | * Invoking this API from a queue that is a part of the target queue hierarchy 563 | * results in deadlocks under certain conditions. 564 | * 565 | * Be judicious about your use of this API. It can block indefinitely, so if you 566 | * are using it to implement an API that can be called from the main thread, you 567 | * may wish to consider allowing the API to take a queue and callback block so 568 | * that results may be delivered asynchronously if possible. 569 | */ 570 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 571 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT XPC_RETURNS_RETAINED 572 | xpc_object_t 573 | xpc_connection_send_message_with_reply_sync(xpc_connection_t connection, 574 | xpc_object_t message); 575 | 576 | /*! 577 | * @function xpc_connection_cancel 578 | * Cancels the connection and ensures that its event handler will not fire 579 | * again. After this call, any messages that have not yet been sent will be 580 | * discarded, and the connection will be unwound. If there are messages that are 581 | * awaiting replies, they will have their reply handlers invoked with the 582 | * XPC_ERROR_CONNECTION_INVALID error. 583 | * 584 | * @param connection 585 | * The connection object which is to be manipulated. 586 | * 587 | * @discussion 588 | * Cancellation is asynchronous and non-preemptive and therefore this method 589 | * will not interrupt the execution of an already-running event handler block. 590 | * If the event handler is executing at the time of this call, it will finish, 591 | * and then the connection will be canceled, causing a final invocation of the 592 | * event handler to be scheduled with the XPC_ERROR_CONNECTION_INVALID error. 593 | * After that invocation, there will be no further invocations of the event 594 | * handler. 595 | * 596 | * The XPC runtime guarantees this non-preemptiveness even for concurrent target 597 | * queues. 598 | */ 599 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 600 | XPC_EXPORT XPC_NONNULL_ALL 601 | void 602 | xpc_connection_cancel(xpc_connection_t connection); 603 | 604 | /*! 605 | * @function xpc_connection_get_name 606 | * Returns the name of the service with which the connections was created. 607 | * 608 | * @param connection 609 | * The connection object which is to be examined. 610 | * 611 | * @result 612 | * The name of the remote service. If you obtained the connection through an 613 | * invocation of another connection's event handler, NULL is returned. 614 | */ 615 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 616 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 617 | const char * _Nullable 618 | xpc_connection_get_name(xpc_connection_t connection); 619 | 620 | /*! 621 | * @function xpc_connection_get_euid 622 | * Returns the EUID of the remote peer. 623 | * 624 | * @param connection 625 | * The connection object which is to be examined. 626 | * 627 | * @result 628 | * The EUID of the remote peer at the time the connection was made. 629 | */ 630 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 631 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 632 | uid_t 633 | xpc_connection_get_euid(xpc_connection_t connection); 634 | 635 | /*! 636 | * @function xpc_connection_get_egid 637 | * Returns the EGID of the remote peer. 638 | * 639 | * @param connection 640 | * The connection object which is to be examined. 641 | * 642 | * @result 643 | * The EGID of the remote peer at the time the connection was made. 644 | */ 645 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 646 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 647 | gid_t 648 | xpc_connection_get_egid(xpc_connection_t connection); 649 | 650 | /*! 651 | * @function xpc_connection_get_pid 652 | * Returns the PID of the remote peer. 653 | * 654 | * @param connection 655 | * The connection object which is to be examined. 656 | * 657 | * @result 658 | * The PID of the remote peer. 659 | * 660 | * @discussion 661 | * A given PID is not guaranteed to be unique across an entire boot cycle. 662 | * Great care should be taken when dealing with this information, as it can go 663 | * stale after the connection is established. OS X recycles PIDs, and therefore 664 | * another process could spawn and claim the PID before a message is actually 665 | * received from the connection. 666 | * 667 | * XPC will deliver an error to your event handler if the remote process goes 668 | * away, but there are no guarantees as to the timing of this notification's 669 | * delivery either at the kernel layer or at the XPC layer. 670 | */ 671 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 672 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 673 | pid_t 674 | xpc_connection_get_pid(xpc_connection_t connection); 675 | 676 | /*! 677 | * @function xpc_connection_get_asid 678 | * Returns the audit session identifier of the remote peer. 679 | * 680 | * @param connection 681 | * The connection object which is to be examined. 682 | * 683 | * @result 684 | * The audit session ID of the remote peer at the time the connection was made. 685 | */ 686 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 687 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 688 | au_asid_t 689 | xpc_connection_get_asid(xpc_connection_t connection); 690 | 691 | /*! 692 | * @function xpc_connection_set_context 693 | * Sets context on an connection. 694 | * 695 | * @param connection 696 | * The connection which is to be manipulated. 697 | * 698 | * @param context 699 | * The context to associate with the connection. 700 | * 701 | * @discussion 702 | * If you must manage the memory of the context object, you must set a finalizer 703 | * to dispose of it. If this method is called on a connection which already has 704 | * context associated with it, the finalizer will NOT be invoked. The finalizer 705 | * is only invoked when the connection is being deallocated. 706 | * 707 | * It is recommended that, instead of changing the actual context pointer 708 | * associated with the object, you instead change the state of the context 709 | * object itself. 710 | */ 711 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 712 | XPC_EXPORT XPC_NONNULL1 713 | void 714 | xpc_connection_set_context(xpc_connection_t connection, 715 | void * _Nullable context); 716 | 717 | /*! 718 | * @function xpc_connection_get_context 719 | * Returns the context associated with the connection. 720 | * 721 | * @param connection 722 | * The connection which is to be examined. 723 | * 724 | * @result 725 | * The context associated with the connection. NULL if there has been no context 726 | * associated with the object. 727 | */ 728 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 729 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 730 | void * _Nullable 731 | xpc_connection_get_context(xpc_connection_t connection); 732 | 733 | /*! 734 | * @function xpc_connection_set_finalizer_f 735 | * Sets the finalizer for the given connection. 736 | * 737 | * @param connection 738 | * The connection on which to set the finalizer. 739 | * 740 | * @param finalizer 741 | * The function that will be invoked when the connection's retain count has 742 | * dropped to zero and is being torn down. 743 | * 744 | * @discussion 745 | * This method disposes of the context value associated with a connection, as 746 | * set by {@link xpc_connection_set_context}. 747 | * 748 | * For many uses of context objects, this API allows for a convenient shorthand 749 | * for freeing them. For example, for a context object allocated with malloc(3): 750 | * 751 | * xpc_connection_set_finalizer_f(object, free); 752 | */ 753 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 754 | XPC_EXPORT XPC_NONNULL1 755 | void 756 | xpc_connection_set_finalizer_f(xpc_connection_t connection, 757 | xpc_finalizer_t _Nullable finalizer); 758 | 759 | /*! 760 | * @function xpc_connection_set_peer_code_signing_requirement 761 | * Requires that the connection peer satisfies a code signing requirement. 762 | * 763 | * @param connection 764 | * The connection object which is to be modified. 765 | * 766 | * @param requirement 767 | * The code signing requirement to be satisfied by the peer 768 | * It is safe to deallocate the requirement string after calling `xpc_connection_set_peer_code_signing_requirement` 769 | * 770 | * @result 771 | * 0 on success, non-zero on error 772 | * 773 | * @discussion 774 | * This function will return an error promptly if the code signing requirement string is invalid. 775 | * 776 | * It is a programming error to call `xpc_connection_set_peer_code_signing_requirement` more than once per connection. 777 | * 778 | * All messages received on this connection will be checked to ensure they come from a peer who satisfies 779 | * the code signing requirement. For a listener connection, requests that do not satisfy the requirement 780 | * are dropped. When a reply is expected on the connection and the peer does not satisfy the requirement 781 | * XPC_ERROR_PEER_CODE_SIGNING_REQUIREMENT will be delivered instead of the reply. 782 | * 783 | * This API is not supported on embedded platforms and will return ENOTSUP. 784 | * 785 | * @see https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html 786 | */ 787 | __API_AVAILABLE(macos(12.0)) 788 | XPC_EXPORT XPC_NONNULL_ALL XPC_WARN_RESULT 789 | int 790 | xpc_connection_set_peer_code_signing_requirement(xpc_connection_t connection, const char *requirement); 791 | 792 | 793 | __END_DECLS 794 | XPC_ASSUME_NONNULL_END 795 | 796 | #endif // __XPC_CONNECTION_H__ 797 | -------------------------------------------------------------------------------- /headers/xpc/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_DEBUG_H__ 2 | #define __XPC_DEBUG_H__ 3 | 4 | /*! 5 | * @function xpc_debugger_api_misuse_info 6 | * Returns a pointer to a string describing the reason XPC aborted the calling 7 | * process. On OS X, this will be the same string present in the "Application 8 | * Specific Information" section of the crash report. 9 | * 10 | * @result 11 | * A pointer to the human-readable string describing the reason the caller was 12 | * aborted. If XPC was not responsible for the program's termination, NULL will 13 | * be returned. 14 | * 15 | * @discussion 16 | * This function is only callable from within a debugger. It is not meant to be 17 | * called by the program directly. 18 | */ 19 | XPC_DEBUGGER_EXCL 20 | const char * 21 | xpc_debugger_api_misuse_info(void); 22 | 23 | #endif // __XPC_DEBUG_H__ 24 | -------------------------------------------------------------------------------- /headers/xpc/endpoint.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_ENDPOINT_H__ 2 | #define __XPC_ENDPOINT_H__ 3 | 4 | /*! 5 | * @function xpc_endpoint_create 6 | * Creates a new endpoint from a connection that is suitable for embedding into 7 | * messages. 8 | * 9 | * @param connection 10 | * Only connections obtained through calls to xpc_connection_create*() may be 11 | * given to this API. Passing any other type of connection is not supported and 12 | * will result in undefined behavior. 13 | * 14 | * @result 15 | * A new endpoint object. 16 | */ 17 | __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0) 18 | XPC_EXPORT XPC_MALLOC XPC_RETURNS_RETAINED XPC_WARN_RESULT XPC_NONNULL1 19 | xpc_endpoint_t _Nonnull 20 | xpc_endpoint_create(xpc_connection_t _Nonnull connection); 21 | 22 | #endif // __XPC_ENDPOINT_H__ 23 | -------------------------------------------------------------------------------- /headers/xpc/module.modulemap: -------------------------------------------------------------------------------- 1 | module XPC [system] [extern_c] { 2 | header "xpc.h" 3 | header "availability.h" 4 | header "base.h" 5 | header "activity.h" 6 | header "connection.h" 7 | header "debug.h" 8 | header "endpoint.h" 9 | export * 10 | } 11 | -------------------------------------------------------------------------------- /headers/xpc/rich_error.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_RICH_ERROR_H__ 2 | #define __XPC_RICH_ERROR_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC Rich Errors require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | #pragma mark Properties 18 | /*! 19 | * @function xpc_rich_error_copy_description 20 | * Copy the string description of an error. 21 | * 22 | * @param error 23 | * The error to be examined. 24 | * 25 | * @result 26 | * The underlying C string for the provided error. This string should be 27 | * disposed of with free(3) when done. 28 | * 29 | * This will return NULL if a string description could not be generated. 30 | */ 31 | XPC_EXPORT XPC_WARN_RESULT 32 | char * _Nullable 33 | xpc_rich_error_copy_description(xpc_rich_error_t error); 34 | 35 | /*! 36 | * @function xpc_rich_error_can_retry 37 | * Whether the operation the error originated from can be retried. 38 | * 39 | * @param error 40 | * The error to be inspected. 41 | * 42 | * @result 43 | * Whether the operation the error originated from can be retried. 44 | */ 45 | XPC_EXPORT XPC_WARN_RESULT 46 | bool 47 | xpc_rich_error_can_retry(xpc_rich_error_t error); 48 | 49 | __END_DECLS 50 | XPC_ASSUME_NONNULL_END 51 | 52 | #endif // __XPC_RICH_ERROR_H__ 53 | -------------------------------------------------------------------------------- /headers/xpc/session.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_SESSION_H__ 2 | #define __XPC_SESSION_H__ 3 | 4 | #ifndef __XPC_INDIRECT__ 5 | #error "Please #include instead of this file directly." 6 | // For HeaderDoc. 7 | #include 8 | #endif // __XPC_INDIRECT__ 9 | 10 | #ifndef __BLOCKS__ 11 | #error "XPC Session require Blocks support." 12 | #endif // __BLOCKS__ 13 | 14 | XPC_ASSUME_NONNULL_BEGIN 15 | __BEGIN_DECLS 16 | 17 | #pragma mark Constants 18 | /*! 19 | * @typedef xpc_session_create_flags_t 20 | * Constants representing different options available when creating an XPC 21 | * Session. 22 | * 23 | * @const XPC_SESSION_CREATE_INACTIVE 24 | * Indicates that the session should not be activated during its creation. The 25 | * returned session must be manually activated using 26 | * {@link xpc_session_activate} before it can be used. 27 | * 28 | * @const XPC_SESSION_CREATE_MACH_PRIVILEGED 29 | * Passed to {@link xpc_session_create_mach_service} to indicate that the job 30 | * advertising the service name in its launchd.plist(5) should be in the 31 | * privileged Mach bootstrap. This is typically accomplished by placing your 32 | * launchd.plist(5) in /Library/LaunchDaemons. 33 | */ 34 | XPC_FLAGS_ENUM(xpc_session_create_flags, uint64_t, 35 | XPC_SESSION_CREATE_NONE XPC_SWIFT_NAME("none") = 0, 36 | XPC_SESSION_CREATE_INACTIVE XPC_SWIFT_NAME("inactive") = (1 << 0), 37 | XPC_SESSION_CREATE_MACH_PRIVILEGED XPC_SWIFT_NAME("privileged") = (1 << 1) 38 | ); 39 | 40 | #pragma mark Handlers 41 | typedef void (^xpc_session_cancel_handler_t)(xpc_rich_error_t error); 42 | typedef void (^xpc_session_incoming_message_handler_t)(xpc_object_t message); 43 | typedef void (^xpc_session_reply_handler_t)(xpc_object_t _Nullable reply, 44 | xpc_rich_error_t _Nullable error); 45 | 46 | #pragma mark Helpers 47 | /*! 48 | * @function xpc_session_copy_description 49 | * Copy the string description of the session. 50 | * 51 | * @param session 52 | * The session to be examined. 53 | * 54 | * @result 55 | * The underlying C string description for the provided session. This string 56 | * should be disposed of with free(3) when done. This will return NULL if a 57 | * string description could not be generated. 58 | */ 59 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 60 | XPC_EXPORT XPC_WARN_RESULT 61 | char * _Nullable 62 | xpc_session_copy_description(xpc_session_t session); 63 | 64 | #pragma mark Client Session Creation 65 | /*! 66 | * @function xpc_session_create_xpc_service 67 | * Creates a new session object representing a connection to the named service. 68 | * 69 | * @param name 70 | * The name of the service to create a session with. 71 | * 72 | * @param target_queue 73 | * The GCD queue onto which session events will be submitted. This may be a 74 | * concurrent queue. This parameter may be NULL, in which case the target queue 75 | * will be libdispatch's default target queue, defined as 76 | * DISPATCH_TARGET_QUEUE_DEFAULT. 77 | * 78 | * @param flags 79 | * Additional attributes which which to create the session. 80 | * 81 | * @param error_out 82 | * An out-parameter that, if set and in the event of an error, will point to an 83 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 84 | * 85 | * @result 86 | * On success this returns a new session object. The returned session is 87 | * activated by default and can be used to send messages. The caller is 88 | * responsible for disposing of the returned object with {@link xpc_release} 89 | * when it is no longer needed. On failure this will return NULL and if set, 90 | * error_out will be set to an error describing the failure. 91 | * 92 | * @discussion 93 | * This will fail if the specified XPC service is either not found or is 94 | * unavailable. 95 | */ 96 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 97 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 98 | xpc_session_t _Nullable 99 | xpc_session_create_xpc_service(const char *name, 100 | dispatch_queue_t _Nullable target_queue, 101 | xpc_session_create_flags_t flags, 102 | xpc_rich_error_t _Nullable * _Nullable error_out); 103 | 104 | /*! 105 | * @function xpc_session_create_mach_service 106 | * Creates a session with the service defined by the provided Mach service name. 107 | * 108 | * @param mach_service 109 | * The Mach service to create a session with. The service name must exist in the 110 | * Mach bootstrap that is accessible to the process and be advertised in a 111 | * launchd.plist. 112 | * 113 | * @param target_queue 114 | * The GCD queue onto which session events will be submitted. This may be a 115 | * concurrent queue. This parameter may be NULL, in which case the target queue 116 | * will be libdispatch's default target queue, defined as 117 | * DISPATCH_TARGET_QUEUE_DEFAULT. 118 | * 119 | * @param flags 120 | * Additional attributes which which to create the session. 121 | * 122 | * @param error_out 123 | * An out-parameter that, if set and in the event of an error, will point to an 124 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 125 | * 126 | * @param cancel_handler 127 | * The cancel handler block that will be executed when this session is canceled. 128 | * 129 | * @result 130 | * On success this returns a new session object. The returned session is 131 | * activated by default and can be used to send messages. The caller is 132 | * responsible for disposing of the returned object with {@link xpc_release} 133 | * when it is no longer needed. On failure this will return NULL and if set, 134 | * error_out will be set to an error describing the failure. 135 | * 136 | * @discussion 137 | * This will fail if the specified Mach service is either not found in the 138 | * bootstrap or is otherwise unavailable. 139 | * 140 | */ 141 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 142 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 143 | xpc_session_t _Nullable 144 | xpc_session_create_mach_service(const char *mach_service, 145 | dispatch_queue_t _Nullable target_queue, 146 | xpc_session_create_flags_t flags, 147 | xpc_rich_error_t _Nullable * _Nullable error_out); 148 | 149 | #pragma mark Session Configuration 150 | /*! 151 | * @function xpc_session_set_incoming_message_handler 152 | * Set an incoming message handler for a session. 153 | * 154 | * @param session 155 | * The session to set the handler for. 156 | * 157 | * @param handler 158 | * The handler block to be called when a message originated by the peer is 159 | * received through the provided session. 160 | * 161 | * @discussion 162 | * This can only be called on an inactive session. Calling this on a session 163 | * with an existing event handler will replace it. 164 | */ 165 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 166 | XPC_EXPORT 167 | void 168 | xpc_session_set_incoming_message_handler(xpc_session_t session, 169 | xpc_session_incoming_message_handler_t handler); 170 | 171 | /*! 172 | * @function xpc_session_set_cancel_handler 173 | * Set the cancel handler for a session. 174 | * 175 | * @param session 176 | * The session to set the cancel handler for. 177 | * 178 | * @param cancel_handler 179 | * The cancel handler block that will be executed when this session is canceled. 180 | * 181 | * @discussion 182 | * This can only be called on an inactive session. Calling this on a session 183 | * with an existing cancel handler will replace the existing cancel handler with 184 | * the one provided. 185 | */ 186 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 187 | XPC_EXPORT 188 | void 189 | xpc_session_set_cancel_handler(xpc_session_t session, 190 | xpc_session_cancel_handler_t cancel_handler); 191 | 192 | #pragma mark Lifecycle 193 | /*! 194 | * @function xpc_session_activate 195 | * Activates a session. 196 | * 197 | * @param session 198 | * The session object to activate. 199 | * 200 | * @param error_out 201 | * An out-parameter that, if set and in the event of an error, will point to an 202 | * {@link xpc_rich_error_t} describing the details of any errors that occurred. 203 | * 204 | * @result 205 | * Returns whether session activation succeeded. 206 | * 207 | * @discussion 208 | * xpc_session_activate must not be called on a session that has been already 209 | * activated. Releasing the last reference on an inactive session that was 210 | * created with an xpc_session_create*() is undefined. 211 | */ 212 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 213 | XPC_EXPORT 214 | bool 215 | xpc_session_activate(xpc_session_t session, 216 | xpc_rich_error_t _Nullable * _Nullable error_out); 217 | 218 | /*! 219 | * @function xpc_session_cancel 220 | * Cancels the session. After this call, any messages that have not yet been 221 | * sent will be discarded, and the connection will be unwound. If there are 222 | * messages that are awaiting replies, they will have their reply handlers 223 | * invoked with an appropriate {@link xpc_rich_error_t}. 224 | * 225 | * @param session 226 | * The session object to cancel. 227 | * 228 | * @discussion 229 | * Session must have been activated to be canceled. Cancellation is asynchronous 230 | * and non-preemptive. 231 | */ 232 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 233 | XPC_EXPORT 234 | void 235 | xpc_session_cancel(xpc_session_t session); 236 | 237 | #pragma mark Message Send 238 | /*! 239 | * @function xpc_session_send_message 240 | * Sends a message over the session to the destination service. 241 | * 242 | * @param session 243 | * The session to send the message over. 244 | * 245 | * @param message 246 | * The message to send. This must be a dictionary object. 247 | * 248 | * @result 249 | * In the event of an error this will return an {@link xpc_rich_error_t} 250 | * detailing the reasons for the failure. On success this return value will be 251 | * NULL. 252 | * 253 | * @discussion 254 | * Messages are delivered in FIFO order. This API is safe to call from multiple 255 | * GCD queues. There is no indication that a message was delivered successfully. 256 | * This is because even once the message has been successfully enqueued on the 257 | * remote end, there are no guarantees about when the runtime will dequeue the 258 | * message and invoke the other session's event handler block. 259 | * 260 | * If this is invoked on an inactive session, one created using the 261 | * XPC_SESSION_CREATE_INACTIVE flag and hasn't yet been activated, the process 262 | * will crash. 263 | */ 264 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 265 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 266 | xpc_rich_error_t _Nullable 267 | xpc_session_send_message(xpc_session_t session, xpc_object_t message); 268 | 269 | /*! 270 | * @function xpc_session_send_message_with_reply_sync 271 | * Sends a message over the session to the destination service and blocks the 272 | * caller until a reply is received. 273 | * 274 | * @param session 275 | * The session over which the message will be sent. 276 | * 277 | * @param message 278 | * The message to send. This must be a dictionary object. 279 | * 280 | * @param error_out 281 | * If this parameter is provided, in the event of a failure it will point to an 282 | * {@link xpc_rich_error_t} describing the details of the error. 283 | * 284 | * @result 285 | * On success, this will return the reply message as an {@link xpc_object_t}. 286 | * Otherwise NULL is returned. 287 | * 288 | * @discussion 289 | * This API supports priority inversion avoidance and should be used instead of 290 | * combining xpc_session_send_message_with_reply_async with a semaphore. 291 | * 292 | * If this is invoked on an inactive session, for example one created using the 293 | * XPC_SESSION_CREATE_INACTIVE flag that hasn't yet been activated, the process 294 | * will crash. 295 | * 296 | * Invoking this API while the target queue is blocked would lead to deadlocks 297 | * in certain scenarios. For that reason, invoking it from the target queue 298 | * results in a crash. 299 | * 300 | * Be judicious about your use of this API. It can block indefinitely, so if you 301 | * are using it to implement an API that can be called from the main queue, you 302 | * may wish to consider allowing the API to take a queue and callback block so 303 | * that results may be delivered asynchronously if possible. 304 | */ 305 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 306 | XPC_EXPORT XPC_RETURNS_RETAINED XPC_WARN_RESULT 307 | xpc_object_t _Nullable 308 | xpc_session_send_message_with_reply_sync(xpc_session_t session, 309 | xpc_object_t message, xpc_rich_error_t _Nullable * _Nullable error_out); 310 | 311 | /*! 312 | * @function xpc_session_send_message_with_reply_async 313 | * Sends a message over the session to the destination service and executes the 314 | * provided callback when a reply is received. 315 | * 316 | * @param session 317 | * The session over which the message will be sent. 318 | * 319 | * @param message 320 | * The message to send. This must be a dictionary object. 321 | * 322 | * @param reply_handler 323 | * The handler block to invoke when a reply to the message is received from the 324 | * session. If the session is torn down before the reply was received, for 325 | * example if the remote service exits prematurely, this handler will be 326 | * executed and passed an appropriate {@link xpc_rich_error_t} object describing 327 | * the failure. 328 | * 329 | * @discussion 330 | * If this is invoked on an inactive session, for example one created using the 331 | * XPC_SESSION_CREATE_INACTIVE flag that hasn't yet been activated, the process 332 | * will crash. 333 | * 334 | * If this is invoked on a cancelled session, this will generate a simulated 335 | * crash. 336 | */ 337 | API_AVAILABLE(macos(13.0), ios(16.0), tvos(16.0), watchos(9.0)) 338 | XPC_EXPORT 339 | void 340 | xpc_session_send_message_with_reply_async(xpc_session_t session, 341 | xpc_object_t message, xpc_session_reply_handler_t reply_handler); 342 | 343 | __END_DECLS 344 | XPC_ASSUME_NONNULL_END 345 | 346 | #endif // __XPC_SESSION_H__ 347 | -------------------------------------------------------------------------------- /headers/xpc_private.h: -------------------------------------------------------------------------------- 1 | #ifndef __XPC_PRIVATE_H__ 2 | #define __XPC_PRIVATE_H__ 3 | 4 | void xpc_dictionary_get_audit_token(xpc_object_t xdict, audit_token_t *token); 5 | char *xpc_strerror (int); 6 | 7 | extern XPC_RETURNS_RETAINED xpc_object_t xpc_pipe_create_from_port(mach_port_t port, uint32_t flags); 8 | extern int xpc_pipe_simpleroutine(xpc_object_t pipe, xpc_object_t message); 9 | extern int xpc_pipe_routine(xpc_object_t pipe, xpc_object_t message, XPC_GIVES_REFERENCE xpc_object_t *reply); 10 | extern int xpc_pipe_routine_with_flags(xpc_object_t xpc_pipe, xpc_object_t inDict, XPC_GIVES_REFERENCE xpc_object_t *reply, uint32_t flags); 11 | extern int xpc_pipe_routine_reply(xpc_object_t reply); 12 | extern int xpc_pipe_receive(mach_port_t port, XPC_GIVES_REFERENCE xpc_object_t *message); 13 | 14 | extern XPC_RETURNS_RETAINED xpc_object_t xpc_copy_entitlement_for_token(const char *, audit_token_t *); 15 | 16 | #endif -------------------------------------------------------------------------------- /jbsigs.h: -------------------------------------------------------------------------------- 1 | #include "jbsigs/jbsigs-1.h" 2 | #include "jbsigs/jbsigs-2.h" 3 | #include "jbsigs/jbsigs-3.h" 4 | #include "jbsigs/jbsigs-4.h" 5 | #include "jbsigs/jbsigs-5.h" 6 | #include "jbsigs/jbsigs-6.h" 7 | #include "jbsigs/jbsigs-7.h" 8 | #include "jbsigs/jbsigs-8.h" 9 | #include "jbsigs/jbsigs-9.h" 10 | #include "jbsigs/jbsigs-10.h" 11 | #include "jbsigs/jbsigs-11.h" 12 | #include "jbsigs/jbsigs-12.h" 13 | #include "jbsigs/jbsigs-13.h" 14 | #include "jbsigs/jbsigs-14.h" 15 | #include "jbsigs/jbsigs-15.h" 16 | #include "jbsigs/jbsigs-16.h" 17 | -------------------------------------------------------------------------------- /jbsigs_generator.m: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define LOG printf 17 | 18 | 19 | int gDesc = 0; 20 | int gFiles = 0; 21 | int gMachOs = 0; 22 | int gSilces = 0; 23 | int gCodeSigns = 0; 24 | int gCodeSignBytes = 0; 25 | 26 | int processMachO(const char* file, int (^handler)(int,uint64_t,size_t,void*)) 27 | { 28 | void* macho=NULL; 29 | int fd = open(file, O_RDONLY|O_NOFOLLOW_ANY); 30 | if(fd < 0) { 31 | fprintf(stderr, "open %s error:%d,%s\n", file, errno, strerror(errno)); 32 | goto final; 33 | } 34 | 35 | gFiles++; 36 | 37 | struct stat st; 38 | if(stat(file, &st) < 0) { 39 | fprintf(stderr, "stat %s error:%d,%s\n", file, errno, strerror(errno)); 40 | goto final; 41 | } 42 | 43 | LOG("file size = %lld\n", st.st_size); 44 | 45 | int mapflag = MAP_PRIVATE; 46 | #ifdef MAP_RESILIENT_CODESIGN 47 | /* MAP_RESILIENT_CODESIGN only works with MAP_PRIVATE+(PROT_READ[|PROT_WRITE]) or MAP_SHARED+PROT_READ */ 48 | mapflag |= MAP_RESILIENT_CODESIGN; 49 | #endif 50 | macho = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, mapflag, fd, 0); 51 | if(macho == MAP_FAILED) { 52 | fprintf(stderr, "map %s error:%d,%s\n", file, errno, strerror(errno)); 53 | goto final; 54 | } 55 | 56 | uint32_t magic = *(uint32_t*)macho; 57 | LOG("macho magic=%08x\n", magic); 58 | if(magic==FAT_MAGIC || magic==FAT_CIGAM) { 59 | gMachOs++; 60 | struct fat_header* fathdr = (struct fat_header*)macho; 61 | struct fat_arch* archdr = (struct fat_arch*)((uint64_t)fathdr + sizeof(*fathdr)); 62 | int count = magic==FAT_MAGIC ? fathdr->nfat_arch : __builtin_bswap32(fathdr->nfat_arch); 63 | for(int i=0; infat_arch : __builtin_bswap32(fathdr->nfat_arch); 74 | for(int i=0; i=0) close(fd); 92 | 93 | return 0; 94 | } 95 | 96 | int findCodeSignature(struct mach_header_64* header, void(^handler)(void*, size_t)) 97 | { 98 | struct load_command* lc = (struct load_command*)((uint64_t)header + sizeof(*header)); 99 | for (int i = 0; i < header->ncmds; i++) { 100 | 101 | switch(lc->cmd) { 102 | 103 | case LC_CODE_SIGNATURE: 104 | { 105 | struct linkedit_data_command* sigCmd = (struct linkedit_data_command*)lc; 106 | handler((void*)((uint64_t)header + sigCmd->dataoff), sigCmd->datasize); 107 | break; 108 | } 109 | } 110 | 111 | ///////// 112 | lc = (struct load_command *) ((char *)lc + lc->cmdsize); 113 | } 114 | return 0; 115 | } 116 | 117 | void writeMachOFileSig(NSString* path) 118 | { 119 | static int index=1; 120 | static FILE* outfp = NULL; 121 | static FILE* sigfp = NULL; 122 | static NSMutableSet* jbsigs = nil; 123 | 124 | static dispatch_once_t onceToken; 125 | dispatch_once(&onceToken, ^{ 126 | jbsigs = [NSMutableSet new]; 127 | 128 | [NSFileManager.defaultManager removeItemAtPath:@"jbsigs" error:nil]; 129 | 130 | mkdir("jbsigs", 0755); 131 | 132 | outfp = fopen("jbsigs.h", "w+"); 133 | fprintf(outfp, "#include \"jbsigs/jbsigs-%d.h\"\n", index); 134 | }); 135 | 136 | __block NSMutableString* result = [NSMutableString new]; 137 | LOG("file: %s\n", path.fileSystemRepresentation); 138 | processMachO(path.fileSystemRepresentation, ^(int fd,uint64_t offset,size_t size, void* header) { 139 | gSilces++; 140 | findCodeSignature(header, ^(void* data, size_t size) { 141 | uint8_t cdhash[20]={0}; 142 | CC_SHA1(data, (CC_LONG)size, cdhash); 143 | char hashstr[sizeof(cdhash)*2 + 1] = {0}; 144 | for(int i=0; i (1*1024*1024)) 159 | { 160 | index++; 161 | fprintf(outfp, "#include \"jbsigs/jbsigs-%d.h\"\n", index); 162 | if(sigfp) { 163 | fclose(sigfp); 164 | sigfp=NULL; 165 | } 166 | } 167 | 168 | if(!sigfp) { 169 | char sigpath[PATH_MAX]; 170 | snprintf(sigpath,sizeof(sigpath),"jbsigs/jbsigs-%d.h", index); 171 | sigfp = fopen(sigpath, "w+"); 172 | } 173 | 174 | if(gDesc) fprintf(sigfp, "// %s, %llx\n", path.lastPathComponent.fileSystemRepresentation, offset); 175 | fprintf(sigfp, "JBSIGS(%ld, %s, ((uint8_t[]){\n", size, hashstr); 176 | for(int i=0; i= 3) { 201 | gDesc = YES; 202 | } 203 | 204 | if(access(argv[1], F_OK) != 0) { 205 | LOG("invalid dir path: %s\n", argv[1]); 206 | return -1; 207 | } 208 | 209 | NSDirectoryEnumerator *directoryEnumerator = [[NSFileManager defaultManager] enumeratorAtURL:[NSURL fileURLWithPath:@(argv[1]) isDirectory:YES] includingPropertiesForKeys:nil options:0 errorHandler:nil]; 210 | for(NSURL* file in directoryEnumerator) { 211 | writeMachOFileSig(file.path); 212 | } 213 | 214 | printf("total files=%d machos=%d silces=%d codesigns=%d bytes=%d wrote to jbsigs.h\n", gFiles, gMachOs, gSilces, gCodeSigns, gCodeSignBytes); 215 | 216 | return 0; 217 | } 218 | 219 | #ifndef __XCODE_IDE_TEST__ 220 | //clang -framework Foundation jbsigs_generator.m -o jbsigs_generator 221 | int main(int argc, char * argv[]) 222 | { 223 | return realmain(argc, argv); 224 | } 225 | #endif 226 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | extern char**environ; 9 | 10 | //Don't try to patch/hook me, it's a Kids's trick! 11 | 12 | #define LOG(...) printf(__VA_ARGS__) 13 | 14 | void detect_rootlessJB() 15 | { 16 | if(access("/var/jb", F_OK)==0) { 17 | LOG("rootless JB found!\n"); 18 | } 19 | 20 | if(access("/private/preboot/jb", F_OK)==0) { 21 | LOG("Fugu15 JB found!\n"); 22 | } 23 | 24 | char* xinafiles[] = { 25 | "/var/containers/Bundle/dylib", 26 | "/var/containers/Bundle/xina", 27 | "/var/mobile/Library/Preferences/com.xina.blacklist.plist", 28 | }; 29 | 30 | for(int i=0; i %s\n", ss[i].f_mntfromname, ss[i].f_mntonname); 74 | } 75 | 76 | for(int j=0; j3600700D, 22003305/lldb32003005 180 | 181 | if(flags & 0x00000004) { 182 | LOG("get-task-allow found!\n"); 183 | } 184 | if(flags & 0x04000000) { 185 | LOG("unexcept platform binary!\n"); 186 | } 187 | if(flags & 0x00000008) { 188 | LOG("unexcept installer!\n"); 189 | } 190 | if(!(flags & 0x00000300)) { 191 | LOG("jit-allow found!\n"); 192 | } 193 | if(flags & 0x00004000) { 194 | LOG("unexcept entitlements!\n"); 195 | } 196 | } 197 | 198 | void detect_jb_payload() 199 | { 200 | mach_port_t object_name; 201 | mach_vm_size_t region_size=0; 202 | mach_vm_address_t region_base = (uint64_t)vm_region_64; 203 | 204 | vm_region_basic_info_data_64_t info = {0}; 205 | mach_msg_type_number_t info_cnt = VM_REGION_BASIC_INFO_COUNT_64; 206 | 207 | vm_region_64(mach_task_self(), (vm_address_t*)®ion_base, (vm_size_t*)®ion_size, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info, &info_cnt, &object_name); 208 | 209 | if(info.protection != VM_PROT_READ) { 210 | LOG("jb payload injected!\n"); 211 | } 212 | } 213 | 214 | void detect_exception_port() 215 | { 216 | exception_mask_t masks[EXC_TYPES_COUNT]; 217 | mach_port_t ports[EXC_TYPES_COUNT]; 218 | exception_behavior_t behaviors[EXC_TYPES_COUNT]; 219 | thread_state_flavor_t flavors[EXC_TYPES_COUNT]; 220 | mach_msg_type_number_t count=0; 221 | 222 | mach_port_t task = mach_task_self(); 223 | 224 | task_get_exception_ports(task, EXC_MASK_ALL, masks, &count, ports, behaviors, flavors); 225 | //default: mask=00001BFE port=00000000 behavior=00000000 flavor=00000000 226 | //some jailbreaks set launchd exception port and subproces will auto inherit it 227 | 228 | if(count != 1) { 229 | LOG("exception record modified!"); 230 | } 231 | 232 | for (int i = 0; i0) { 326 | LOG("/var/jb found: %s", buf); 327 | //we can save the link to userDefaults/keyChains/pasteBoard, or send to server and bind it to your device-id/app-account 328 | [NSUserDefaults.standardUserDefaults setObject:[NSString stringWithUTF8String:buf] forKey:@"/var/jb"]; 329 | } 330 | else 331 | { 332 | NSString* saved = [NSUserDefaults.standardUserDefaults stringForKey:@"/var/jb"]; 333 | if(access(saved.UTF8String, F_OK)==0) { 334 | LOG("removed /var/jb found: %s\n", saved.UTF8String); 335 | } 336 | } 337 | } 338 | 339 | void detect_fugu15Max() 340 | { 341 | if(access("/usr/lib/systemhook.dylib", F_OK)==0) { 342 | LOG("systemhook.dylib found!\n"); 343 | } 344 | if(access("/usr/lib/sandbox.plist", F_OK)==0) { 345 | LOG("sandbox.plist found!\n"); 346 | } 347 | if(access("/var/log/launchdhook.log", F_OK)==0) { 348 | LOG("launchdhook.log found!\n"); 349 | } 350 | 351 | struct statfs s={0}; 352 | statfs("/usr/lib", &s); 353 | if(strcmp("/", s.f_mntonname)!=0) { 354 | LOG("fakelib found! %s\n", s.f_mntfromname); 355 | } 356 | } 357 | 358 | void detect_url_schemes() 359 | { 360 | //jailbroken app's scheme doesn't need to define in Info.plist ? 361 | static char* schemes[] = { 362 | "sileo", 363 | "zbra", 364 | "cydia", 365 | "installer", 366 | "apt-repo", 367 | "filza", 368 | }; 369 | 370 | for(int i=0; i= 0); 419 | 420 | fsignatures_t sigreg; 421 | sigreg.fs_file_start = 0; 422 | sigreg.fs_blob_start = jbsigs[i].data; 423 | sigreg.fs_blob_size = jbsigs[i].size; 424 | if(fcntl(fd, F_ADDSIGS, &sigreg)==0) 425 | { 426 | struct fgetsigsinfo siginfo = {0, GETSIGSINFO_PLATFORM_BINARY, 0}; 427 | assert(fcntl(fd, F_GETSIGSINFO, &siginfo)==0); 428 | 429 | LOG("jailbreak actived! %s : %d\n", jbsigs[i].tag, siginfo.fg_sig_is_platform); 430 | //break; 431 | } 432 | 433 | close(fd); 434 | unlink(path); 435 | } 436 | } 437 | 438 | void detect_jailbreak_port() 439 | { 440 | char* ports[] = { 441 | "cy:com.saurik.substrated", 442 | "cy:com.opa334.jailbreakd", 443 | "lh:com.opa334.jailbreakd" 444 | }; 445 | for(int i=0; i 459 | #include 460 | 461 | struct _os_alloc_once_s { 462 | long once; 463 | void *ptr; 464 | }; 465 | 466 | struct xpc_global_data { 467 | uint64_t a; 468 | uint64_t xpc_flags; 469 | mach_port_t task_bootstrap_port; /* 0x10 */ 470 | #ifndef _64 471 | uint32_t padding; 472 | #endif 473 | xpc_object_t xpc_bootstrap_pipe; /* 0x18 */ 474 | }; 475 | 476 | extern struct _os_alloc_once_s _os_alloc_once_table[]; 477 | extern void* _os_alloc_once(struct _os_alloc_once_s *slot, size_t sz, os_function_t init); 478 | 479 | #define JBS_DOMAIN_SYSTEMWIDE 1 480 | #define JBS_SYSTEMWIDE_GET_JBROOT 1 481 | 482 | void detect_launchd_jbserver() 483 | { 484 | struct xpc_global_data* globalData = NULL; 485 | if (_os_alloc_once_table[1].once == -1) { 486 | globalData = _os_alloc_once_table[1].ptr; 487 | } 488 | else { 489 | globalData = _os_alloc_once(&_os_alloc_once_table[1], 472, NULL); 490 | if (!globalData) _os_alloc_once_table[1].once = -1; 491 | } 492 | if (!globalData) { 493 | LOG("invalid globalData!\n"); 494 | return; 495 | } 496 | 497 | if (!globalData->xpc_bootstrap_pipe) { 498 | mach_port_t *initPorts; 499 | mach_msg_type_number_t initPortsCount = 0; 500 | if (mach_ports_lookup(mach_task_self(), &initPorts, &initPortsCount) == 0) { 501 | globalData->task_bootstrap_port = initPorts[0]; 502 | globalData->xpc_bootstrap_pipe = xpc_pipe_create_from_port(globalData->task_bootstrap_port, 0); 503 | } 504 | } 505 | if (!globalData->xpc_bootstrap_pipe) { 506 | LOG("invalid xpc_bootstrap_pipe!\n"); 507 | return; 508 | } 509 | xpc_object_t xpipe = globalData->xpc_bootstrap_pipe; 510 | 511 | xpc_object_t xdict = xpc_dictionary_create_empty(); 512 | 513 | xpc_dictionary_set_uint64(xdict, "jb-domain", JBS_DOMAIN_SYSTEMWIDE); 514 | xpc_dictionary_set_uint64(xdict, "action", JBS_SYSTEMWIDE_GET_JBROOT); 515 | 516 | xpc_object_t xreply = NULL; 517 | 518 | int err = xpc_pipe_routine_with_flags(xpipe, xdict, &xreply, 0); 519 | //LOG("xpc_pipe_routine_with_flags error=%d xreply=%p\n", err, xreply); 520 | 521 | if (err != 0) { 522 | return; 523 | } 524 | 525 | if(xreply) { 526 | const char *replyRootPath = xpc_dictionary_get_string(xreply, "root-path"); 527 | LOG("dopamine2 installed: %s\n", replyRootPath); 528 | } 529 | } 530 | 531 | 532 | #define JBSERVER_MACH_MAGIC 0x444F50414D494E45 533 | #define JBSERVER_MACH_CHECKIN 0 534 | struct jbserver_mach_msg { 535 | mach_msg_header_t hdr; 536 | uint64_t magic; 537 | uint64_t action; 538 | }; 539 | struct jbserver_mach_msg_reply { 540 | struct jbserver_mach_msg msg; 541 | uint64_t status; 542 | }; 543 | struct jbserver_mach_msg_checkin { 544 | struct jbserver_mach_msg base; 545 | }; 546 | struct jbserver_mach_msg_checkin_reply { 547 | struct jbserver_mach_msg_reply base; 548 | bool fullyDebugged; 549 | char jbRootPath[PATH_MAX]; 550 | char bootUUID[37]; 551 | char sandboxExtensions[2000]; 552 | }; 553 | kern_return_t jbclient_mach_send_msg(mach_msg_header_t *hdr, struct jbserver_mach_msg_reply *reply) 554 | { 555 | mach_port_t replyPort = mig_get_reply_port(); 556 | if (!replyPort) 557 | return KERN_FAILURE; 558 | 559 | mach_port_t launchdPort = bootstrap_port; 560 | if (!launchdPort) 561 | return KERN_FAILURE; 562 | 563 | hdr->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); 564 | 565 | // size already set 566 | hdr->msgh_remote_port = launchdPort; 567 | hdr->msgh_local_port = replyPort; 568 | hdr->msgh_voucher_port = 0; 569 | hdr->msgh_id = 0x40000000 | 206; 570 | // 206: magic value to make WebContent work (seriously, this is the only ID that the WebContent sandbox allows) 571 | 572 | kern_return_t kr = mach_msg(hdr, MACH_SEND_MSG, hdr->msgh_size, 0, 0, 0, 0); 573 | if (kr != KERN_SUCCESS) { 574 | mach_port_deallocate(task_self_trap(), launchdPort); 575 | return kr; 576 | } 577 | 578 | reply->status = -1; 579 | kr = mach_msg(&reply->msg.hdr, MACH_RCV_MSG, 0, reply->msg.hdr.msgh_size, replyPort, 0, 0); 580 | if (kr != KERN_SUCCESS) { 581 | mach_port_deallocate(task_self_trap(), launchdPort); 582 | return kr; 583 | } 584 | 585 | // Get rid of any rights we might have received 586 | mach_msg_destroy(&reply->msg.hdr); 587 | mach_port_deallocate(task_self_trap(), launchdPort); 588 | return KERN_SUCCESS; 589 | } 590 | void detect_launchd_jb_mach_server() 591 | { 592 | struct jbserver_mach_msg_checkin msg; 593 | msg.base.hdr.msgh_size = sizeof(msg); 594 | msg.base.hdr.msgh_bits = 0; 595 | msg.base.action = JBSERVER_MACH_CHECKIN; 596 | msg.base.magic = JBSERVER_MACH_MAGIC; 597 | 598 | size_t replySize = sizeof(struct jbserver_mach_msg_checkin_reply) + MAX_TRAILER_SIZE; 599 | 600 | uint8_t replyU[replySize]; 601 | bzero(replyU, replySize); 602 | 603 | struct jbserver_mach_msg_checkin_reply *reply = (struct jbserver_mach_msg_checkin_reply *)&replyU; 604 | reply->base.msg.hdr.msgh_size = replySize; 605 | 606 | kern_return_t kr = jbclient_mach_send_msg(&msg.base.hdr, (struct jbserver_mach_msg_reply *)reply); 607 | if (kr != KERN_SUCCESS) 608 | { 609 | LOG("detect_launchd_jb_mach_server: mach error=%x, %s\n", kr, mach_error_string(kr)); 610 | return; 611 | } 612 | 613 | //LOG("detect_launchd_jb_mach_server: status=%d, jbroot=%s\n", reply->base.status, reply->jbRootPath); 614 | if(reply->base.status==0 && reply->jbRootPath[0]) { 615 | LOG("detect_launchd_jb_mach_server: dopamine2 installed: %s\n", reply->jbRootPath); 616 | } 617 | } 618 | 619 | //works on ios14.0 ~ 15.1.1 620 | void detect_trollstpre_app() 621 | { 622 | xpc_connection_t connection = xpc_connection_create_mach_service("com.apple.nehelper", nil, 2); 623 | xpc_connection_set_event_handler(connection, ^(xpc_object_t object){}); 624 | xpc_connection_resume(connection); 625 | xpc_object_t xdict = xpc_dictionary_create(nil, nil, 0); 626 | xpc_dictionary_set_uint64(xdict, "delegate-class-id", 1); 627 | xpc_dictionary_set_uint64(xdict, "cache-command", 3); 628 | xpc_dictionary_set_string(xdict, "cache-signing-identifier", "com.opa334.TrollStore"); 629 | xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, xdict); 630 | // NSLog(@"reply=%s", xpc_copy_description(reply)); 631 | xpc_object_t resultData = xpc_dictionary_get_value(reply, "result-data"); 632 | if(xpc_dictionary_get_value(resultData, "cache-app-uuid") != nil) { 633 | LOG("trollstore app installed!\n"); 634 | } 635 | } 636 | 637 | 638 | #import 639 | #import 640 | void detect_passcode_status() 641 | { 642 | { 643 | LAContext *myContext = [[LAContext alloc] init]; 644 | 645 | NSError *authError = nil; 646 | if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&authError]) 647 | { 648 | // LOG("LocalAuthentication: passcode has set\n"); 649 | } 650 | else 651 | { 652 | LOG("LocalAuthentication: passcode has not set, %s\n", authError.localizedDescription.UTF8String); 653 | } 654 | } 655 | 656 | { 657 | NSDictionary *attributes = @{ 658 | (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, 659 | (__bridge id)kSecAttrService: @"LocalDeviceServices", 660 | (__bridge id)kSecAttrAccount: @"NoAccount", 661 | (__bridge id)kSecValueData: [@"Device has passcode set?" dataUsingEncoding:NSUTF8StringEncoding], 662 | (__bridge id)kSecAttrAccessible: (__bridge id)kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly 663 | }; 664 | 665 | OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL); 666 | if (status == errSecSuccess) { 667 | // item added okay, passcode has been set 668 | 669 | SecItemDelete((__bridge CFDictionaryRef)attributes); 670 | 671 | // LOG("SecurityFramework: passcode has set\n"); 672 | } else { 673 | LOG("SecurityFramework: passcode has not set, %d\n", status); 674 | } 675 | } 676 | 677 | { 678 | CFErrorRef sacError = NULL; 679 | SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, kNilOptions, &sacError); 680 | 681 | NSDictionary *params = @{ 682 | (__bridge id)kSecAttrTokenID: (__bridge id)kSecAttrTokenIDSecureEnclave, 683 | (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeEC, 684 | (__bridge id)kSecAttrKeySizeInBits: @256, 685 | (__bridge id)kSecPrivateKeyAttrs: @{ 686 | (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject, 687 | (__bridge id)kSecAttrIsPermanent: @YES, 688 | (__bridge id)kSecAttrLabel: @"TestKey", 689 | }, 690 | }; 691 | 692 | CFErrorRef error=nil; 693 | SecKeyRef SEKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)params, &error); 694 | if (SEKey) { 695 | // LOG("SecureEnclave: passcode has set\n"); 696 | } else { 697 | LOG("SecureEnclave: passcode has not set, %s\n", ((__bridge NSError*)error).localizedDescription.UTF8String); 698 | } 699 | } 700 | 701 | { 702 | #define kMobileKeyBagDisabled 3 703 | void* MobileKeyBag = dlopen("/System/Library/PrivateFrameworks/MobileKeyBag.framework/MobileKeyBag", RTLD_NOW); 704 | int (*MKBGetDeviceLockState)(CFDictionaryRef options) = dlsym(MobileKeyBag, "MKBGetDeviceLockState"); 705 | if(MKBGetDeviceLockState(NULL) == kMobileKeyBagDisabled) { 706 | LOG("AppleKeyStore: passcode has not set!\n"); 707 | } 708 | } 709 | } 710 | 711 | void detect_cfprefsd_hook() 712 | { 713 | char* jbplists[] = { 714 | "/basebin/LaunchDaemons/com.opa334.Dopamine.idownloadd", 715 | "/basebin/LaunchDaemons/com.opa334.trustcache_rebuild", 716 | "/basebin/LaunchDaemons/com.opa334.Dopamine.startup", 717 | "/basebin/LaunchDaemons/com.opa334.jailbreakd", 718 | "/basebin/LaunchDaemons/jailbreakd", 719 | 720 | "/Library/LaunchDaemons/us.diatr.shshd", 721 | "/Library/LaunchDaemons/com.apple.atrun", 722 | "/Library/LaunchDaemons/com.opa334.sandyd", 723 | "/Library/LaunchDaemons/com.openssh.sshd", 724 | "/Library/LaunchDaemons/com.tigisoftware.filza.helper", 725 | 726 | "/var/mobile/Library/Preferences/com.opa334.choicyprefs", 727 | "/var/mobile/Library/Preferences/com.opa334.craneprefs", 728 | "/var/mobile/Library/Preferences/com.spark.snowboardprefs", 729 | "/var/mobile/Library/Preferences/com.tigisoftware.Filza", 730 | "/var/mobile/Library/Preferences/org.coolstar.SileoStore", 731 | "/var/mobile/Library/Preferences/ru.domo.cocoatop64", 732 | "/var/mobile/Library/Preferences/ws.hbang.Terminal", 733 | "/var/mobile/Library/Preferences/xyz.willy.Zebra", 734 | }; 735 | char* validKeys[] = { 736 | "Label", 737 | "Program", 738 | "ProgramArguments", 739 | "EnvironmentVariables", 740 | "ProcessType", 741 | "MachServices", 742 | "UserName", 743 | "RunAtLoad", 744 | "KeepAlive", 745 | "Disabled", 746 | 747 | "additionalExecutables", 748 | "appSettings", 749 | 750 | "keychainVersion", 751 | "expandContainersShortcutEnabled", 752 | "launchApplicationOnContainerSelectionEnabled", 753 | "onlyShowIfContainersExistEnabled", 754 | 755 | "ActiveMenuItems", 756 | "CustomCornerRadiusEnabled", 757 | 758 | "FavoritedLinks", 759 | "FavoritesVersion", 760 | 761 | "AutoRefreshSources", 762 | "CanisterIngest", 763 | "CanisterUpdateDate", 764 | "InstallSortType", 765 | "ShowIgnoredUpdates", 766 | 767 | "Mode4SortColumn", 768 | "Mode4SortDescending", 769 | "ProcInfoMode", 770 | 771 | "keyboardArrowsStyle", 772 | "refreshRateOnAC", 773 | "refreshRateOnBattery", 774 | 775 | "AlwaysInstallLatest", 776 | "FeaturedPackagesType", 777 | "FilterIncompatibleArchitectures", 778 | "FinishAutomatically", 779 | "PackageSortingType", 780 | "WantsFeaturedPackages", 781 | 782 | }; 783 | for(int i=0; i 0.2 || ((double)delta2/(double)basetime) > 0.2 ) 825 | { 826 | LOG("ipchook detected: basetime=%llu delta1=%lld delta2=%lld\n", basetime, delta1, delta2); 827 | } 828 | } 829 | 830 | /* bypass all jb-bypass: FlyJB,Shadow,A-Bypass etc... */ 831 | @interface NSObject(JBDetect15) + (void)initialize; @end 832 | @implementation NSObject(JBDetect15) 833 | + (void)initialize 834 | { 835 | static int loaded=0; 836 | if(loaded++==0) { 837 | 838 | LOG("Don't try to patch/hook me, it's a Kids's trick!\n"); 839 | 840 | // NS Foundation is not available here 841 | 842 | detect_rootlessJB(); 843 | detect_kernBypass(); 844 | detect_chroot(); 845 | detect_mount_fs(); 846 | detect_bootstraps(); 847 | detect_trollStoredFilza(); 848 | detect_jailbreakd(); 849 | detect_proc_flags(); 850 | detect_exception_port(); 851 | detect_jb_payload(); 852 | detect_jb_preboot(); 853 | detect_jailbroken_apps(); 854 | detect_fugu15Max(); 855 | detect_jailbreak_sigs(); 856 | detect_jailbreak_port(); 857 | detect_launchd_jbserver(); 858 | detect_launchd_jb_mach_server(); 859 | detect_trollstpre_app(); 860 | detect_launchd_ipchook(); 861 | 862 | // wait for NS Foundation to initialize. 863 | dispatch_async(dispatch_get_main_queue(), ^{ 864 | detect_passcode_status(); 865 | detect_removed_varjb(); 866 | detect_url_schemes(); 867 | detect_cfprefsd_hook(); 868 | detect_jbapp_plugins(); 869 | }); 870 | } 871 | } 872 | @end 873 | 874 | #import "AppDelegate.h" 875 | int main(int argc, char * argv[]) 876 | { 877 | NSString * appDelegateClassName; 878 | @autoreleasepool { 879 | // Setup code that might create autoreleased objects goes here. 880 | appDelegateClassName = NSStringFromClass([AppDelegate class]); 881 | } 882 | return UIApplicationMain(argc, argv, nil, appDelegateClassName); 883 | } 884 | --------------------------------------------------------------------------------