D-Bus: dbus-bus.c Source File

D-Bus 1.14.10

dbus-bus.c
1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2/* dbus-bus.c Convenience functions for communicating with the bus.
3 *
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003 Red Hat, Inc.
6 *
7 * Licensed under the Academic Free License version 2.1
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25#include <config.h>
26#include "dbus-bus.h"
27#include "dbus-protocol.h"
28#include "dbus-internals.h"
29#include "dbus-message.h"
30#include "dbus-marshal-validate.h"
31#include "dbus-misc.h"
32#include "dbus-threads-internal.h"
33#include "dbus-connection-internal.h"
34#include "dbus-string.h"
35
77 typedef struct
78{
79 DBusConnection *connection;
80 char *unique_name;
82 unsigned int is_well_known : 1;
83} BusData;
84
88static dbus_int32_t bus_data_slot = -1;
89
91#define N_BUS_TYPES 3
92
93/* Protected by _DBUS_LOCK_bus, except during shutdown, which can't safely
94 * be done in a threaded application anyway. */
95static DBusConnection *bus_connections[N_BUS_TYPES];
96static char *bus_connection_addresses[N_BUS_TYPES] = { NULL, NULL, NULL };
97static DBusBusType activation_bus_type = DBUS_BUS_STARTER;
98static dbus_bool_t initialized = FALSE;
99
100static void
101addresses_shutdown_func (void *data)
102{
103 int i;
104
105 i = 0;
106 while (i < N_BUS_TYPES)
107 {
108 if (bus_connections[i] != NULL)
109 _dbus_warn_check_failed ("dbus_shutdown() called but connections were still live. This probably means the application did not drop all its references to bus connections.");
110
111 dbus_free (bus_connection_addresses[i]);
112 bus_connection_addresses[i] = NULL;
113 ++i;
114 }
115
116 activation_bus_type = DBUS_BUS_STARTER;
117
118 initialized = FALSE;
119}
120
121static dbus_bool_t
122get_from_env (char **connection_p,
123 const char *env_var)
124{
125 const char *s;
126
127 _dbus_assert (*connection_p == NULL);
128
129 s = _dbus_getenv (env_var);
130 if (s == NULL || *s == '\0')
131 return TRUE; /* successfully didn't use the env var */
132 else
133 {
134 *connection_p = _dbus_strdup (s);
135 return *connection_p != NULL;
136 }
137}
138
139static dbus_bool_t
140init_session_address (void)
141{
142 dbus_bool_t retval;
143
144 retval = FALSE;
145
146 /* First, look in the environment. This is the normal case on
147 * freedesktop.org/Unix systems. */
148 get_from_env (&bus_connection_addresses[DBUS_BUS_SESSION],
149 "DBUS_SESSION_BUS_ADDRESS");
150 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
151 {
152 dbus_bool_t supported;
153 DBusString addr;
154 DBusError error = DBUS_ERROR_INIT;
155
156 if (!_dbus_string_init (&addr))
157 return FALSE;
158
159 supported = FALSE;
160 /* So it's not in the environment - let's try a platform-specific method.
161 * On MacOS, this involves asking launchd. On Windows (not specified yet)
162 * we might do a COM lookup.
163 * Ignore errors - if we failed, fall back to autolaunch. */
164 retval = _dbus_lookup_session_address (&supported, &addr, &error);
165 if (supported && retval)
166 {
167 retval =_dbus_string_steal_data (&addr, &bus_connection_addresses[DBUS_BUS_SESSION]);
168 }
169 else if (supported && !retval)
170 {
171 if (dbus_error_is_set(&error))
172 _dbus_warn ("Dynamic session lookup supported but failed: %s", error.message);
173 else
174 _dbus_warn ("Dynamic session lookup supported but failed silently");
175 }
176 _dbus_string_free (&addr);
177 }
178 else
179 retval = TRUE;
180
181 if (!retval)
182 return FALSE;
183
184 /* We have a hard-coded (but compile-time-configurable) fallback address for
185 * the session bus. */
186 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
187 bus_connection_addresses[DBUS_BUS_SESSION] =
188 _dbus_strdup (DBUS_SESSION_BUS_CONNECT_ADDRESS);
189
190 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
191 return FALSE;
192
193 return TRUE;
194}
195
196static dbus_bool_t
197init_connections_unlocked (void)
198{
199 if (!initialized)
200 {
201 const char *s;
202 int i;
203
204 i = 0;
205 while (i < N_BUS_TYPES)
206 {
207 bus_connections[i] = NULL;
208 ++i;
209 }
210
211 /* Don't init these twice, we may run this code twice if
212 * init_connections_unlocked() fails midway through.
213 * In practice, each block below should contain only one
214 * "return FALSE" or running through twice may not
215 * work right.
216 */
217
218 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
219 {
220 _dbus_verbose ("Filling in system bus address...\n");
221
222 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_SYSTEM],
223 "DBUS_SYSTEM_BUS_ADDRESS"))
224 return FALSE;
225 }
226
227
228 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
229 {
230 /* Use default system bus address if none set in environment */
231 bus_connection_addresses[DBUS_BUS_SYSTEM] =
232 _dbus_strdup (DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
233
234 if (bus_connection_addresses[DBUS_BUS_SYSTEM] == NULL)
235 return FALSE;
236
237 _dbus_verbose (" used default system bus \"%s\"\n",
238 bus_connection_addresses[DBUS_BUS_SYSTEM]);
239 }
240 else
241 _dbus_verbose (" used env var system bus \"%s\"\n",
242 bus_connection_addresses[DBUS_BUS_SYSTEM]);
243
244 if (bus_connection_addresses[DBUS_BUS_SESSION] == NULL)
245 {
246 _dbus_verbose ("Filling in session bus address...\n");
247
248 if (!init_session_address ())
249 return FALSE;
250
251 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_SESSION] ?
252 bus_connection_addresses[DBUS_BUS_SESSION] : "none set");
253 }
254
255 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
256 {
257 _dbus_verbose ("Filling in activation bus address...\n");
258
259 if (!get_from_env (&bus_connection_addresses[DBUS_BUS_STARTER],
260 "DBUS_STARTER_ADDRESS"))
261 return FALSE;
262
263 _dbus_verbose (" \"%s\"\n", bus_connection_addresses[DBUS_BUS_STARTER] ?
264 bus_connection_addresses[DBUS_BUS_STARTER] : "none set");
265 }
266
267
268 if (bus_connection_addresses[DBUS_BUS_STARTER] != NULL)
269 {
270 s = _dbus_getenv ("DBUS_STARTER_BUS_TYPE");
271
272 if (s != NULL)
273 {
274 _dbus_verbose ("Bus activation type was set to \"%s\"\n", s);
275
276 if (strcmp (s, "system") == 0)
277 activation_bus_type = DBUS_BUS_SYSTEM;
278 else if (strcmp (s, "session") == 0)
279 activation_bus_type = DBUS_BUS_SESSION;
280 }
281 }
282 else
283 {
284 /* Default to the session bus instead if available */
285 if (bus_connection_addresses[DBUS_BUS_SESSION] != NULL)
286 {
287 bus_connection_addresses[DBUS_BUS_STARTER] =
288 _dbus_strdup (bus_connection_addresses[DBUS_BUS_SESSION]);
289 if (bus_connection_addresses[DBUS_BUS_STARTER] == NULL)
290 return FALSE;
291 }
292 }
293
294 /* If we return FALSE we have to be sure that restarting
295 * the above code will work right
296 */
297
298 if (!_dbus_register_shutdown_func (addresses_shutdown_func,
299 NULL))
300 return FALSE;
301
302 initialized = TRUE;
303 }
304
305 return initialized;
306}
307
308static void
309bus_data_free (void *data)
310{
311 BusData *bd = data;
312
313 if (bd->is_well_known)
314 {
315 int i;
316
317 if (!_DBUS_LOCK (bus))
318 _dbus_assert_not_reached ("global locks should have been initialized "
319 "when we attached bus data");
320
321 /* We may be stored in more than one slot */
322 /* This should now be impossible - these slots are supposed to
323 * be cleared on disconnect, so should not need to be cleared on
324 * finalize
325 */
326 i = 0;
327 while (i < N_BUS_TYPES)
328 {
329 if (bus_connections[i] == bd->connection)
330 bus_connections[i] = NULL;
331
332 ++i;
333 }
334 _DBUS_UNLOCK (bus);
335 }
336
337 dbus_free (bd->unique_name);
338 dbus_free (bd);
339
340 dbus_connection_free_data_slot (&bus_data_slot);
341}
342
343static BusData*
344ensure_bus_data (DBusConnection *connection)
345{
346 BusData *bd;
347
348 if (!dbus_connection_allocate_data_slot (&bus_data_slot))
349 return NULL;
350
351 bd = dbus_connection_get_data (connection, bus_data_slot);
352 if (bd == NULL)
353 {
354 bd = dbus_new0 (BusData, 1);
355 if (bd == NULL)
356 {
357 dbus_connection_free_data_slot (&bus_data_slot);
358 return NULL;
359 }
360
361 bd->connection = connection;
362
363 if (!dbus_connection_set_data (connection, bus_data_slot, bd,
364 bus_data_free))
365 {
366 dbus_free (bd);
367 dbus_connection_free_data_slot (&bus_data_slot);
368 return NULL;
369 }
370
371 /* Data slot refcount now held by the BusData */
372 }
373 else
374 {
375 dbus_connection_free_data_slot (&bus_data_slot);
376 }
377
378 return bd;
379}
380
387void
388_dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection)
389{
390 int i;
391
392 if (!_DBUS_LOCK (bus))
393 {
394 /* If it was in bus_connections, we would have initialized global locks
395 * when we added it. So, it can't be. */
396 return;
397 }
398
399 /* We are expecting to have the connection saved in only one of these
400 * slots, but someone could in a pathological case set system and session
401 * bus to the same bus or something. Or set one of them to the starter
402 * bus without setting the starter bus type in the env variable.
403 * So we don't break the loop as soon as we find a match.
404 */
405 for (i = 0; i < N_BUS_TYPES; ++i)
406 {
407 if (bus_connections[i] == connection)
408 {
409 bus_connections[i] = NULL;
410 }
411 }
412
413 _DBUS_UNLOCK (bus);
414}
415
416static DBusConnection *
417internal_bus_get (DBusBusType type,
418 dbus_bool_t private,
419 DBusError *error)
420{
421 const char *address;
422 DBusConnection *connection;
423 BusData *bd;
424 DBusBusType address_type;
425
426 _dbus_return_val_if_fail (type >= 0 && type < N_BUS_TYPES, NULL);
427 _dbus_return_val_if_error_is_set (error, NULL);
428
429 connection = NULL;
430
431 if (!_DBUS_LOCK (bus))
432 {
433 _DBUS_SET_OOM (error);
434 /* do not "goto out", that would try to unlock */
435 return NULL;
436 }
437
438 if (!init_connections_unlocked ())
439 {
440 _DBUS_SET_OOM (error);
441 goto out;
442 }
443
444 /* We want to use the activation address even if the
445 * activating bus is the session or system bus,
446 * per the spec.
447 */
448 address_type = type;
449
450 /* Use the real type of the activation bus for getting its
451 * connection, but only if the real type's address is available. (If
452 * the activating bus isn't a well-known bus then
453 * activation_bus_type == DBUS_BUS_STARTER)
454 */
455 if (type == DBUS_BUS_STARTER &&
456 bus_connection_addresses[activation_bus_type] != NULL)
457 type = activation_bus_type;
458
459 if (!private && bus_connections[type] != NULL)
460 {
461 connection = bus_connections[type];
462 dbus_connection_ref (connection);
463 goto out;
464 }
465
466 address = bus_connection_addresses[address_type];
467 if (address == NULL)
468 {
469 dbus_set_error (error, DBUS_ERROR_FAILED,
470 "Unable to determine the address of the message bus (try 'man dbus-launch' and 'man dbus-daemon' for help)");
471 goto out;
472 }
473
474 if (private)
475 connection = dbus_connection_open_private (address, error);
476 else
477 connection = dbus_connection_open (address, error);
478
479 if (!connection)
480 {
481 goto out;
482 }
483
484 if (!dbus_bus_register (connection, error))
485 {
486 _dbus_connection_close_possibly_shared (connection);
487 dbus_connection_unref (connection);
488 connection = NULL;
489 goto out;
490 }
491
492 if (!private)
493 {
494 /* store a weak ref to the connection (dbus-connection.c is
495 * supposed to have a strong ref that it drops on disconnect,
496 * since this is a shared connection)
497 */
498 bus_connections[type] = connection;
499 }
500
501 /* By default we're bound to the lifecycle of
502 * the message bus.
503 */
504 dbus_connection_set_exit_on_disconnect (connection,
505 TRUE);
506
507 if (!_DBUS_LOCK (bus_datas))
508 _dbus_assert_not_reached ("global locks were initialized already");
509
510 bd = ensure_bus_data (connection);
511 _dbus_assert (bd != NULL); /* it should have been created on
512 register, so OOM not possible */
513 bd->is_well_known = TRUE;
514 _DBUS_UNLOCK (bus_datas);
515
516out:
517 /* Return a reference to the caller, or NULL with error set. */
518 if (connection == NULL)
519 _DBUS_ASSERT_ERROR_IS_SET (error);
520
521 _DBUS_UNLOCK (bus);
522 return connection;
523}
524
525
/* end of implementation details docs */
527
558 DBusConnection *
559dbus_bus_get (DBusBusType type,
560 DBusError *error)
561{
562 return internal_bus_get (type, FALSE, error);
563}
564
590 DBusConnection *
591dbus_bus_get_private (DBusBusType type,
592 DBusError *error)
593{
594 return internal_bus_get (type, TRUE, error);
595}
596
646dbus_bool_t
647dbus_bus_register (DBusConnection *connection,
648 DBusError *error)
649{
650 DBusMessage *message, *reply;
651 char *name;
652 BusData *bd;
653 dbus_bool_t retval;
654
655 _dbus_return_val_if_fail (connection != NULL, FALSE);
656 _dbus_return_val_if_error_is_set (error, FALSE);
657
658 retval = FALSE;
659 message = NULL;
660 reply = NULL;
661
662 if (!_DBUS_LOCK (bus_datas))
663 {
664 _DBUS_SET_OOM (error);
665 /* do not "goto out", that would try to unlock */
666 return FALSE;
667 }
668
669 bd = ensure_bus_data (connection);
670 if (bd == NULL)
671 {
672 _DBUS_SET_OOM (error);
673 goto out;
674 }
675
676 if (bd->unique_name != NULL)
677 {
678 _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n",
679 bd->unique_name);
680 /* Success! */
681 retval = TRUE;
682 goto out;
683 }
684
685 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
686 DBUS_PATH_DBUS,
687 DBUS_INTERFACE_DBUS,
688 "Hello");
689
690 if (!message)
691 {
692 _DBUS_SET_OOM (error);
693 goto out;
694 }
695
696 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
697
698 if (reply == NULL)
699 goto out;
700 else if (dbus_set_error_from_message (error, reply))
701 goto out;
702 else if (!dbus_message_get_args (reply, error,
703 DBUS_TYPE_STRING, &name,
704 DBUS_TYPE_INVALID))
705 goto out;
706
707 bd->unique_name = _dbus_strdup (name);
708 if (bd->unique_name == NULL)
709 {
710 _DBUS_SET_OOM (error);
711 goto out;
712 }
713
714 retval = TRUE;
715
716 out:
717 _DBUS_UNLOCK (bus_datas);
718
719 if (message)
720 dbus_message_unref (message);
721
722 if (reply)
723 dbus_message_unref (reply);
724
725 if (!retval)
726 _DBUS_ASSERT_ERROR_IS_SET (error);
727
728 return retval;
729}
730
731
766dbus_bool_t
767dbus_bus_set_unique_name (DBusConnection *connection,
768 const char *unique_name)
769{
770 BusData *bd;
771 dbus_bool_t success = FALSE;
772
773 _dbus_return_val_if_fail (connection != NULL, FALSE);
774 _dbus_return_val_if_fail (unique_name != NULL, FALSE);
775
776 if (!_DBUS_LOCK (bus_datas))
777 {
778 /* do not "goto out", that would try to unlock */
779 return FALSE;
780 }
781
782 bd = ensure_bus_data (connection);
783 if (bd == NULL)
784 goto out;
785
786 _dbus_assert (bd->unique_name == NULL);
787
788 bd->unique_name = _dbus_strdup (unique_name);
789 success = bd->unique_name != NULL;
790
791out:
792 _DBUS_UNLOCK (bus_datas);
793
794 return success;
795}
796
815const char*
816dbus_bus_get_unique_name (DBusConnection *connection)
817{
818 BusData *bd;
819 const char *unique_name = NULL;
820
821 _dbus_return_val_if_fail (connection != NULL, NULL);
822
823 if (!_DBUS_LOCK (bus_datas))
824 {
825 /* We'd have initialized locks when we gave it its unique name, if it
826 * had one. Don't "goto out", that would try to unlock. */
827 return NULL;
828 }
829
830 bd = ensure_bus_data (connection);
831 if (bd == NULL)
832 goto out;
833
834 unique_name = bd->unique_name;
835
836out:
837 _DBUS_UNLOCK (bus_datas);
838
839 return unique_name;
840}
841
865unsigned long
866dbus_bus_get_unix_user (DBusConnection *connection,
867 const char *name,
868 DBusError *error)
869{
870 DBusMessage *message, *reply;
871 dbus_uint32_t uid;
872
873 _dbus_return_val_if_fail (connection != NULL, DBUS_UID_UNSET);
874 _dbus_return_val_if_fail (name != NULL, DBUS_UID_UNSET);
875 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), DBUS_UID_UNSET);
876 _dbus_return_val_if_error_is_set (error, DBUS_UID_UNSET);
877
878 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
879 DBUS_PATH_DBUS,
880 DBUS_INTERFACE_DBUS,
881 "GetConnectionUnixUser");
882
883 if (message == NULL)
884 {
885 _DBUS_SET_OOM (error);
886 return DBUS_UID_UNSET;
887 }
888
889 if (!dbus_message_append_args (message,
890 DBUS_TYPE_STRING, &name,
891 DBUS_TYPE_INVALID))
892 {
893 dbus_message_unref (message);
894 _DBUS_SET_OOM (error);
895 return DBUS_UID_UNSET;
896 }
897
898 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
899 error);
900
901 dbus_message_unref (message);
902
903 if (reply == NULL)
904 {
905 _DBUS_ASSERT_ERROR_IS_SET (error);
906 return DBUS_UID_UNSET;
907 }
908
909 if (dbus_set_error_from_message (error, reply))
910 {
911 _DBUS_ASSERT_ERROR_IS_SET (error);
912 dbus_message_unref (reply);
913 return DBUS_UID_UNSET;
914 }
915
916 if (!dbus_message_get_args (reply, error,
917 DBUS_TYPE_UINT32, &uid,
918 DBUS_TYPE_INVALID))
919 {
920 _DBUS_ASSERT_ERROR_IS_SET (error);
921 dbus_message_unref (reply);
922 return DBUS_UID_UNSET;
923 }
924
925 dbus_message_unref (reply);
926
927 return (unsigned long) uid;
928}
929
948char*
949dbus_bus_get_id (DBusConnection *connection,
950 DBusError *error)
951{
952 DBusMessage *message, *reply;
953 char *id;
954 const char *v_STRING;
955
956 _dbus_return_val_if_fail (connection != NULL, NULL);
957 _dbus_return_val_if_error_is_set (error, NULL);
958
959 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
960 DBUS_PATH_DBUS,
961 DBUS_INTERFACE_DBUS,
962 "GetId");
963
964 if (message == NULL)
965 {
966 _DBUS_SET_OOM (error);
967 return NULL;
968 }
969
970 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
971 error);
972
973 dbus_message_unref (message);
974
975 if (reply == NULL)
976 {
977 _DBUS_ASSERT_ERROR_IS_SET (error);
978 return NULL;
979 }
980
981 if (dbus_set_error_from_message (error, reply))
982 {
983 _DBUS_ASSERT_ERROR_IS_SET (error);
984 dbus_message_unref (reply);
985 return NULL;
986 }
987
988 v_STRING = NULL;
989 if (!dbus_message_get_args (reply, error,
990 DBUS_TYPE_STRING, &v_STRING,
991 DBUS_TYPE_INVALID))
992 {
993 _DBUS_ASSERT_ERROR_IS_SET (error);
994 dbus_message_unref (reply);
995 return NULL;
996 }
997
998 id = _dbus_strdup (v_STRING); /* may be NULL */
999
1000 dbus_message_unref (reply);
1001
1002 if (id == NULL)
1003 _DBUS_SET_OOM (error);
1004
1005 /* FIXME it might be nice to cache the ID locally */
1006
1007 return id;
1008}
1009
1112int
1113dbus_bus_request_name (DBusConnection *connection,
1114 const char *name,
1115 unsigned int flags,
1116 DBusError *error)
1117{
1118 DBusMessage *message, *reply;
1119 dbus_uint32_t result;
1120
1121 _dbus_return_val_if_fail (connection != NULL, 0);
1122 _dbus_return_val_if_fail (name != NULL, 0);
1123 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1124 _dbus_return_val_if_error_is_set (error, 0);
1125
1126 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1127 DBUS_PATH_DBUS,
1128 DBUS_INTERFACE_DBUS,
1129 "RequestName");
1130
1131 if (message == NULL)
1132 {
1133 _DBUS_SET_OOM (error);
1134 return -1;
1135 }
1136
1137 if (!dbus_message_append_args (message,
1138 DBUS_TYPE_STRING, &name,
1139 DBUS_TYPE_UINT32, &flags,
1140 DBUS_TYPE_INVALID))
1141 {
1142 dbus_message_unref (message);
1143 _DBUS_SET_OOM (error);
1144 return -1;
1145 }
1146
1147 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1148 error);
1149
1150 dbus_message_unref (message);
1151
1152 if (reply == NULL)
1153 {
1154 _DBUS_ASSERT_ERROR_IS_SET (error);
1155 return -1;
1156 }
1157
1158 if (dbus_set_error_from_message (error, reply))
1159 {
1160 _DBUS_ASSERT_ERROR_IS_SET (error);
1161 dbus_message_unref (reply);
1162 return -1;
1163 }
1164
1165 if (!dbus_message_get_args (reply, error,
1166 DBUS_TYPE_UINT32, &result,
1167 DBUS_TYPE_INVALID))
1168 {
1169 _DBUS_ASSERT_ERROR_IS_SET (error);
1170 dbus_message_unref (reply);
1171 return -1;
1172 }
1173
1174 dbus_message_unref (reply);
1175
1176 return result;
1177}
1178
1179
1198int
1199dbus_bus_release_name (DBusConnection *connection,
1200 const char *name,
1201 DBusError *error)
1202{
1203 DBusMessage *message, *reply;
1204 dbus_uint32_t result;
1205
1206 _dbus_return_val_if_fail (connection != NULL, 0);
1207 _dbus_return_val_if_fail (name != NULL, 0);
1208 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), 0);
1209 _dbus_return_val_if_error_is_set (error, 0);
1210
1211 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1212 DBUS_PATH_DBUS,
1213 DBUS_INTERFACE_DBUS,
1214 "ReleaseName");
1215
1216 if (message == NULL)
1217 {
1218 _DBUS_SET_OOM (error);
1219 return -1;
1220 }
1221
1222 if (!dbus_message_append_args (message,
1223 DBUS_TYPE_STRING, &name,
1224 DBUS_TYPE_INVALID))
1225 {
1226 dbus_message_unref (message);
1227 _DBUS_SET_OOM (error);
1228 return -1;
1229 }
1230
1231 reply = dbus_connection_send_with_reply_and_block (connection, message, -1,
1232 error);
1233
1234 dbus_message_unref (message);
1235
1236 if (reply == NULL)
1237 {
1238 _DBUS_ASSERT_ERROR_IS_SET (error);
1239 return -1;
1240 }
1241
1242 if (dbus_set_error_from_message (error, reply))
1243 {
1244 _DBUS_ASSERT_ERROR_IS_SET (error);
1245 dbus_message_unref (reply);
1246 return -1;
1247 }
1248
1249 if (!dbus_message_get_args (reply, error,
1250 DBUS_TYPE_UINT32, &result,
1251 DBUS_TYPE_INVALID))
1252 {
1253 _DBUS_ASSERT_ERROR_IS_SET (error);
1254 dbus_message_unref (reply);
1255 return -1;
1256 }
1257
1258 dbus_message_unref (reply);
1259
1260 return result;
1261}
1262
1280dbus_bool_t
1281dbus_bus_name_has_owner (DBusConnection *connection,
1282 const char *name,
1283 DBusError *error)
1284{
1285 DBusMessage *message, *reply;
1286 dbus_bool_t exists;
1287
1288 _dbus_return_val_if_fail (connection != NULL, FALSE);
1289 _dbus_return_val_if_fail (name != NULL, FALSE);
1290 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1291 _dbus_return_val_if_error_is_set (error, FALSE);
1292
1293 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1294 DBUS_PATH_DBUS,
1295 DBUS_INTERFACE_DBUS,
1296 "NameHasOwner");
1297 if (message == NULL)
1298 {
1299 _DBUS_SET_OOM (error);
1300 return FALSE;
1301 }
1302
1303 if (!dbus_message_append_args (message,
1304 DBUS_TYPE_STRING, &name,
1305 DBUS_TYPE_INVALID))
1306 {
1307 dbus_message_unref (message);
1308 _DBUS_SET_OOM (error);
1309 return FALSE;
1310 }
1311
1312 reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error);
1313 dbus_message_unref (message);
1314
1315 if (reply == NULL)
1316 {
1317 _DBUS_ASSERT_ERROR_IS_SET (error);
1318 return FALSE;
1319 }
1320
1321 if (!dbus_message_get_args (reply, error,
1322 DBUS_TYPE_BOOLEAN, &exists,
1323 DBUS_TYPE_INVALID))
1324 {
1325 _DBUS_ASSERT_ERROR_IS_SET (error);
1326 dbus_message_unref (reply);
1327 return FALSE;
1328 }
1329
1330 dbus_message_unref (reply);
1331 return exists;
1332}
1333
1356dbus_bool_t
1357dbus_bus_start_service_by_name (DBusConnection *connection,
1358 const char *name,
1359 dbus_uint32_t flags,
1360 dbus_uint32_t *result,
1361 DBusError *error)
1362{
1363 DBusMessage *msg;
1364 DBusMessage *reply;
1365
1366 _dbus_return_val_if_fail (connection != NULL, FALSE);
1367 _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE);
1368
1369 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1370 DBUS_PATH_DBUS,
1371 DBUS_INTERFACE_DBUS,
1372 "StartServiceByName");
1373
1374 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
1375 DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
1376 {
1377 dbus_message_unref (msg);
1378 _DBUS_SET_OOM (error);
1379 return FALSE;
1380 }
1381
1382 reply = dbus_connection_send_with_reply_and_block (connection, msg,
1383 -1, error);
1384 dbus_message_unref (msg);
1385
1386 if (reply == NULL)
1387 {
1388 _DBUS_ASSERT_ERROR_IS_SET (error);
1389 return FALSE;
1390 }
1391
1392 if (dbus_set_error_from_message (error, reply))
1393 {
1394 _DBUS_ASSERT_ERROR_IS_SET (error);
1395 dbus_message_unref (reply);
1396 return FALSE;
1397 }
1398
1399 if (result != NULL &&
1400 !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32,
1401 result, DBUS_TYPE_INVALID))
1402 {
1403 _DBUS_ASSERT_ERROR_IS_SET (error);
1404 dbus_message_unref (reply);
1405 return FALSE;
1406 }
1407
1408 dbus_message_unref (reply);
1409 return TRUE;
1410}
1411
1412static void
1413send_no_return_values (DBusConnection *connection,
1414 DBusMessage *msg,
1415 DBusError *error)
1416{
1417 if (error)
1418 {
1419 /* Block to check success codepath */
1420 DBusMessage *reply;
1421
1422 reply = dbus_connection_send_with_reply_and_block (connection, msg,
1423 -1, error);
1424
1425 if (reply == NULL)
1426 _DBUS_ASSERT_ERROR_IS_SET (error);
1427 else
1428 dbus_message_unref (reply);
1429 }
1430 else
1431 {
1432 /* Silently-fail nonblocking codepath */
1433 dbus_message_set_no_reply (msg, TRUE);
1434 dbus_connection_send (connection, msg, NULL);
1435 }
1436}
1437
1526void
1527dbus_bus_add_match (DBusConnection *connection,
1528 const char *rule,
1529 DBusError *error)
1530{
1531 DBusMessage *msg;
1532
1533 _dbus_return_if_fail (rule != NULL);
1534
1535 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1536 DBUS_PATH_DBUS,
1537 DBUS_INTERFACE_DBUS,
1538 "AddMatch");
1539
1540 if (msg == NULL)
1541 {
1542 _DBUS_SET_OOM (error);
1543 return;
1544 }
1545
1546 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1547 DBUS_TYPE_INVALID))
1548 {
1549 dbus_message_unref (msg);
1550 _DBUS_SET_OOM (error);
1551 return;
1552 }
1553
1554 send_no_return_values (connection, msg, error);
1555
1556 dbus_message_unref (msg);
1557}
1558
1576void
1577dbus_bus_remove_match (DBusConnection *connection,
1578 const char *rule,
1579 DBusError *error)
1580{
1581 DBusMessage *msg;
1582
1583 _dbus_return_if_fail (rule != NULL);
1584
1585 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1586 DBUS_PATH_DBUS,
1587 DBUS_INTERFACE_DBUS,
1588 "RemoveMatch");
1589
1590 if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &rule,
1591 DBUS_TYPE_INVALID))
1592 {
1593 dbus_message_unref (msg);
1594 _DBUS_SET_OOM (error);
1595 return;
1596 }
1597
1598 send_no_return_values (connection, msg, error);
1599
1600 dbus_message_unref (msg);
1601}
1602
_dbus_bus_notify_shared_connection_disconnected_unlocked
void _dbus_bus_notify_shared_connection_disconnected_unlocked(DBusConnection *connection)
Internal function that checks to see if this is a shared connection owned by the bus and if it is unr...
Definition dbus-bus.c:388
N_BUS_TYPES
#define N_BUS_TYPES
Number of bus types.
Definition dbus-bus.c:91
dbus_bus_set_unique_name
dbus_bool_t dbus_bus_set_unique_name(DBusConnection *connection, const char *unique_name)
Sets the unique name of the connection, as assigned by the message bus.
Definition dbus-bus.c:767
dbus_bus_register
dbus_bool_t dbus_bus_register(DBusConnection *connection, DBusError *error)
Registers a connection with the bus.
Definition dbus-bus.c:647
dbus_bus_get_id
char * dbus_bus_get_id(DBusConnection *connection, DBusError *error)
Asks the bus to return its globally unique ID, as described in the D-Bus specification.
Definition dbus-bus.c:949
dbus_bus_get_unix_user
unsigned long dbus_bus_get_unix_user(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus to return the UID the named connection authenticated as, if any.
Definition dbus-bus.c:866
dbus_bus_add_match
void dbus_bus_add_match(DBusConnection *connection, const char *rule, DBusError *error)
Adds a match rule to match messages going through the message bus.
Definition dbus-bus.c:1527
dbus_bus_name_has_owner
dbus_bool_t dbus_bus_name_has_owner(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus whether a certain name has an owner.
Definition dbus-bus.c:1281
dbus_bus_remove_match
void dbus_bus_remove_match(DBusConnection *connection, const char *rule, DBusError *error)
Removes a previously-added match rule "by value" (the most recently-added identical rule gets removed...
Definition dbus-bus.c:1577
dbus_bus_get
DBusConnection * dbus_bus_get(DBusBusType type, DBusError *error)
Connects to a bus daemon and registers the client with it.
Definition dbus-bus.c:559
dbus_bus_start_service_by_name
dbus_bool_t dbus_bus_start_service_by_name(DBusConnection *connection, const char *name, dbus_uint32_t flags, dbus_uint32_t *result, DBusError *error)
Starts a service that will request ownership of the given name.
Definition dbus-bus.c:1357
dbus_bus_request_name
int dbus_bus_request_name(DBusConnection *connection, const char *name, unsigned int flags, DBusError *error)
Asks the bus to assign the given name to this connection by invoking the RequestName method on the bu...
Definition dbus-bus.c:1113
dbus_bus_get_unique_name
const char * dbus_bus_get_unique_name(DBusConnection *connection)
Gets the unique name of the connection as assigned by the message bus.
Definition dbus-bus.c:816
dbus_bus_get_private
DBusConnection * dbus_bus_get_private(DBusBusType type, DBusError *error)
Connects to a bus daemon and registers the client with it as with dbus_bus_register().
Definition dbus-bus.c:591
dbus_bus_release_name
int dbus_bus_release_name(DBusConnection *connection, const char *name, DBusError *error)
Asks the bus to unassign the given name from this connection by invoking the ReleaseName method on th...
Definition dbus-bus.c:1199
_dbus_connection_close_possibly_shared
void _dbus_connection_close_possibly_shared(DBusConnection *connection)
Closes a shared OR private connection, while dbus_connection_close() can only be used on private conn...
Definition dbus-connection.c:1960
dbus_connection_set_exit_on_disconnect
void dbus_connection_set_exit_on_disconnect(DBusConnection *connection, dbus_bool_t exit_on_disconnect)
Set whether _exit() should be called when the connection receives a disconnect signal.
Definition dbus-connection.c:3156
dbus_connection_get_data
void * dbus_connection_get_data(DBusConnection *connection, dbus_int32_t slot)
Retrieves data previously set with dbus_connection_set_data().
Definition dbus-connection.c:6139
dbus_connection_open_private
DBusConnection * dbus_connection_open_private(const char *address, DBusError *error)
Opens a new, dedicated connection to a remote address.
Definition dbus-connection.c:2674
dbus_connection_unref
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero.
Definition dbus-connection.c:2828
dbus_connection_allocate_data_slot
dbus_bool_t dbus_connection_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusConnection.
Definition dbus-connection.c:6042
dbus_connection_free_data_slot
void dbus_connection_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for connection data slots.
Definition dbus-connection.c:6060
dbus_connection_set_data
dbus_bool_t dbus_connection_set_data(DBusConnection *connection, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusConnection, along with an optional function to be used for freeing the data...
Definition dbus-connection.c:6090
dbus_connection_send_with_reply_and_block
DBusMessage * dbus_connection_send_with_reply_and_block(DBusConnection *connection, DBusMessage *message, int timeout_milliseconds, DBusError *error)
Sends a message and blocks a certain time period while waiting for a reply.
Definition dbus-connection.c:3546
dbus_connection_open
DBusConnection * dbus_connection_open(const char *address, DBusError *error)
Gets a connection to a remote address.
Definition dbus-connection.c:2631
dbus_connection_send
dbus_bool_t dbus_connection_send(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial)
Adds a message to the outgoing message queue.
Definition dbus-connection.c:3313
dbus_connection_ref
DBusConnection * dbus_connection_ref(DBusConnection *connection)
Increments the reference count of a DBusConnection.
Definition dbus-connection.c:2696
DBUS_ERROR_INIT
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition dbus-errors.h:62
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition dbus-errors.c:354
dbus_error_is_set
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition dbus-errors.c:329
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition dbus-internals.h:164
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition dbus-internals.h:153
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
Definition dbus-internals.h:422
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition dbus-internals.h:421
_dbus_warn_check_failed
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
Definition dbus-internals.c:270
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition dbus-internals.c:589
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition dbus-internals.c:238
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
Definition dbus-macros.h:49
TRUE
#define TRUE
Expands to "1".
Definition dbus-macros.h:39
FALSE
#define FALSE
Expands to "0".
Definition dbus-macros.h:42
_dbus_register_shutdown_func
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called.
Definition dbus-memory.c:801
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition dbus-memory.c:692
dbus_new0
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition dbus-memory.h:58
dbus_message_set_no_reply
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set,...
Definition dbus-message.c:3229
dbus_message_append_args
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
Definition dbus-message.c:1831
dbus_message_new_method_call
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *iface, const char *method)
Constructs a new message to invoke a method on a remote object.
Definition dbus-message.c:1366
dbus_message_unref
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0.
Definition dbus-message.c:1723
dbus_set_error_from_message
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
Definition dbus-message.c:4041
dbus_message_get_args
dbus_bool_t dbus_message_get_args(DBusMessage *message, DBusError *error, int first_arg_type,...)
Gets arguments from a message given a variable argument list.
Definition dbus-message.c:2020
DBUS_TYPE_BOOLEAN
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition dbus-protocol.h:70
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition dbus-protocol.h:102
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition dbus-protocol.h:60
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition dbus-protocol.h:359
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition dbus-protocol.h:86
DBUS_PATH_DBUS
#define DBUS_PATH_DBUS
The object path used to talk to the bus itself.
Definition dbus-shared.h:80
DBusBusType
DBusBusType
Well-known bus types.
Definition dbus-shared.h:57
DBUS_SERVICE_DBUS
#define DBUS_SERVICE_DBUS
The bus name used to talk to the bus itself.
Definition dbus-shared.h:76
DBUS_INTERFACE_DBUS
#define DBUS_INTERFACE_DBUS
The interface exported by the object with DBUS_SERVICE_DBUS and DBUS_PATH_DBUS.
Definition dbus-shared.h:88
DBUS_BUS_SESSION
@ DBUS_BUS_SESSION
The login session bus.
Definition dbus-shared.h:58
DBUS_BUS_STARTER
@ DBUS_BUS_STARTER
The bus that started us, if any.
Definition dbus-shared.h:60
DBUS_BUS_SYSTEM
@ DBUS_BUS_SYSTEM
The systemwide bus.
Definition dbus-shared.h:59
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition dbus-string.c:182
_dbus_string_steal_data
dbus_bool_t _dbus_string_steal_data(DBusString *str, char **data_return)
Like _dbus_string_get_data(), but removes the gotten data from the original string.
Definition dbus-string.c:672
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as _DBUS_STRING_IN...
Definition dbus-string.c:278
DBUS_UID_UNSET
#define DBUS_UID_UNSET
an invalid UID used to represent an uninitialized dbus_uid_t field
Definition dbus-sysdeps.h:144
_dbus_getenv
const char * _dbus_getenv(const char *varname)
Wrapper for getenv().
Definition dbus-sysdeps.c:195
_dbus_lookup_session_address
dbus_bool_t _dbus_lookup_session_address(dbus_bool_t *supported, DBusString *address, DBusError *error)
Determines the address of the session bus by querying a platform-specific method.
Definition dbus-sysdeps-unix.c:4513
BusData
Block of message-bus-related data we attach to each DBusConnection used with these convenience functi...
Definition dbus-bus.c:78
BusData::is_well_known
unsigned int is_well_known
Is one of the well-known connections in our global array.
Definition dbus-bus.c:82
BusData::connection
DBusConnection * connection
Connection we're associated with.
Definition dbus-bus.c:79
BusData::unique_name
char * unique_name
Unique name of this connection.
Definition dbus-bus.c:80
DBusConnection
Implementation details of DBusConnection.
Definition dbus-connection.c:257
DBusError
Object representing an exception.
Definition dbus-errors.h:49
DBusError::message
const char * message
public error message field
Definition dbus-errors.h:51
DBusMessage
Internals of DBusMessage.
Definition dbus-message-private.h:100
DBusString
Definition dbus-string.h:43