├── .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 |
--------------------------------------------------------------------------------