D-Bus: dbus-bus.c Source File

D-Bus 1.10.22

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