1 #include <config.h>
2 #include "test-utils.h"
3 
4 typedef struct
5 {
6   DBusLoop *loop;
7   DBusConnection *connection;
8 
9 } CData;
10 
11 static dbus_bool_t
add_watch(DBusWatch * watch,void * data)12 add_watch (DBusWatch *watch,
13 	   void      *data)
14 {
15   CData *cd = data;
16 
17   return _dbus_loop_add_watch (cd->loop, watch);
18 }
19 
20 static void
remove_watch(DBusWatch * watch,void * data)21 remove_watch (DBusWatch *watch,
22 	      void      *data)
23 {
24   CData *cd = data;
25 
26   _dbus_loop_remove_watch (cd->loop, watch);
27 }
28 
29 static void
toggle_watch(DBusWatch * watch,void * data)30 toggle_watch (DBusWatch  *watch,
31               void       *data)
32 {
33   CData *cd = data;
34 
35   _dbus_loop_toggle_watch (cd->loop, watch);
36 }
37 
38 static dbus_bool_t
add_timeout(DBusTimeout * timeout,void * data)39 add_timeout (DBusTimeout *timeout,
40 	     void        *data)
41 {
42   CData *cd = data;
43 
44   return _dbus_loop_add_timeout (cd->loop, timeout);
45 }
46 
47 static void
remove_timeout(DBusTimeout * timeout,void * data)48 remove_timeout (DBusTimeout *timeout,
49 		void        *data)
50 {
51   CData *cd = data;
52 
53   _dbus_loop_remove_timeout (cd->loop, timeout);
54 }
55 
56 static void
dispatch_status_function(DBusConnection * connection,DBusDispatchStatus new_status,void * data)57 dispatch_status_function (DBusConnection    *connection,
58                           DBusDispatchStatus new_status,
59                           void              *data)
60 {
61   DBusLoop *loop = data;
62 
63   if (new_status != DBUS_DISPATCH_COMPLETE)
64     {
65       while (!_dbus_loop_queue_dispatch (loop, connection))
66         _dbus_wait_for_memory ();
67     }
68 }
69 
70 static void
cdata_free(void * data)71 cdata_free (void *data)
72 {
73   CData *cd = data;
74 
75   dbus_connection_unref (cd->connection);
76   _dbus_loop_unref (cd->loop);
77 
78   dbus_free (cd);
79 }
80 
81 static CData*
cdata_new(DBusLoop * loop,DBusConnection * connection)82 cdata_new (DBusLoop       *loop,
83            DBusConnection *connection)
84 {
85   CData *cd;
86 
87   cd = dbus_new0 (CData, 1);
88   if (cd == NULL)
89     return NULL;
90 
91   cd->loop = loop;
92   cd->connection = connection;
93 
94   dbus_connection_ref (cd->connection);
95   _dbus_loop_ref (cd->loop);
96 
97   return cd;
98 }
99 
100 dbus_bool_t
test_connection_setup(TestMainContext * ctx,DBusConnection * connection)101 test_connection_setup (TestMainContext *ctx,
102                        DBusConnection *connection)
103 {
104   DBusLoop *loop = ctx;
105   CData *cd;
106 
107   cd = NULL;
108 
109   dbus_connection_set_dispatch_status_function (connection, dispatch_status_function,
110                                                 loop, NULL);
111 
112   cd = cdata_new (loop, connection);
113   if (cd == NULL)
114     goto nomem;
115 
116   if (!dbus_connection_set_watch_functions (connection,
117                                             add_watch,
118                                             remove_watch,
119                                             toggle_watch,
120                                             cd, cdata_free))
121     goto nomem;
122 
123 
124   cd = cdata_new (loop, connection);
125   if (cd == NULL)
126     goto nomem;
127 
128   if (!dbus_connection_set_timeout_functions (connection,
129                                               add_timeout,
130                                               remove_timeout,
131                                               NULL,
132                                               cd, cdata_free))
133     goto nomem;
134 
135   if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
136     {
137       if (!_dbus_loop_queue_dispatch (loop, connection))
138         goto nomem;
139     }
140 
141   return TRUE;
142 
143  nomem:
144   if (cd)
145     cdata_free (cd);
146 
147   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
148   dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL);
149   dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL);
150 
151   return FALSE;
152 }
153 
154 static void die (const char *message) _DBUS_GNUC_NORETURN;
155 
156 static void
die(const char * message)157 die (const char *message)
158 {
159   fprintf (stderr, "*** %s", message);
160   exit (1);
161 }
162 
163 void
test_connection_shutdown(TestMainContext * ctx,DBusConnection * connection)164 test_connection_shutdown (TestMainContext *ctx,
165                           DBusConnection *connection)
166 {
167   if (!dbus_connection_set_watch_functions (connection,
168                                             NULL,
169                                             NULL,
170                                             NULL,
171                                             NULL, NULL))
172     die ("setting watch functions to NULL failed");
173 
174   if (!dbus_connection_set_timeout_functions (connection,
175                                               NULL,
176                                               NULL,
177                                               NULL,
178                                               NULL, NULL))
179     die ("setting timeout functions to NULL failed");
180 
181   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
182 }
183 
184 typedef struct
185 {
186   DBusLoop *loop;
187   DBusServer *server;
188 } ServerData;
189 
190 static void
serverdata_free(void * data)191 serverdata_free (void *data)
192 {
193   ServerData *sd = data;
194 
195   dbus_server_unref (sd->server);
196   _dbus_loop_unref (sd->loop);
197 
198   dbus_free (sd);
199 }
200 
201 static ServerData*
serverdata_new(DBusLoop * loop,DBusServer * server)202 serverdata_new (DBusLoop       *loop,
203                 DBusServer     *server)
204 {
205   ServerData *sd;
206 
207   sd = dbus_new0 (ServerData, 1);
208   if (sd == NULL)
209     return NULL;
210 
211   sd->loop = loop;
212   sd->server = server;
213 
214   dbus_server_ref (sd->server);
215   _dbus_loop_ref (sd->loop);
216 
217   return sd;
218 }
219 
220 static dbus_bool_t
add_server_watch(DBusWatch * watch,void * data)221 add_server_watch (DBusWatch  *watch,
222                   void       *data)
223 {
224   ServerData *context = data;
225 
226   return _dbus_loop_add_watch (context->loop, watch);
227 }
228 
229 static void
toggle_server_watch(DBusWatch * watch,void * data)230 toggle_server_watch (DBusWatch  *watch,
231                      void       *data)
232 {
233   ServerData *context = data;
234 
235   _dbus_loop_toggle_watch (context->loop, watch);
236 }
237 
238 static void
remove_server_watch(DBusWatch * watch,void * data)239 remove_server_watch (DBusWatch  *watch,
240                      void       *data)
241 {
242   ServerData *context = data;
243 
244   _dbus_loop_remove_watch (context->loop, watch);
245 }
246 
247 static dbus_bool_t
add_server_timeout(DBusTimeout * timeout,void * data)248 add_server_timeout (DBusTimeout *timeout,
249                     void        *data)
250 {
251   ServerData *context = data;
252 
253   return _dbus_loop_add_timeout (context->loop, timeout);
254 }
255 
256 static void
remove_server_timeout(DBusTimeout * timeout,void * data)257 remove_server_timeout (DBusTimeout *timeout,
258                        void        *data)
259 {
260   ServerData *context = data;
261 
262   _dbus_loop_remove_timeout (context->loop, timeout);
263 }
264 
265 dbus_bool_t
test_server_setup(TestMainContext * ctx,DBusServer * server)266 test_server_setup (TestMainContext *ctx,
267                    DBusServer    *server)
268 {
269   DBusLoop *loop = ctx;
270   ServerData *sd;
271 
272   sd = serverdata_new (loop, server);
273   if (sd == NULL)
274     goto nomem;
275 
276   if (!dbus_server_set_watch_functions (server,
277                                         add_server_watch,
278                                         remove_server_watch,
279                                         toggle_server_watch,
280                                         sd,
281                                         serverdata_free))
282     {
283       goto nomem;
284     }
285 
286   sd = serverdata_new (loop, server);
287   if (sd == NULL)
288     goto nomem;
289 
290   if (!dbus_server_set_timeout_functions (server,
291                                           add_server_timeout,
292                                           remove_server_timeout,
293                                           NULL,
294                                           sd, serverdata_free))
295     {
296       goto nomem;
297     }
298   return TRUE;
299 
300  nomem:
301   if (sd)
302     serverdata_free (sd);
303 
304   test_server_shutdown (loop, server);
305 
306   return FALSE;
307 }
308 
309 void
test_server_shutdown(TestMainContext * ctx,DBusServer * server)310 test_server_shutdown (TestMainContext  *ctx,
311                       DBusServer       *server)
312 {
313   dbus_server_disconnect (server);
314 
315   if (!dbus_server_set_watch_functions (server,
316                                         NULL, NULL, NULL,
317                                         NULL,
318                                         NULL))
319     die ("setting watch functions to NULL failed");
320 
321   if (!dbus_server_set_timeout_functions (server,
322                                           NULL, NULL, NULL,
323                                           NULL,
324                                           NULL))
325     die ("setting timeout functions to NULL failed");
326 }
327 
328 TestMainContext *
test_main_context_get(void)329 test_main_context_get (void)
330 {
331   return _dbus_loop_new ();
332 }
333 
334 TestMainContext *
test_main_context_ref(TestMainContext * ctx)335 test_main_context_ref (TestMainContext *ctx)
336 {
337   return _dbus_loop_ref (ctx);
338 }
339 
test_main_context_unref(TestMainContext * ctx)340 void test_main_context_unref (TestMainContext *ctx)
341 {
342   _dbus_loop_unref (ctx);
343 }
344 
test_main_context_iterate(TestMainContext * ctx,dbus_bool_t may_block)345 void test_main_context_iterate (TestMainContext *ctx,
346                                 dbus_bool_t      may_block)
347 {
348   _dbus_loop_iterate (ctx, may_block);
349 }
350 
351 void
test_pending_call_store_reply(DBusPendingCall * pc,void * data)352 test_pending_call_store_reply (DBusPendingCall *pc,
353     void *data)
354 {
355   DBusMessage **message_p = data;
356 
357   *message_p = dbus_pending_call_steal_reply (pc);
358   _dbus_assert (*message_p != NULL);
359 }
360