2 * Copyright (c) 2012, 2013, 2015 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <Availability.h>
25 #include <TargetConditionals.h>
27 #include <dispatch/dispatch.h>
29 #include <vproc_priv.h>
32 #include "libSystemConfiguration_client.h"
36 #pragma mark libSC fork handlers
39 __attribute__((weak_import
)) bool _dispatch_is_multithreaded(void);
41 static boolean_t _has_forked
= FALSE
;
43 // These functions are registered with libSystem to
44 // handle pthread_atfork callbacks.
47 _libSC_info_fork_prepare()
53 _libSC_info_fork_parent()
59 _libSC_info_fork_child()
61 if (_dispatch_is_multithreaded()) {
62 // if dispatch was active before fork
71 #pragma mark Support functions
75 log_xpc_object(const char *msg
, xpc_object_t obj
)
79 desc
= xpc_copy_description(obj
);
80 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
, "%s = %s", msg
, desc
);
87 libSC_info_client_create(dispatch_queue_t q
,
88 const char *service_name
,
89 const char *service_description
)
92 libSC_info_client_t
*client
;
93 #if !TARGET_IPHONE_SIMULATOR
94 const uint64_t flags
= XPC_CONNECTION_MACH_SERVICE_PRIVILEGED
;
95 #else // !TARGET_IPHONE_SIMULATOR
96 const uint64_t flags
= 0;
97 #endif // !TARGET_IPHONE_SIMULATOR
103 client
= malloc(sizeof(libSC_info_client_t
));
104 client
->active
= TRUE
;
105 client
->service_description
= strdup(service_description
);
106 client
->service_name
= strdup(service_name
);
108 c
= xpc_connection_create_mach_service(service_name
, q
, flags
);
110 xpc_connection_set_event_handler(c
, ^(xpc_object_t xobj
) {
113 type
= xpc_get_type(xobj
);
114 if (type
== XPC_TYPE_DICTIONARY
) {
115 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
, "%s: unexpected message", client
->service_name
);
116 log_xpc_object(" dict = ", xobj
);
117 } else if (type
== XPC_TYPE_ERROR
) {
118 if (xobj
== XPC_ERROR_CONNECTION_INVALID
) {
119 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
, "%s: server not available", client
->service_name
);
120 client
->active
= FALSE
;
121 } else if (xobj
== XPC_ERROR_CONNECTION_INTERRUPTED
) {
122 asl_log(NULL
, NULL
, ASL_LEVEL_DEBUG
, "%s: server failed", client
->service_name
);
126 desc
= xpc_dictionary_get_string(xobj
, XPC_ERROR_KEY_DESCRIPTION
);
127 asl_log(NULL
, NULL
, ASL_LEVEL_DEBUG
,
128 "%s: connection error: %d : %s",
129 client
->service_name
,
130 xpc_connection_get_pid(c
),
134 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
,
135 "%s: unknown event type : %p",
136 client
->service_name
,
141 client
->connection
= c
;
143 xpc_connection_resume(c
);
151 libSC_info_client_release(libSC_info_client_t
*client
)
153 xpc_release(client
->connection
);
154 free(client
->service_description
);
155 free(client
->service_name
);
162 libSC_send_message_with_reply_sync(libSC_info_client_t
*client
,
163 xpc_object_t message
)
168 // send request to the DNS configuration server
169 reply
= xpc_connection_send_message_with_reply_sync(client
->connection
, message
);
173 type
= xpc_get_type(reply
);
174 if (type
== XPC_TYPE_DICTIONARY
) {
179 if ((type
== XPC_TYPE_ERROR
) && (reply
== XPC_ERROR_CONNECTION_INTERRUPTED
)) {
180 asl_log(NULL
, NULL
, ASL_LEVEL_DEBUG
,
181 "%s server failure, retrying",
182 client
->service_description
);
188 if ((type
== XPC_TYPE_ERROR
) && (reply
== XPC_ERROR_CONNECTION_INVALID
)) {
189 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
,
190 "%s server not available",
191 client
->service_description
);
192 client
->active
= FALSE
;
194 asl_log(NULL
, NULL
, ASL_LEVEL_ERR
,
195 "%s xpc_connection_send_message_with_reply_sync() with unexpected reply",
196 client
->service_description
);
197 log_xpc_object(" reply", reply
);