00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-server.h"
00026 #include "dbus-server-unix.h"
00027 #include "dbus-server-socket.h"
00028 #include "dbus-string.h"
00029 #ifdef DBUS_BUILD_TESTS
00030 #include "dbus-server-debug-pipe.h"
00031 #endif
00032 #include "dbus-address.h"
00033 #include "dbus-protocol.h"
00034
00056
00057
00058
00059 static char*
00060 copy_address_with_guid_appended (const DBusString *address,
00061 const DBusString *guid_hex)
00062 {
00063 DBusString with_guid;
00064 char *retval;
00065
00066 if (!_dbus_string_init (&with_guid))
00067 return NULL;
00068
00069 if (!_dbus_string_copy (address, 0, &with_guid,
00070 _dbus_string_get_length (&with_guid)) ||
00071 !_dbus_string_append (&with_guid, ",guid=") ||
00072 !_dbus_string_copy (guid_hex, 0,
00073 &with_guid, _dbus_string_get_length (&with_guid)))
00074 {
00075 _dbus_string_free (&with_guid);
00076 return NULL;
00077 }
00078
00079 retval = NULL;
00080 _dbus_string_steal_data (&with_guid, &retval);
00081
00082 _dbus_string_free (&with_guid);
00083
00084 return retval;
00085 }
00086
00096 dbus_bool_t
00097 _dbus_server_init_base (DBusServer *server,
00098 const DBusServerVTable *vtable,
00099 const DBusString *address)
00100 {
00101 server->vtable = vtable;
00102 server->refcount.value = 1;
00103
00104 server->address = NULL;
00105 server->watches = NULL;
00106 server->timeouts = NULL;
00107 server->published_address = FALSE;
00108
00109 if (!_dbus_string_init (&server->guid_hex))
00110 return FALSE;
00111
00112 _dbus_generate_uuid (&server->guid);
00113
00114 if (!_dbus_uuid_encode (&server->guid, &server->guid_hex))
00115 goto failed;
00116
00117 server->address = copy_address_with_guid_appended (address,
00118 &server->guid_hex);
00119 if (server->address == NULL)
00120 goto failed;
00121
00122 _dbus_mutex_new_at_location (&server->mutex);
00123 if (server->mutex == NULL)
00124 goto failed;
00125
00126 server->watches = _dbus_watch_list_new ();
00127 if (server->watches == NULL)
00128 goto failed;
00129
00130 server->timeouts = _dbus_timeout_list_new ();
00131 if (server->timeouts == NULL)
00132 goto failed;
00133
00134 _dbus_data_slot_list_init (&server->slot_list);
00135
00136 _dbus_verbose ("Initialized server on address %s\n", server->address);
00137
00138 return TRUE;
00139
00140 failed:
00141 _dbus_mutex_free_at_location (&server->mutex);
00142 server->mutex = NULL;
00143 if (server->watches)
00144 {
00145 _dbus_watch_list_free (server->watches);
00146 server->watches = NULL;
00147 }
00148 if (server->timeouts)
00149 {
00150 _dbus_timeout_list_free (server->timeouts);
00151 server->timeouts = NULL;
00152 }
00153 if (server->address)
00154 {
00155 dbus_free (server->address);
00156 server->address = NULL;
00157 }
00158 _dbus_string_free (&server->guid_hex);
00159
00160 return FALSE;
00161 }
00162
00169 void
00170 _dbus_server_finalize_base (DBusServer *server)
00171 {
00172
00173
00174
00175 #ifndef DBUS_DISABLE_CHECKS
00176 _dbus_assert (!server->have_server_lock);
00177 #endif
00178 _dbus_assert (server->disconnected);
00179
00180
00181 _dbus_data_slot_list_free (&server->slot_list);
00182
00183 dbus_server_set_new_connection_function (server, NULL, NULL, NULL);
00184
00185 _dbus_watch_list_free (server->watches);
00186 _dbus_timeout_list_free (server->timeouts);
00187
00188 _dbus_mutex_free_at_location (&server->mutex);
00189
00190 dbus_free (server->address);
00191
00192 dbus_free_string_array (server->auth_mechanisms);
00193
00194 _dbus_string_free (&server->guid_hex);
00195 }
00196
00197
00199 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00200 DBusWatch *watch);
00202 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00203 DBusWatch *watch);
00205 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00206 DBusWatch *watch,
00207 dbus_bool_t enabled);
00208
00209 static dbus_bool_t
00210 protected_change_watch (DBusServer *server,
00211 DBusWatch *watch,
00212 DBusWatchAddFunction add_function,
00213 DBusWatchRemoveFunction remove_function,
00214 DBusWatchToggleFunction toggle_function,
00215 dbus_bool_t enabled)
00216 {
00217 DBusWatchList *watches;
00218 dbus_bool_t retval;
00219
00220 HAVE_LOCK_CHECK (server);
00221
00222
00223
00224
00225
00226
00227 watches = server->watches;
00228 if (watches)
00229 {
00230 server->watches = NULL;
00231 _dbus_server_ref_unlocked (server);
00232 SERVER_UNLOCK (server);
00233
00234 if (add_function)
00235 retval = (* add_function) (watches, watch);
00236 else if (remove_function)
00237 {
00238 retval = TRUE;
00239 (* remove_function) (watches, watch);
00240 }
00241 else
00242 {
00243 retval = TRUE;
00244 (* toggle_function) (watches, watch, enabled);
00245 }
00246
00247 SERVER_LOCK (server);
00248 server->watches = watches;
00249 _dbus_server_unref_unlocked (server);
00250
00251 return retval;
00252 }
00253 else
00254 return FALSE;
00255 }
00256
00264 dbus_bool_t
00265 _dbus_server_add_watch (DBusServer *server,
00266 DBusWatch *watch)
00267 {
00268 HAVE_LOCK_CHECK (server);
00269 return protected_change_watch (server, watch,
00270 _dbus_watch_list_add_watch,
00271 NULL, NULL, FALSE);
00272 }
00273
00280 void
00281 _dbus_server_remove_watch (DBusServer *server,
00282 DBusWatch *watch)
00283 {
00284 HAVE_LOCK_CHECK (server);
00285 protected_change_watch (server, watch,
00286 NULL,
00287 _dbus_watch_list_remove_watch,
00288 NULL, FALSE);
00289 }
00290
00298 void
00299 _dbus_server_toggle_all_watches (DBusServer *server,
00300 dbus_bool_t enabled)
00301 {
00302 _dbus_watch_list_toggle_all_watches (server->watches, enabled);
00303 }
00304
00306 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00307 DBusTimeout *timeout);
00309 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00310 DBusTimeout *timeout);
00312 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00313 DBusTimeout *timeout,
00314 dbus_bool_t enabled);
00315
00316
00317 static dbus_bool_t
00318 protected_change_timeout (DBusServer *server,
00319 DBusTimeout *timeout,
00320 DBusTimeoutAddFunction add_function,
00321 DBusTimeoutRemoveFunction remove_function,
00322 DBusTimeoutToggleFunction toggle_function,
00323 dbus_bool_t enabled)
00324 {
00325 DBusTimeoutList *timeouts;
00326 dbus_bool_t retval;
00327
00328 HAVE_LOCK_CHECK (server);
00329
00330
00331
00332
00333
00334 timeouts = server->timeouts;
00335 if (timeouts)
00336 {
00337 server->timeouts = NULL;
00338 _dbus_server_ref_unlocked (server);
00339 SERVER_UNLOCK (server);
00340
00341 if (add_function)
00342 retval = (* add_function) (timeouts, timeout);
00343 else if (remove_function)
00344 {
00345 retval = TRUE;
00346 (* remove_function) (timeouts, timeout);
00347 }
00348 else
00349 {
00350 retval = TRUE;
00351 (* toggle_function) (timeouts, timeout, enabled);
00352 }
00353
00354 SERVER_LOCK (server);
00355 server->timeouts = timeouts;
00356 _dbus_server_unref_unlocked (server);
00357
00358 return retval;
00359 }
00360 else
00361 return FALSE;
00362 }
00363
00373 dbus_bool_t
00374 _dbus_server_add_timeout (DBusServer *server,
00375 DBusTimeout *timeout)
00376 {
00377 return protected_change_timeout (server, timeout,
00378 _dbus_timeout_list_add_timeout,
00379 NULL, NULL, FALSE);
00380 }
00381
00388 void
00389 _dbus_server_remove_timeout (DBusServer *server,
00390 DBusTimeout *timeout)
00391 {
00392 protected_change_timeout (server, timeout,
00393 NULL,
00394 _dbus_timeout_list_remove_timeout,
00395 NULL, FALSE);
00396 }
00397
00407 void
00408 _dbus_server_toggle_timeout (DBusServer *server,
00409 DBusTimeout *timeout,
00410 dbus_bool_t enabled)
00411 {
00412 protected_change_timeout (server, timeout,
00413 NULL, NULL,
00414 _dbus_timeout_list_toggle_timeout,
00415 enabled);
00416 }
00417
00418
00424 void
00425 _dbus_server_ref_unlocked (DBusServer *server)
00426 {
00427 _dbus_assert (server != NULL);
00428 _dbus_assert (server->refcount.value > 0);
00429
00430 HAVE_LOCK_CHECK (server);
00431
00432 #ifdef DBUS_HAVE_ATOMIC_INT
00433 _dbus_atomic_inc (&server->refcount);
00434 #else
00435 _dbus_assert (server->refcount.value > 0);
00436
00437 server->refcount.value += 1;
00438 #endif
00439 }
00440
00446 void
00447 _dbus_server_unref_unlocked (DBusServer *server)
00448 {
00449 dbus_bool_t last_unref;
00450
00451
00452
00453 _dbus_assert (server != NULL);
00454 _dbus_assert (server->refcount.value > 0);
00455
00456 HAVE_LOCK_CHECK (server);
00457
00458 #ifdef DBUS_HAVE_ATOMIC_INT
00459 last_unref = (_dbus_atomic_dec (&server->refcount) == 1);
00460 #else
00461 _dbus_assert (server->refcount.value > 0);
00462
00463 server->refcount.value -= 1;
00464 last_unref = (server->refcount.value == 0);
00465 #endif
00466
00467 if (last_unref)
00468 {
00469 _dbus_assert (server->disconnected);
00470
00471 SERVER_UNLOCK (server);
00472
00473 _dbus_assert (server->vtable->finalize != NULL);
00474
00475 (* server->vtable->finalize) (server);
00476 }
00477 }
00478
00500 static const struct {
00501 DBusServerListenResult (* func) (DBusAddressEntry *entry,
00502 DBusServer **server_p,
00503 DBusError *error);
00504 } listen_funcs[] = {
00505 { _dbus_server_listen_socket }
00506 , { _dbus_server_listen_platform_specific }
00507 #ifdef DBUS_BUILD_TESTS
00508 , { _dbus_server_listen_debug_pipe }
00509 #endif
00510 };
00511
00532 DBusServer*
00533 dbus_server_listen (const char *address,
00534 DBusError *error)
00535 {
00536 DBusServer *server;
00537 DBusAddressEntry **entries;
00538 int len, i;
00539 DBusError first_connect_error = DBUS_ERROR_INIT;
00540 dbus_bool_t handled_once;
00541
00542 _dbus_return_val_if_fail (address != NULL, NULL);
00543 _dbus_return_val_if_error_is_set (error, NULL);
00544
00545 if (!dbus_parse_address (address, &entries, &len, error))
00546 return NULL;
00547
00548 server = NULL;
00549 handled_once = FALSE;
00550
00551 for (i = 0; i < len; i++)
00552 {
00553 int j;
00554
00555 for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j)
00556 {
00557 DBusServerListenResult result;
00558 DBusError tmp_error = DBUS_ERROR_INIT;
00559
00560 result = (* listen_funcs[j].func) (entries[i],
00561 &server,
00562 &tmp_error);
00563
00564 if (result == DBUS_SERVER_LISTEN_OK)
00565 {
00566 _dbus_assert (server != NULL);
00567 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00568 handled_once = TRUE;
00569 goto out;
00570 }
00571 else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED)
00572 {
00573 _dbus_assert (server == NULL);
00574 dbus_set_error (error,
00575 DBUS_ERROR_ADDRESS_IN_USE,
00576 "Address '%s' already used",
00577 dbus_address_entry_get_method (entries[0]));
00578 handled_once = TRUE;
00579 goto out;
00580 }
00581 else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS)
00582 {
00583 _dbus_assert (server == NULL);
00584 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00585 dbus_move_error (&tmp_error, error);
00586 handled_once = TRUE;
00587 goto out;
00588 }
00589 else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED)
00590 {
00591 _dbus_assert (server == NULL);
00592 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
00593
00594
00595 }
00596 else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT)
00597 {
00598 _dbus_assert (server == NULL);
00599 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
00600 if (!dbus_error_is_set (&first_connect_error))
00601 dbus_move_error (&tmp_error, &first_connect_error);
00602 else
00603 dbus_error_free (&tmp_error);
00604
00605 handled_once = TRUE;
00606
00607
00608 }
00609 }
00610
00611 _dbus_assert (server == NULL);
00612 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00613 }
00614
00615 out:
00616
00617 if (!handled_once)
00618 {
00619 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00620 if (len > 0)
00621 dbus_set_error (error,
00622 DBUS_ERROR_BAD_ADDRESS,
00623 "Unknown address type '%s'",
00624 dbus_address_entry_get_method (entries[0]));
00625 else
00626 dbus_set_error (error,
00627 DBUS_ERROR_BAD_ADDRESS,
00628 "Empty address '%s'",
00629 address);
00630 }
00631
00632 dbus_address_entries_free (entries);
00633
00634 if (server == NULL)
00635 {
00636 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) ||
00637 dbus_error_is_set (error));
00638
00639 if (error && dbus_error_is_set (error))
00640 {
00641
00642 }
00643 else
00644 {
00645
00646
00647
00648 _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error));
00649 dbus_move_error (&first_connect_error, error);
00650 }
00651
00652 _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error);
00653 _DBUS_ASSERT_ERROR_IS_SET (error);
00654
00655 return NULL;
00656 }
00657 else
00658 {
00659 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00660 return server;
00661 }
00662 }
00663
00670 DBusServer *
00671 dbus_server_ref (DBusServer *server)
00672 {
00673 _dbus_return_val_if_fail (server != NULL, NULL);
00674 _dbus_return_val_if_fail (server->refcount.value > 0, NULL);
00675
00676 #ifdef DBUS_HAVE_ATOMIC_INT
00677 _dbus_atomic_inc (&server->refcount);
00678 #else
00679 SERVER_LOCK (server);
00680 _dbus_assert (server->refcount.value > 0);
00681
00682 server->refcount.value += 1;
00683 SERVER_UNLOCK (server);
00684 #endif
00685
00686 return server;
00687 }
00688
00697 void
00698 dbus_server_unref (DBusServer *server)
00699 {
00700 dbus_bool_t last_unref;
00701
00702
00703
00704 _dbus_return_if_fail (server != NULL);
00705 _dbus_return_if_fail (server->refcount.value > 0);
00706
00707 #ifdef DBUS_HAVE_ATOMIC_INT
00708 last_unref = (_dbus_atomic_dec (&server->refcount) == 1);
00709 #else
00710 SERVER_LOCK (server);
00711
00712 _dbus_assert (server->refcount.value > 0);
00713
00714 server->refcount.value -= 1;
00715 last_unref = (server->refcount.value == 0);
00716
00717 SERVER_UNLOCK (server);
00718 #endif
00719
00720 if (last_unref)
00721 {
00722
00723 _dbus_assert (server->disconnected);
00724
00725 _dbus_assert (server->vtable->finalize != NULL);
00726
00727 (* server->vtable->finalize) (server);
00728 }
00729 }
00730
00739 void
00740 dbus_server_disconnect (DBusServer *server)
00741 {
00742 _dbus_return_if_fail (server != NULL);
00743 _dbus_return_if_fail (server->refcount.value > 0);
00744
00745 SERVER_LOCK (server);
00746 _dbus_server_ref_unlocked (server);
00747
00748 _dbus_assert (server->vtable->disconnect != NULL);
00749
00750 if (!server->disconnected)
00751 {
00752
00753 server->disconnected = TRUE;
00754
00755 (* server->vtable->disconnect) (server);
00756 }
00757
00758 SERVER_UNLOCK (server);
00759 dbus_server_unref (server);
00760 }
00761
00767 dbus_bool_t
00768 dbus_server_get_is_connected (DBusServer *server)
00769 {
00770 dbus_bool_t retval;
00771
00772 _dbus_return_val_if_fail (server != NULL, FALSE);
00773
00774 SERVER_LOCK (server);
00775 retval = !server->disconnected;
00776 SERVER_UNLOCK (server);
00777
00778 return retval;
00779 }
00780
00788 char*
00789 dbus_server_get_address (DBusServer *server)
00790 {
00791 char *retval;
00792
00793 _dbus_return_val_if_fail (server != NULL, NULL);
00794
00795 SERVER_LOCK (server);
00796 retval = _dbus_strdup (server->address);
00797 SERVER_UNLOCK (server);
00798
00799 return retval;
00800 }
00801
00824 char*
00825 dbus_server_get_id (DBusServer *server)
00826 {
00827 char *retval;
00828
00829 _dbus_return_val_if_fail (server != NULL, NULL);
00830
00831 SERVER_LOCK (server);
00832 retval = NULL;
00833 _dbus_string_copy_data (&server->guid_hex, &retval);
00834 SERVER_UNLOCK (server);
00835
00836 return retval;
00837 }
00838
00859 void
00860 dbus_server_set_new_connection_function (DBusServer *server,
00861 DBusNewConnectionFunction function,
00862 void *data,
00863 DBusFreeFunction free_data_function)
00864 {
00865 DBusFreeFunction old_free_function;
00866 void *old_data;
00867
00868 _dbus_return_if_fail (server != NULL);
00869
00870 SERVER_LOCK (server);
00871 old_free_function = server->new_connection_free_data_function;
00872 old_data = server->new_connection_data;
00873
00874 server->new_connection_function = function;
00875 server->new_connection_data = data;
00876 server->new_connection_free_data_function = free_data_function;
00877 SERVER_UNLOCK (server);
00878
00879 if (old_free_function != NULL)
00880 (* old_free_function) (old_data);
00881 }
00882
00899 dbus_bool_t
00900 dbus_server_set_watch_functions (DBusServer *server,
00901 DBusAddWatchFunction add_function,
00902 DBusRemoveWatchFunction remove_function,
00903 DBusWatchToggledFunction toggled_function,
00904 void *data,
00905 DBusFreeFunction free_data_function)
00906 {
00907 dbus_bool_t result;
00908 DBusWatchList *watches;
00909
00910 _dbus_return_val_if_fail (server != NULL, FALSE);
00911
00912 SERVER_LOCK (server);
00913 watches = server->watches;
00914 server->watches = NULL;
00915 if (watches)
00916 {
00917 SERVER_UNLOCK (server);
00918 result = _dbus_watch_list_set_functions (watches,
00919 add_function,
00920 remove_function,
00921 toggled_function,
00922 data,
00923 free_data_function);
00924 SERVER_LOCK (server);
00925 }
00926 else
00927 {
00928 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
00929 result = FALSE;
00930 }
00931 server->watches = watches;
00932 SERVER_UNLOCK (server);
00933
00934 return result;
00935 }
00936
00952 dbus_bool_t
00953 dbus_server_set_timeout_functions (DBusServer *server,
00954 DBusAddTimeoutFunction add_function,
00955 DBusRemoveTimeoutFunction remove_function,
00956 DBusTimeoutToggledFunction toggled_function,
00957 void *data,
00958 DBusFreeFunction free_data_function)
00959 {
00960 dbus_bool_t result;
00961 DBusTimeoutList *timeouts;
00962
00963 _dbus_return_val_if_fail (server != NULL, FALSE);
00964
00965 SERVER_LOCK (server);
00966 timeouts = server->timeouts;
00967 server->timeouts = NULL;
00968 if (timeouts)
00969 {
00970 SERVER_UNLOCK (server);
00971 result = _dbus_timeout_list_set_functions (timeouts,
00972 add_function,
00973 remove_function,
00974 toggled_function,
00975 data,
00976 free_data_function);
00977 SERVER_LOCK (server);
00978 }
00979 else
00980 {
00981 _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME);
00982 result = FALSE;
00983 }
00984 server->timeouts = timeouts;
00985 SERVER_UNLOCK (server);
00986
00987 return result;
00988 }
00989
01003 dbus_bool_t
01004 dbus_server_set_auth_mechanisms (DBusServer *server,
01005 const char **mechanisms)
01006 {
01007 char **copy;
01008
01009 _dbus_return_val_if_fail (server != NULL, FALSE);
01010
01011 SERVER_LOCK (server);
01012
01013 if (mechanisms != NULL)
01014 {
01015 copy = _dbus_dup_string_array (mechanisms);
01016 if (copy == NULL)
01017 return FALSE;
01018 }
01019 else
01020 copy = NULL;
01021
01022 dbus_free_string_array (server->auth_mechanisms);
01023 server->auth_mechanisms = copy;
01024
01025 SERVER_UNLOCK (server);
01026
01027 return TRUE;
01028 }
01029
01030
01031 static DBusDataSlotAllocator slot_allocator;
01032 _DBUS_DEFINE_GLOBAL_LOCK (server_slots);
01033
01048 dbus_bool_t
01049 dbus_server_allocate_data_slot (dbus_int32_t *slot_p)
01050 {
01051 return _dbus_data_slot_allocator_alloc (&slot_allocator,
01052 (DBusMutex **)&_DBUS_LOCK_NAME (server_slots),
01053 slot_p);
01054 }
01055
01067 void
01068 dbus_server_free_data_slot (dbus_int32_t *slot_p)
01069 {
01070 _dbus_return_if_fail (*slot_p >= 0);
01071
01072 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
01073 }
01074
01088 dbus_bool_t
01089 dbus_server_set_data (DBusServer *server,
01090 int slot,
01091 void *data,
01092 DBusFreeFunction free_data_func)
01093 {
01094 DBusFreeFunction old_free_func;
01095 void *old_data;
01096 dbus_bool_t retval;
01097
01098 _dbus_return_val_if_fail (server != NULL, FALSE);
01099
01100 SERVER_LOCK (server);
01101
01102 retval = _dbus_data_slot_list_set (&slot_allocator,
01103 &server->slot_list,
01104 slot, data, free_data_func,
01105 &old_free_func, &old_data);
01106
01107
01108 SERVER_UNLOCK (server);
01109
01110 if (retval)
01111 {
01112
01113 if (old_free_func)
01114 (* old_free_func) (old_data);
01115 }
01116
01117 return retval;
01118 }
01119
01128 void*
01129 dbus_server_get_data (DBusServer *server,
01130 int slot)
01131 {
01132 void *res;
01133
01134 _dbus_return_val_if_fail (server != NULL, NULL);
01135
01136 SERVER_LOCK (server);
01137
01138 res = _dbus_data_slot_list_get (&slot_allocator,
01139 &server->slot_list,
01140 slot);
01141
01142 SERVER_UNLOCK (server);
01143
01144 return res;
01145 }
01146
01149 #ifdef DBUS_BUILD_TESTS
01150 #include "dbus-test.h"
01151 #include <string.h>
01152
01153 dbus_bool_t
01154 _dbus_server_test (void)
01155 {
01156 const char *valid_addresses[] = {
01157 "tcp:port=1234",
01158 "tcp:host=localhost,port=1234",
01159 "tcp:host=localhost,port=1234;tcp:port=5678",
01160 #ifdef DBUS_UNIX
01161 "unix:path=./boogie",
01162 "tcp:port=1234;unix:path=./boogie",
01163 #endif
01164 };
01165
01166 DBusServer *server;
01167 int i;
01168
01169 for (i = 0; i < _DBUS_N_ELEMENTS (valid_addresses); i++)
01170 {
01171 DBusError error = DBUS_ERROR_INIT;
01172 char *address;
01173 char *id;
01174
01175 server = dbus_server_listen (valid_addresses[i], &error);
01176 if (server == NULL)
01177 {
01178 _dbus_warn ("server listen error: %s: %s\n", error.name, error.message);
01179 dbus_error_free (&error);
01180 _dbus_assert_not_reached ("Failed to listen for valid address.");
01181 }
01182
01183 id = dbus_server_get_id (server);
01184 _dbus_assert (id != NULL);
01185 address = dbus_server_get_address (server);
01186 _dbus_assert (address != NULL);
01187
01188 if (strstr (address, id) == NULL)
01189 {
01190 _dbus_warn ("server id '%s' is not in the server address '%s'\n",
01191 id, address);
01192 _dbus_assert_not_reached ("bad server id or address");
01193 }
01194
01195 dbus_free (id);
01196 dbus_free (address);
01197
01198 dbus_server_disconnect (server);
01199 dbus_server_unref (server);
01200 }
01201
01202 return TRUE;
01203 }
01204
01205 #endif