/** * Listens for new connections on the given address. If there are * multiple semicolon-separated address entries in the address, tries * each one and listens on the first one that works. * * Returns #NULL and sets error if listening fails for any reason. * Otherwise returns a new #DBusServer. * dbus_server_set_new_connection_function(), * dbus_server_set_watch_functions(), and * dbus_server_set_timeout_functions() should be called immediately to * render the server fully functional. * * To free the server, applications must call first * dbus_server_disconnect() and then dbus_server_unref(). * * @param address the address of this server. * @param error location to store reason for failure. * @returns a new #DBusServer, or #NULL on failure. * */ DBusServer* dbus_server_listen (const char *address, DBusError *error) { DBusServer *server; DBusAddressEntry **entries; int len, i; DBusError first_connect_error = DBUS_ERROR_INIT; dbus_bool_t handled_once; _dbus_return_val_if_fail (address != NULL, NULL); _dbus_return_val_if_error_is_set (error, NULL); if (!dbus_parse_address (address, &entries, &len, error)) return NULL; server = NULL; handled_once = FALSE; for (i = 0; i < len; i++) { int j; for (j = 0; j < (int) _DBUS_N_ELEMENTS (listen_funcs); ++j) { DBusServerListenResult result; DBusError tmp_error = DBUS_ERROR_INIT; result = (* listen_funcs[j].func) (entries[i], &server, &tmp_error); if (result == DBUS_SERVER_LISTEN_OK) { _dbus_assert (server != NULL); _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); handled_once = TRUE; goto out; } else if (result == DBUS_SERVER_LISTEN_ADDRESS_ALREADY_USED) { _dbus_assert (server == NULL); dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, "Address '%s' already used", dbus_address_entry_get_method (entries[0])); handled_once = TRUE; goto out; } else if (result == DBUS_SERVER_LISTEN_BAD_ADDRESS) { _dbus_assert (server == NULL); _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); dbus_move_error (&tmp_error, error); handled_once = TRUE; goto out; } else if (result == DBUS_SERVER_LISTEN_NOT_HANDLED) { _dbus_assert (server == NULL); _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); /* keep trying addresses */ } else if (result == DBUS_SERVER_LISTEN_DID_NOT_CONNECT) { _dbus_assert (server == NULL); _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); if (!dbus_error_is_set (&first_connect_error)) dbus_move_error (&tmp_error, &first_connect_error); else dbus_error_free (&tmp_error); handled_once = TRUE; /* keep trying addresses */ } } _dbus_assert (server == NULL); _DBUS_ASSERT_ERROR_IS_CLEAR (error); } out: if (!handled_once) { _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (len > 0) dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Unknown address type '%s'", dbus_address_entry_get_method (entries[0])); else dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS, "Empty address '%s'", address); } dbus_address_entries_free (entries); if (server == NULL) { _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error) || dbus_error_is_set (error)); if (error && dbus_error_is_set (error)) { /* already set the error */ } else { /* didn't set the error but either error should be * NULL or first_connect_error should be set. */ _dbus_assert (error == NULL || dbus_error_is_set (&first_connect_error)); dbus_move_error (&first_connect_error, error); } _DBUS_ASSERT_ERROR_IS_CLEAR (&first_connect_error); /* be sure we freed it */ _DBUS_ASSERT_ERROR_IS_SET (error); return NULL; } else { _DBUS_ASSERT_ERROR_IS_CLEAR (error); return server; } }
static dbus_bool_t init_locks (void) { int i; DBusMutex ***dynamic_global_locks; DBusMutex **global_locks[] = { #define LOCK_ADDR(name) (& _dbus_lock_##name) LOCK_ADDR (win_fds), LOCK_ADDR (sid_atom_cache), LOCK_ADDR (list), LOCK_ADDR (connection_slots), LOCK_ADDR (pending_call_slots), LOCK_ADDR (server_slots), LOCK_ADDR (message_slots), #if !DBUS_USE_SYNC LOCK_ADDR (atomic), #endif LOCK_ADDR (bus), LOCK_ADDR (bus_datas), LOCK_ADDR (shutdown_funcs), LOCK_ADDR (system_users), LOCK_ADDR (message_cache), LOCK_ADDR (shared_connections), LOCK_ADDR (machine_uuid) #undef LOCK_ADDR }; _dbus_assert (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); i = 0; dynamic_global_locks = dbus_new (DBusMutex**, _DBUS_N_GLOBAL_LOCKS); if (dynamic_global_locks == NULL) goto failed; while (i < _DBUS_N_ELEMENTS (global_locks)) { *global_locks[i] = _dbus_mutex_new (); if (*global_locks[i] == NULL) goto failed; dynamic_global_locks[i] = global_locks[i]; ++i; } if (!_dbus_register_shutdown_func (shutdown_global_locks, dynamic_global_locks)) goto failed; if (!init_uninitialized_locks ()) goto failed; return TRUE; failed: dbus_free (dynamic_global_locks); for (i = i - 1; i >= 0; i--) { _dbus_mutex_free (*global_locks[i]); *global_locks[i] = NULL; } return FALSE; }
/** * @ingroup DBusStringInternals * Unit test for DBusString. * * @todo Need to write tests for _dbus_string_copy() and * _dbus_string_move() moving to/from each of start/middle/end of a * string. Also need tests for _dbus_string_move_len () * * @returns #TRUE on success. */ dbus_bool_t _dbus_string_test (void) { DBusString str; DBusString other; int i, a, end; long v; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; /* Test shortening and setting length */ i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { int j; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); j = lens[i]; while (j > 0) { _dbus_assert (_dbus_string_get_length (&str) == j); if (j > 0) { _dbus_string_shorten (&str, 1); _dbus_assert (_dbus_string_get_length (&str) == (j - 1)); } --j; } _dbus_string_free (&str); ++i; } /* Test equality */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("oom"); _dbus_string_init_const (&other, "H"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1)); _dbus_string_init_const (&other, "Hello"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5)); _dbus_string_init_const (&other, "World"); _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11)); _dbus_string_free (&str); /* Test appending data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); i = 0; while (i < 10) { if (!_dbus_string_append (&str, "a")) _dbus_assert_not_reached ("failed to append string to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); if (!_dbus_string_append_byte (&str, 'b')) _dbus_assert_not_reached ("failed to append byte to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); ++i; } _dbus_string_free (&str); /* Check steal_data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_steal_data (&str, &s)) _dbus_assert_not_reached ("failed to steal data"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (((int)strlen (s)) == i); dbus_free (s); /* Check move */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_move (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 2); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_string_free (&other); /* Check copy */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_copy (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello World")); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello WorldHello World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check replace */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 0, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not replace"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 5, 1)) _dbus_assert_not_reached ("could not replace center space"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorld")); if (!_dbus_string_replace_len (&str, 1, 1, &other, _dbus_string_get_length (&other) - 1, 1)) _dbus_assert_not_reached ("could not replace end character"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); _dbus_string_free (&str); _dbus_string_free (&other); /* Different tests are provided because different behaviours are * implemented in _dbus_string_replace_len() in function of replacing and * replaced lengths */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_append (&other, "Foo String")) _dbus_assert_not_reached ("could not append to string"); a = _dbus_string_get_length (&other); if (!_dbus_string_replace_len (&str, 0, 6, &other, 4, 0)) _dbus_assert_not_reached ("could not replace 0 length"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 6); _dbus_assert (_dbus_string_equal_c_str (&other, "Foo Hello String")); if (!_dbus_string_replace_len (&str, 5, 6, &other, _dbus_string_get_length (&other), 0)) _dbus_assert_not_reached ("could not replace at the end"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); _dbus_assert (_dbus_string_equal_c_str (&other, "Foo Hello String World")); if (!_dbus_string_replace_len (&str, 0, 5, &other, _dbus_string_get_length (&other) - 5, 5)) _dbus_assert_not_reached ("could not replace same length"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 6 + 6); _dbus_assert (_dbus_string_equal_c_str (&other, "Foo Hello String Hello")); if (!_dbus_string_replace_len (&str, 6, 5, &other, 4, 12)) _dbus_assert_not_reached ("could not replace with shorter string"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 5); _dbus_assert (_dbus_string_equal_c_str (&other, "Foo World Hello")); if (!_dbus_string_replace_len (&str, 0, 1, &other, 0, 3)) _dbus_assert_not_reached ("could not replace at the beginning"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 3); _dbus_assert (_dbus_string_equal_c_str (&other, "H World Hello")); if (!_dbus_string_replace_len (&str, 6, 5, &other, _dbus_string_get_length (&other) - 5, 5)) _dbus_assert_not_reached ("could not replace same length"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == a + 3); _dbus_assert (_dbus_string_equal_c_str (&other, "H World World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check insert/set/get byte */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("failed to append Hello"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o'); _dbus_string_set_byte (&str, 1, 'q'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q'); if (!_dbus_string_insert_bytes (&str, 0, 1, 255)) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) _dbus_assert_not_reached ("can't insert byte"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 255); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q'); _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o'); _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W'); _dbus_string_free (&str); /* Check append/parse int/double */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_int (&str, 27)) _dbus_assert_not_reached ("failed to append int"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_int (&str, 0, &v, &end)) _dbus_assert_not_reached ("failed to parse int"); _dbus_assert (v == 27); _dbus_assert (end == i); _dbus_string_free (&str); /* Test find */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("couldn't append to string"); if (!_dbus_string_find (&str, 0, "He", &i)) _dbus_assert_not_reached ("didn't find 'He'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "Hello", &i)) _dbus_assert_not_reached ("didn't find 'Hello'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "ello", &i)) _dbus_assert_not_reached ("didn't find 'ello'"); _dbus_assert (i == 1); if (!_dbus_string_find (&str, 0, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (!_dbus_string_find (&str, 2, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (_dbus_string_find (&str, 4, "lo", &i)) _dbus_assert_not_reached ("did find 'lo'"); if (!_dbus_string_find (&str, 0, "l", &i)) _dbus_assert_not_reached ("didn't find 'l'"); _dbus_assert (i == 2); if (!_dbus_string_find (&str, 0, "H", &i)) _dbus_assert_not_reached ("didn't find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "", &i)) _dbus_assert_not_reached ("didn't find ''"); _dbus_assert (i == 0); if (_dbus_string_find (&str, 0, "Hello!", NULL)) _dbus_assert_not_reached ("Did find 'Hello!'"); if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) _dbus_assert_not_reached ("Did find 'Oh, Hello'"); if (_dbus_string_find (&str, 0, "ill", NULL)) _dbus_assert_not_reached ("Did find 'ill'"); if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) _dbus_assert_not_reached ("Didn't find 'He'"); if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) _dbus_assert_not_reached ("Did not find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) _dbus_assert_not_reached ("Did not find 'o'"); _dbus_assert (i == _dbus_string_get_length (&str) - 1); if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) _dbus_assert_not_reached ("Did find 'o'"); _dbus_assert (i == -1); if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) _dbus_assert_not_reached ("Did find 'e'"); _dbus_assert (i == -1); if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) _dbus_assert_not_reached ("Didn't find 'e'"); _dbus_assert (i == 1); _dbus_string_free (&str); /* Hex encoding */ _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) _dbus_assert_not_reached ("deccoded bogus hex string with no error"); _dbus_assert (end == 8); _dbus_string_free (&other); test_roundtrips (test_hex_roundtrip); _dbus_string_free (&str); { int found, found_len; _dbus_string_init_const (&str, "012\r\n567\n90"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) _dbus_assert_not_reached ("Did not find '\\r\\n'"); if (found != 3 || found_len != 2) _dbus_assert_not_reached ("invalid return values"); if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) _dbus_assert_not_reached ("Did not find '\\n'"); if (found != 8 || found_len != 1) _dbus_assert_not_reached ("invalid return values"); if (_dbus_string_find_eol (&str, 9, &found, &found_len)) _dbus_assert_not_reached ("Found not expected '\\n'"); else if (found != 11 || found_len != 0) _dbus_assert_not_reached ("invalid return values '\\n'"); found = -1; found_len = -1; _dbus_string_init_const (&str, ""); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found an eol in an empty string"); _dbus_assert (found == 0); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar"); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found eol in string that lacks one"); _dbus_assert (found == 6); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar\n"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("did not find eol in string that has one at end"); _dbus_assert (found == 6); _dbus_assert (found_len == 1); } { DBusString line; #define FIRST_LINE "this is a line" #define SECOND_LINE "this is a second line" /* third line is empty */ #define THIRD_LINE "" #define FOURTH_LINE "this is a fourth line" if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&line)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop first line"); _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop second line"); _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop third line"); _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop fourth line"); _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); _dbus_string_free (&str); _dbus_string_free (&line); } { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); for (i = 0; i < 10000; i++) if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_set_length (&str, 10)) _dbus_assert_not_reached ("failed to set length"); /* actually compact */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact after set_length"); /* peek inside to make sure it worked */ if (((DBusRealString *)&str)->allocated > 30) _dbus_assert_not_reached ("compacting string didn't do anything"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after compact"); /* compact nothing */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact 2nd time"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after 2nd compact"); /* and make sure it still works...*/ if (!_dbus_string_append (&str, "123456")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content after append"); /* after growing automatically, this should do nothing */ if (!_dbus_string_compact (&str, 20000)) _dbus_assert_not_reached ("failed to compact after grow"); /* but this one will do something */ if (!_dbus_string_compact (&str, 0)) _dbus_assert_not_reached ("failed to compact after grow"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content"); if (!_dbus_string_append (&str, "!@#$%")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) _dbus_assert_not_reached ("unexpected content"); _dbus_string_free (&str); } { const char two_strings[] = "one\ttwo"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, two_strings)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_split_on_byte (&str, '\t', &other)) _dbus_assert_not_reached ("no memory or delimiter not found"); if (strcmp (_dbus_string_get_data (&str), "one") != 0) _dbus_assert_not_reached ("left side after split on tab is wrong"); if (strcmp (_dbus_string_get_data (&other), "two") != 0) _dbus_assert_not_reached ("right side after split on tab is wrong"); _dbus_string_free (&str); _dbus_string_free (&other); } { const char upper_string[] = "TOUPPERSTRING"; const char lower_string[] = "toupperstring"; const char lower2_string[] = "toupperSTRING"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, upper_string)) _dbus_assert_not_reached ("no memory"); _dbus_string_tolower_ascii (&str, 0, _dbus_string_get_length(&str)); if (!_dbus_string_equal_c_str (&str, lower_string)) _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed"); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, upper_string)) _dbus_assert_not_reached ("no memory"); _dbus_string_tolower_ascii (&str, 0, 7); if (!_dbus_string_equal_c_str (&str, lower2_string)) _dbus_assert_not_reached ("_dbus_string_tolower_ascii failed in partial conversion"); _dbus_string_free (&str); } { const char lower_string[] = "toupperstring"; const char upper_string[] = "TOUPPERSTRING"; const char upper2_string[] = "TOUPPERstring"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, lower_string)) _dbus_assert_not_reached ("no memory"); _dbus_string_toupper_ascii (&str, 0, _dbus_string_get_length(&str)); if (!_dbus_string_equal_c_str (&str, upper_string)) _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed"); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, lower_string)) _dbus_assert_not_reached ("no memory"); _dbus_string_toupper_ascii (&str, 0, 7); if (!_dbus_string_equal_c_str (&str, upper2_string)) _dbus_assert_not_reached ("_dbus_string_toupper_ascii failed in partial conversion"); _dbus_string_free (&str); } return TRUE; }
static dbus_bool_t generate_wrong_length (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int lengths[] = { -42, -17, -16, -15, -9, -8, -7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 30 }; int adjust; int len_seq; restart: len_seq = iter_get_sequence (iter); if (len_seq == _DBUS_N_ELEMENTS (lengths)) return FALSE; _dbus_assert (len_seq < _DBUS_N_ELEMENTS (lengths)); iter_recurse (iter); if (!generate_many_bodies (iter, data, expected_validity)) { iter_set_sequence (iter, 0); /* reset to first body */ iter_unrecurse (iter); iter_next (iter); /* next length adjustment */ goto restart; } iter_unrecurse (iter); adjust = lengths[len_seq]; if (adjust < 0) { if ((_dbus_string_get_length (data) + adjust) < DBUS_MINIMUM_HEADER_SIZE) _dbus_string_set_length (data, DBUS_MINIMUM_HEADER_SIZE); else _dbus_string_shorten (data, - adjust); *expected_validity = DBUS_INVALID_FOR_UNKNOWN_REASON; } else { if (!_dbus_string_lengthen (data, adjust)) _dbus_assert_not_reached ("oom"); *expected_validity = DBUS_INVALID_TOO_MUCH_DATA; } /* Fixup lengths */ { int old_body_len; int new_body_len; int byte_order; _dbus_assert (_dbus_string_get_length (data) >= DBUS_MINIMUM_HEADER_SIZE); byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); old_body_len = _dbus_marshal_read_uint32 (data, BODY_LENGTH_OFFSET, byte_order, NULL); _dbus_assert (old_body_len < _dbus_string_get_length (data)); new_body_len = old_body_len + adjust; if (new_body_len < 0) { new_body_len = 0; /* we just munged the header, and aren't sure how */ *expected_validity = DBUS_VALIDITY_UNKNOWN; } _dbus_verbose ("changing body len from %u to %u by adjust %d\n", old_body_len, new_body_len, adjust); _dbus_marshal_set_uint32 (data, BODY_LENGTH_OFFSET, new_body_len, byte_order); } return TRUE; }
static dbus_bool_t generate_uint32_changed (DBusMessageDataIter *iter, DBusString *data, DBusValidity *expected_validity) { int body_seq; int byte_seq; int change_seq; dbus_uint32_t v_UINT32; int byte_order; const UIntChange *change; int base_depth; /* Outer loop is each body, next loop is each change, * inner loop is each change location */ base_depth = iter->depth; next_body: _dbus_assert (iter->depth == (base_depth + 0)); _dbus_string_set_length (data, 0); body_seq = iter_get_sequence (iter); if (!generate_many_bodies (iter, data, expected_validity)) return FALSE; _dbus_assert (iter->depth == (base_depth + 0)); iter_set_sequence (iter, body_seq); /* undo the "next" from generate_many_bodies */ iter_recurse (iter); next_change: _dbus_assert (iter->depth == (base_depth + 1)); change_seq = iter_get_sequence (iter); if (change_seq == _DBUS_N_ELEMENTS (uint32_changes)) { /* Reset change count */ iter_set_sequence (iter, 0); iter_unrecurse (iter); iter_next (iter); goto next_body; } _dbus_assert (iter->depth == (base_depth + 1)); iter_recurse (iter); _dbus_assert (iter->depth == (base_depth + 2)); byte_seq = iter_get_sequence (iter); /* skip 4 bytes at a time */ iter_next (iter); iter_next (iter); iter_next (iter); iter_next (iter); iter_unrecurse (iter); _dbus_assert (_DBUS_ALIGN_VALUE (byte_seq, 4) == (unsigned) byte_seq); if (byte_seq >= (_dbus_string_get_length (data) - 4)) { /* reset byte count */ _dbus_assert (iter->depth == (base_depth + 1)); iter_recurse (iter); _dbus_assert (iter->depth == (base_depth + 2)); iter_set_sequence (iter, 0); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 1)); iter_next (iter); goto next_change; } _dbus_assert (byte_seq <= (_dbus_string_get_length (data) - 4)); byte_order = _dbus_string_get_byte (data, BYTE_ORDER_OFFSET); v_UINT32 = _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL); change = &uint32_changes[change_seq]; if (change->type == CHANGE_TYPE_ADJUST) { v_UINT32 += (int) change->value; } else { v_UINT32 = change->value; } #if 0 printf ("body %d change %d pos %d ", body_seq, change_seq, byte_seq); if (change->type == CHANGE_TYPE_ADJUST) printf ("adjust by %d", (int) change->value); else printf ("set to %u", change->value); printf (" \t%u -> %u\n", _dbus_marshal_read_uint32 (data, byte_seq, byte_order, NULL), v_UINT32); #endif _dbus_marshal_set_uint32 (data, byte_seq, v_UINT32, byte_order); *expected_validity = DBUS_VALIDITY_UNKNOWN; _dbus_assert (iter->depth == (base_depth + 1)); iter_unrecurse (iter); _dbus_assert (iter->depth == (base_depth + 0)); return TRUE; }
dbus_bool_t _dbus_marshal_validate_test (void) { DBusString str; int i; const char *valid_paths[] = { "/", "/foo/bar", "/foo", "/foo/bar/baz" }; const char *invalid_paths[] = { "bar", "bar/baz", "/foo/bar/", "/foo/" "foo/", "boo//blah", "//", "///", "foo///blah/", "Hello World", "", " ", "foo bar" }; const char *valid_interfaces[] = { "org.freedesktop.Foo", "Bar.Baz", "Blah.Blah.Blah.Blah.Blah", "a.b", "a.b.c.d.e.f.g", "a0.b1.c2.d3.e4.f5.g6", "abc123.foo27" }; const char *invalid_interfaces[] = { ".", "", "..", ".Foo.Bar", "..Foo.Bar", "Foo.Bar.", "Foo.Bar..", "Foo", "9foo.bar.baz", "foo.bar..baz", "foo.bar...baz", "foo.bar.b..blah", ":", ":0-1", "10", ":11.34324", "0.0.0", "0..0", "foo.Bar.%", "foo.Bar!!", "!Foo.bar.bz", "foo.$.blah", "", " ", "foo bar" }; const char *valid_unique_names[] = { ":0", ":a", ":", ":.a", ":.1", ":0.1", ":000.2222", ":.blah", ":abce.freedesktop.blah" }; const char *invalid_unique_names[] = { //":-", ":!", //":0-10", ":blah.", ":blah.", ":blah..org", ":blah.org..", ":..blah.org", "", " ", "foo bar" }; const char *valid_members[] = { "Hello", "Bar", "foobar", "_foobar", "foo89" }; const char *invalid_members[] = { "9Hello", "10", "1", "foo-bar", "blah.org", ".blah", "blah.", "Hello.", "!foo", "", " ", "foo bar" }; const char *valid_signatures[] = { "", "sss", "i", "b" }; const char *invalid_signatures[] = { " ", "not a valid signature", "123", ".", "(", "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */ }; /* Signature with reason */ run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests), _dbus_validate_signature_with_reason); /* Path validation */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_paths)) { _dbus_string_init_const (&str, valid_paths[i]); if (!_dbus_validate_path (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]); _dbus_assert_not_reached ("invalid path"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_paths)) { _dbus_string_init_const (&str, invalid_paths[i]); if (_dbus_validate_path (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]); _dbus_assert_not_reached ("valid path"); } ++i; } /* Interface validation */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) { _dbus_string_init_const (&str, valid_interfaces[i]); if (!_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]); _dbus_assert_not_reached ("invalid interface"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) { _dbus_string_init_const (&str, invalid_interfaces[i]); if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]); _dbus_assert_not_reached ("valid interface"); } ++i; } /* Bus name validation (check that valid interfaces are valid bus names, * and invalid interfaces are invalid services except if they start with ':') */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) { _dbus_string_init_const (&str, valid_interfaces[i]); if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]); _dbus_assert_not_reached ("invalid bus name"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) { if (invalid_interfaces[i][0] != ':') { _dbus_string_init_const (&str, invalid_interfaces[i]); if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]); _dbus_assert_not_reached ("valid bus name"); } } ++i; } /* unique name validation */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names)) { _dbus_string_init_const (&str, valid_unique_names[i]); if (!_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]); _dbus_assert_not_reached ("invalid unique name"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names)) { _dbus_string_init_const (&str, invalid_unique_names[i]); if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]); _dbus_assert_not_reached ("valid unique name"); } ++i; } /* Error name validation (currently identical to interfaces) */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) { _dbus_string_init_const (&str, valid_interfaces[i]); if (!_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]); _dbus_assert_not_reached ("invalid error name"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) { if (invalid_interfaces[i][0] != ':') { _dbus_string_init_const (&str, invalid_interfaces[i]); if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]); _dbus_assert_not_reached ("valid error name"); } } ++i; } /* Member validation */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_members)) { _dbus_string_init_const (&str, valid_members[i]); if (!_dbus_validate_member (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]); _dbus_assert_not_reached ("invalid member"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_members)) { _dbus_string_init_const (&str, invalid_members[i]); if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]); _dbus_assert_not_reached ("valid member"); } ++i; } /* Signature validation */ i = 0; while (i < (int) _DBUS_N_ELEMENTS (valid_signatures)) { _dbus_string_init_const (&str, valid_signatures[i]); if (!_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]); _dbus_assert_not_reached ("invalid signature"); } ++i; } i = 0; while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures)) { _dbus_string_init_const (&str, invalid_signatures[i]); if (_dbus_validate_signature (&str, 0, _dbus_string_get_length (&str))) { _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]); _dbus_assert_not_reached ("valid signature"); } ++i; } /* Validate claimed length longer than real length */ _dbus_string_init_const (&str, "abc.efg"); if (_dbus_validate_bus_name (&str, 0, 8)) _dbus_assert_not_reached ("validated too-long string"); if (_dbus_validate_interface (&str, 0, 8)) _dbus_assert_not_reached ("validated too-long string"); if (_dbus_validate_error_name (&str, 0, 8)) _dbus_assert_not_reached ("validated too-long string"); _dbus_string_init_const (&str, "abc"); if (_dbus_validate_member (&str, 0, 4)) _dbus_assert_not_reached ("validated too-long string"); _dbus_string_init_const (&str, "sss"); if (_dbus_validate_signature (&str, 0, 4)) _dbus_assert_not_reached ("validated too-long signature"); /* Validate string exceeding max name length */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) if (!_dbus_string_append (&str, "abc.def")) _dbus_assert_not_reached ("no memory"); if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) _dbus_assert_not_reached ("validated overmax string"); if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str))) _dbus_assert_not_reached ("validated overmax string"); if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str))) _dbus_assert_not_reached ("validated overmax string"); /* overlong member */ _dbus_string_set_length (&str, 0); while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) if (!_dbus_string_append (&str, "abc")) _dbus_assert_not_reached ("no memory"); if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str))) _dbus_assert_not_reached ("validated overmax string"); /* overlong unique name */ _dbus_string_set_length (&str, 0); _dbus_string_append (&str, ":"); while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) if (!_dbus_string_append (&str, "abc")) _dbus_assert_not_reached ("no memory"); if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) _dbus_assert_not_reached ("validated overmax string"); _dbus_string_free (&str); /* Body validation; test basic validation of valid bodies for both endian */ { int sequence; DBusString signature; DBusString body; if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) _dbus_assert_not_reached ("oom"); sequence = 0; while (dbus_internal_do_not_use_generate_bodies (sequence, DBUS_LITTLE_ENDIAN, &signature, &body)) { DBusValidity validity; validity = _dbus_validate_body_with_reason (&signature, 0, DBUS_LITTLE_ENDIAN, NULL, &body, 0, _dbus_string_get_length (&body)); if (validity != DBUS_VALID) { _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n", validity, sequence); _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); _dbus_assert_not_reached ("test failed"); } _dbus_string_set_length (&signature, 0); _dbus_string_set_length (&body, 0); ++sequence; } sequence = 0; while (dbus_internal_do_not_use_generate_bodies (sequence, DBUS_BIG_ENDIAN, &signature, &body)) { DBusValidity validity; validity = _dbus_validate_body_with_reason (&signature, 0, DBUS_BIG_ENDIAN, NULL, &body, 0, _dbus_string_get_length (&body)); if (validity != DBUS_VALID) { _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n", validity, sequence); _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); _dbus_assert_not_reached ("test failed"); } _dbus_string_set_length (&signature, 0); _dbus_string_set_length (&body, 0); ++sequence; } _dbus_string_free (&signature); _dbus_string_free (&body); } return TRUE; }
static void babysit (pid_t grandchild_pid, int parent_pipe) { int sigchld_pipe[2]; /* We don't exec, so we keep parent state, such as the pid that * _dbus_verbose() uses. Reset the pid here. */ _dbus_verbose_reset (); /* I thought SIGCHLD would just wake up the poll, but * that didn't seem to work, so added this pipe. * Probably the pipe is more likely to work on busted * operating systems anyhow. */ if (pipe (sigchld_pipe) < 0) { _dbus_warn ("Not enough file descriptors to create pipe in babysitter process\n"); exit (1); } babysit_sigchld_pipe = sigchld_pipe[WRITE_END]; _dbus_set_signal_handler (SIGCHLD, babysit_signal_handler); write_pid (parent_pipe, grandchild_pid); check_babysit_events (grandchild_pid, parent_pipe, 0); while (TRUE) { DBusPollFD pfds[2]; pfds[0].fd = parent_pipe; pfds[0].events = _DBUS_POLLIN; pfds[0].revents = 0; pfds[1].fd = sigchld_pipe[READ_END]; pfds[1].events = _DBUS_POLLIN; pfds[1].revents = 0; if (_dbus_poll (pfds, _DBUS_N_ELEMENTS (pfds), -1) < 0 && errno != EINTR) { _dbus_warn ("_dbus_poll() error: %s\n", strerror (errno)); exit (1); } if (pfds[0].revents != 0) { check_babysit_events (grandchild_pid, parent_pipe, pfds[0].revents); } else if (pfds[1].revents & _DBUS_POLLIN) { char b; if (read (sigchld_pipe[READ_END], &b, 1) == -1) { /* ignore */ } /* do waitpid check */ check_babysit_events (grandchild_pid, parent_pipe, 0); } } exit (1); }
dbus_bool_t _dbus_message_test (const char *test_data_dir) { DBusMessage *message; DBusMessageLoader *loader; int i; const char *data; DBusMessage *copy; const char *name1; const char *name2; const dbus_uint32_t our_uint32_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int32_t our_int32_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; #ifdef DBUS_HAVE_INT64 const dbus_uint64_t our_uint64_array[] = { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; const dbus_int64_t our_int64_array[] = { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; #endif const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; const char **v_ARRAY_STRING = our_string_array; const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; const double *v_ARRAY_DOUBLE = our_double_array; const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; const unsigned char *v_ARRAY_BYTE = our_byte_array; const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; char sig[64]; const char *s; const char *v_STRING; double v_DOUBLE; dbus_int16_t v_INT16; dbus_uint16_t v_UINT16; dbus_int32_t v_INT32; dbus_uint32_t v_UINT32; #ifdef DBUS_HAVE_INT64 dbus_int64_t v_INT64; dbus_uint64_t v_UINT64; #endif unsigned char v_BYTE; unsigned char v2_BYTE; dbus_bool_t v_BOOLEAN; message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", "TestMethod")); _dbus_assert (strcmp (dbus_message_get_path (message), "/org/freedesktop/TestPath") == 0); _dbus_message_set_serial (message, 1234); /* string length including nul byte not a multiple of 4 */ if (!dbus_message_set_sender (message, "org.foo.bar1")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); dbus_message_set_reply_serial (message, 5678); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); if (!dbus_message_set_sender (message, NULL)) _dbus_assert_not_reached ("out of memory"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); _dbus_assert (dbus_message_get_serial (message) == 1234); _dbus_assert (dbus_message_get_reply_serial (message) == 5678); _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); dbus_message_set_no_reply (message, TRUE); _dbus_assert (dbus_message_get_no_reply (message) == TRUE); dbus_message_set_no_reply (message, FALSE); _dbus_assert (dbus_message_get_no_reply (message) == FALSE); /* Set/get some header fields */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); /* Set/get them with longer values */ if (!dbus_message_set_path (message, "/foo/bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo/bar") == 0); if (!dbus_message_set_interface (message, "org.Foo.Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo.Bar") == 0); if (!dbus_message_set_member (message, "BarFoo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "BarFoo") == 0); /* Realloc shorter again */ if (!dbus_message_set_path (message, "/foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_path (message), "/foo") == 0); if (!dbus_message_set_interface (message, "org.Foo")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_interface (message), "org.Foo") == 0); if (!dbus_message_set_member (message, "Bar")) _dbus_assert_not_reached ("out of memory"); _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); dbus_message_unref (message); /* Test the vararg functions */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", "Foo.TestInterface", "TestMethod"); _dbus_message_set_serial (message, 1); dbus_message_set_reply_serial (message, 5678); v_INT16 = -0x123; v_UINT16 = 0x123; v_INT32 = -0x12345678; v_UINT32 = 0x12300042; #ifdef DBUS_HAVE_INT64 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); #endif v_STRING = "Test string"; v_DOUBLE = 3.14159; v_BOOLEAN = TRUE; v_BYTE = 42; v2_BYTE = 24; dbus_message_append_args (message, DBUS_TYPE_INT16, &v_INT16, DBUS_TYPE_UINT16, &v_UINT16, DBUS_TYPE_INT32, &v_INT32, DBUS_TYPE_UINT32, &v_UINT32, #ifdef DBUS_HAVE_INT64 DBUS_TYPE_INT64, &v_INT64, DBUS_TYPE_UINT64, &v_UINT64, #endif DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_DOUBLE, &v_DOUBLE, DBUS_TYPE_BOOLEAN, &v_BOOLEAN, DBUS_TYPE_BYTE, &v_BYTE, DBUS_TYPE_BYTE, &v2_BYTE, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, _DBUS_N_ELEMENTS (our_uint32_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, _DBUS_N_ELEMENTS (our_int32_array), #ifdef DBUS_HAVE_INT64 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, _DBUS_N_ELEMENTS (our_uint64_array), DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, _DBUS_N_ELEMENTS (our_int64_array), #endif DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, _DBUS_N_ELEMENTS (our_double_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, _DBUS_N_ELEMENTS (our_byte_array), DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, _DBUS_N_ELEMENTS (our_boolean_array), DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, _DBUS_N_ELEMENTS (our_string_array), DBUS_TYPE_INVALID); i = 0; sig[i++] = DBUS_TYPE_INT16; sig[i++] = DBUS_TYPE_UINT16; sig[i++] = DBUS_TYPE_INT32; sig[i++] = DBUS_TYPE_UINT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_INT64; sig[i++] = DBUS_TYPE_UINT64; #endif sig[i++] = DBUS_TYPE_STRING; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT32; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT32; #ifdef DBUS_HAVE_INT64 sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_UINT64; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_INT64; #endif sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_DOUBLE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BYTE; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_STRING; sig[i++] = DBUS_TYPE_INVALID; _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); _dbus_verbose ("HEADER\n"); _dbus_verbose_bytes_of_string (&message->header.data, 0, _dbus_string_get_length (&message->header.data)); _dbus_verbose ("BODY\n"); _dbus_verbose_bytes_of_string (&message->body, 0, _dbus_string_get_length (&message->body)); _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", sig, dbus_message_get_signature (message)); s = dbus_message_get_signature (message); _dbus_assert (dbus_message_has_signature (message, sig)); _dbus_assert (strcmp (s, sig) == 0); verify_test_message (message); copy = dbus_message_copy (message); _dbus_assert (dbus_message_get_reply_serial (message) == dbus_message_get_reply_serial (copy)); _dbus_assert (message->header.padding == copy->header.padding); _dbus_assert (_dbus_string_get_length (&message->header.data) == _dbus_string_get_length (©->header.data)); _dbus_assert (_dbus_string_get_length (&message->body) == _dbus_string_get_length (©->body)); verify_test_message (copy); name1 = dbus_message_get_interface (message); name2 = dbus_message_get_interface (copy); _dbus_assert (strcmp (name1, name2) == 0); name1 = dbus_message_get_member (message); name2 = dbus_message_get_member (copy); _dbus_assert (strcmp (name1, name2) == 0); dbus_message_unref (copy); /* Message loader test */ _dbus_message_lock (message); loader = _dbus_message_loader_new (); /* check ref/unref */ _dbus_message_loader_ref (loader); _dbus_message_loader_unref (loader); /* Write the header data one byte at a time */ data = _dbus_string_get_const_data (&message->header.data); for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } /* Write the body data one byte at a time */ data = _dbus_string_get_const_data (&message->body); for (i = 0; i < _dbus_string_get_length (&message->body); i++) { DBusString *buffer; _dbus_message_loader_get_buffer (loader, &buffer); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer, 1); } dbus_message_unref (message); /* Now pop back the message */ if (!_dbus_message_loader_queue_messages (loader)) _dbus_assert_not_reached ("no memory to queue messages"); if (_dbus_message_loader_get_is_corrupted (loader)) _dbus_assert_not_reached ("message loader corrupted"); message = _dbus_message_loader_pop_message (loader); if (!message) _dbus_assert_not_reached ("received a NULL message"); if (dbus_message_get_reply_serial (message) != 5678) _dbus_assert_not_reached ("reply serial fields differ"); verify_test_message (message); dbus_message_unref (message); _dbus_message_loader_unref (loader); check_memleaks (); /* Load all the sample messages from the message factory */ { DBusMessageDataIter diter; DBusMessageData mdata; int count; reset_validities_seen (); count = 0; _dbus_message_data_iter_init (&diter); while (_dbus_message_data_iter_get_and_next (&diter, &mdata)) { if (!dbus_internal_do_not_use_try_message_data (&mdata.data, mdata.expected_validity)) { _dbus_warn ("expected validity %d and did not get it\n", mdata.expected_validity); _dbus_assert_not_reached ("message data failed"); } _dbus_message_data_free (&mdata); count += 1; } printf ("%d sample messages tested\n", count); print_validities_seen (FALSE); print_validities_seen (TRUE); } check_memleaks (); /* Now load every message in test_data_dir if we have one */ if (test_data_dir == NULL) return TRUE; return dbus_internal_do_not_use_foreach_message_file (test_data_dir, (DBusForeachMessageFileFunc) dbus_internal_do_not_use_try_message_file, NULL); }