/** * Adds a new watch to the watch list, invoking the * application DBusAddWatchFunction if appropriate. * * @param watch_list the watch list. * @param watch the watch to add. * @returns #TRUE on success, #FALSE if no memory. */ dbus_bool_t _dbus_watch_list_add_watch (DBusWatchList *watch_list, DBusWatch *watch) { if (!_dbus_list_append (&watch_list->watches, watch)) return FALSE; _dbus_watch_ref (watch); if (watch_list->add_watch_function != NULL) { _dbus_verbose ("Adding watch on fd %" DBUS_POLLABLE_FORMAT "\n", _dbus_pollable_printable (watch->fd)); if (!(* watch_list->add_watch_function) (watch, watch_list->watch_data)) { _dbus_list_remove_last (&watch_list->watches, watch); _dbus_watch_unref (watch); return FALSE; } } return TRUE; }
/** * Adds a new watch to the watch list, invoking the * application DBusAddWatchFunction if appropriate. * * @param watch_list the watch list. * @param watch the watch to add. * @returns #TRUE on success, #FALSE if no memory. */ dbus_bool_t _dbus_watch_list_add_watch (DBusWatchList *watch_list, DBusWatch *watch) { if (!_dbus_list_append (&watch_list->watches, watch)) return FALSE; _dbus_watch_ref (watch); if (watch_list->add_watch_function != NULL) { _dbus_verbose ("Adding watch on fd %d\n", dbus_watch_get_socket (watch)); if (!(* watch_list->add_watch_function) (watch, watch_list->watch_data)) { _dbus_list_remove_last (&watch_list->watches, watch); _dbus_watch_unref (watch); return FALSE; } } return TRUE; }
/** * Copies a list. This is a linear-time operation. If there isn't * enough memory to copy the entire list, the destination list will be * set to #NULL. * * @param list address of the head of the list to copy. * @param dest address where the copied list should be placed. * @returns #TRUE on success, #FALSE if not enough memory. */ dbus_bool_t _dbus_list_copy (DBusList **list, DBusList **dest) { DBusList *link; _dbus_assert (list != dest); *dest = NULL; link = *list; while (link != NULL) { if (!_dbus_list_append (dest, link->data)) { /* free what we have so far */ _dbus_list_clear (dest); return FALSE; } link = _dbus_list_get_next_link (list, link); } return TRUE; }
dbus_bool_t bus_service_list_queued_owners (BusService *service, DBusList **return_list, DBusError *error) { DBusList *link; _dbus_assert (*return_list == NULL); link = _dbus_list_get_first_link (&service->owners); _dbus_assert (link != NULL); while (link != NULL) { BusOwner *owner; const char *uname; owner = (BusOwner *) link->data; uname = bus_connection_get_name (owner->conn); if (!_dbus_list_append (return_list, (char *)uname)) goto oom; link = _dbus_list_get_next_link (&service->owners, link); } return TRUE; oom: _dbus_list_clear (return_list); BUS_SET_OOM (error); return FALSE; }
static dbus_bool_t _dbus_condvar_wait_win32 (DBusCondVar *cond, DBusCMutex *mutex, int milliseconds) { DWORD retval; dbus_bool_t ret; HANDLE event = TlsGetValue (dbus_cond_event_tls); if (!event) { event = CreateEvent (0, FALSE, FALSE, NULL); if (event == 0) return FALSE; TlsSetValue (dbus_cond_event_tls, event); } EnterCriticalSection (&cond->lock); /* The event must not be signaled. Check this */ _dbus_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT); ret = _dbus_list_append (&cond->list, event); LeaveCriticalSection (&cond->lock); if (!ret) return FALSE; /* Prepend failed */ _dbus_platform_cmutex_unlock (mutex); retval = WaitForSingleObject (event, milliseconds); _dbus_platform_cmutex_lock (mutex); if (retval == WAIT_TIMEOUT) { EnterCriticalSection (&cond->lock); _dbus_list_remove (&cond->list, event); /* In the meantime we could have been signaled, so we must again * wait for the signal, this time with no timeout, to reset * it. retval is set again to honour the late arrival of the * signal */ retval = WaitForSingleObject (event, 0); LeaveCriticalSection (&cond->lock); } #ifndef DBUS_DISABLE_ASSERT EnterCriticalSection (&cond->lock); /* Now event must not be inside the array, check this */ _dbus_assert (_dbus_list_remove (&cond->list, event) == FALSE); LeaveCriticalSection (&cond->lock); #endif /* !G_DISABLE_ASSERT */ return retval != WAIT_TIMEOUT; }
dbus_bool_t bus_policy_append_mandatory_rule (BusPolicy *policy, BusPolicyRule *rule) { if (!_dbus_list_append (&policy->mandatory_rules, rule)) return FALSE; bus_policy_rule_ref (rule); return TRUE; }
dbus_bool_t _dbus_loop_queue_dispatch (DBusLoop *loop, DBusConnection *connection) { if (_dbus_list_append (&loop->need_dispatch, connection)) { dbus_connection_ref (connection); return TRUE; } else return FALSE; }
void _dbus_condvar_new_at_location (DBusCondVar **location_p) { *location_p = _dbus_condvar_new(); if (thread_init_generation != _dbus_current_generation && *location_p) { if (!_dbus_list_append (&uninitialized_condvar_list, location_p)) { _dbus_condvar_free (*location_p); *location_p = NULL; } } }
/** * This does the same thing as _dbus_mutex_new. It however * gives another level of indirection by allocating a pointer * to point to the mutex location. This allows the threading * module to swap out dummy mutexes for real a real mutex so libraries * can initialize threads even after the D-Bus API has been used. * * @param location_p the location of the new mutex, can return #NULL on OOM */ void _dbus_mutex_new_at_location (DBusMutex **location_p) { _dbus_assert (location_p != NULL); *location_p = _dbus_mutex_new(); if (thread_init_generation != _dbus_current_generation && *location_p) { if (!_dbus_list_append (&uninitialized_mutex_list, location_p)) { _dbus_mutex_free (*location_p); *location_p = NULL; } } }
/** * Inserts data into the list before the given existing link. * * @param list the list to modify * @param before_this_link existing link to insert before, or #NULL to append * @param data the value to insert * @returns #TRUE on success, #FALSE if memory allocation fails */ dbus_bool_t _dbus_list_insert_before (DBusList **list, DBusList *before_this_link, void *data) { DBusList *link; if (before_this_link == NULL) return _dbus_list_append (list, data); else { link = alloc_link (data); if (link == NULL) return FALSE; link_before (list, before_this_link, link); } return TRUE; }
static dbus_bool_t add_callback (DBusLoop *loop, Callback *cb) { if (!_dbus_list_append (&loop->callbacks, cb)) return FALSE; loop->callback_list_serial += 1; switch (cb->type) { case CALLBACK_WATCH: loop->watch_count += 1; break; case CALLBACK_TIMEOUT: loop->timeout_count += 1; break; } return TRUE; }
/** * Adds a new timeout to the timeout list, invoking the * application DBusAddTimeoutFunction if appropriate. * * @param timeout_list the timeout list. * @param timeout the timeout to add. * @returns #TRUE on success, #FALSE If no memory. */ dbus_bool_t _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list, DBusTimeout *timeout) { if (!_dbus_list_append (&timeout_list->timeouts, timeout)) return FALSE; _dbus_timeout_ref (timeout); if (timeout_list->add_timeout_function != NULL) { if (!(* timeout_list->add_timeout_function) (timeout, timeout_list->timeout_data)) { _dbus_list_remove_last (&timeout_list->timeouts, timeout); _dbus_timeout_unref (timeout); return FALSE; } } return TRUE; }
static dbus_bool_t delimit_token (DBusString *token, DBusList **retval, DBusError *error) { char *str; str = _dbus_strdup (_dbus_string_get_data (token)); if (!str) { _DBUS_SET_OOM (error); return FALSE; } if (!_dbus_list_append (retval, str)) { dbus_free (str); _DBUS_SET_OOM (error); return FALSE; } return TRUE; }
dbus_bool_t bus_setup_debug_client (DBusConnection *connection) { dbus_bool_t retval; if (!dbus_connection_add_filter (connection, client_disconnect_filter, NULL, NULL)) return FALSE; retval = FALSE; if (client_loop == NULL) { client_loop = _dbus_loop_new (); if (client_loop == NULL) goto out; } if (!dbus_connection_set_watch_functions (connection, add_client_watch, remove_client_watch, toggle_client_watch, connection, NULL)) goto out; if (!dbus_connection_set_timeout_functions (connection, add_client_timeout, remove_client_timeout, NULL, connection, NULL)) goto out; if (!_dbus_list_append (&clients, connection)) goto out; retval = TRUE; out: if (!retval) { dbus_connection_remove_filter (connection, client_disconnect_filter, NULL); dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL); dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL); _dbus_list_remove_last (&clients, connection); if (clients == NULL) { _dbus_loop_unref (client_loop); client_loop = NULL; } } return retval; }
/** * @ingroup DBusListInternals * Unit test for DBusList * @returns #TRUE on success. */ dbus_bool_t _dbus_list_test (void) { DBusList *list1; DBusList *list2; DBusList *link1; DBusList *link2; DBusList *copy1; DBusList *copy2; int i; list1 = NULL; list2 = NULL; /* Test append and prepend */ i = 0; while (i < 10) { if (!_dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("could not allocate for append"); if (!_dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("count not allocate for prepend"); ++i; verify_list (&list1); verify_list (&list2); _dbus_assert (_dbus_list_get_length (&list1) == i); _dbus_assert (_dbus_list_get_length (&list2) == i); } _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); /* Test list clear */ _dbus_list_clear (&list1); _dbus_list_clear (&list2); verify_list (&list1); verify_list (&list2); /* Test get_first, get_last, pop_first, pop_last */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { void *got_data1; void *got_data2; void *data1; void *data2; got_data1 = _dbus_list_get_last (&list1); got_data2 = _dbus_list_get_first (&list2); data1 = _dbus_list_pop_last (&list1); data2 = _dbus_list_pop_first (&list2); _dbus_assert (got_data1 == data1); _dbus_assert (got_data2 == data2); _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); verify_list (&list1); verify_list (&list2); _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; } _dbus_assert (list1 == NULL); _dbus_assert (list2 == NULL); /* Test get_first_link, get_last_link, pop_first_link, pop_last_link */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { DBusList *got_link1; DBusList *got_link2; DBusList *link1; DBusList *link2; void *data1; void *data2; got_link1 = _dbus_list_get_last_link (&list1); got_link2 = _dbus_list_get_first_link (&list2); link1 = _dbus_list_pop_last_link (&list1); link2 = _dbus_list_pop_first_link (&list2); _dbus_assert (got_link1 == link1); _dbus_assert (got_link2 == link2); data1 = link1->data; data2 = link2->data; _dbus_list_free_link (link1); _dbus_list_free_link (link2); _dbus_assert (_DBUS_POINTER_TO_INT (data1) == i); _dbus_assert (_DBUS_POINTER_TO_INT (data2) == i); verify_list (&list1); verify_list (&list2); _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; } _dbus_assert (list1 == NULL); _dbus_assert (list2 == NULL); /* Test iteration */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; verify_list (&list1); verify_list (&list2); _dbus_assert (_dbus_list_get_length (&list1) == i); _dbus_assert (_dbus_list_get_length (&list2) == i); } _dbus_assert (is_ascending_sequence (&list1)); _dbus_assert (is_descending_sequence (&list2)); --i; link2 = _dbus_list_get_first_link (&list2); while (link2 != NULL) { verify_list (&link2); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); link2 = _dbus_list_get_next_link (&list2, link2); --i; } i = 0; link1 = _dbus_list_get_first_link (&list1); while (link1 != NULL) { verify_list (&link1); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); link1 = _dbus_list_get_next_link (&list1, link1); ++i; } --i; link1 = _dbus_list_get_last_link (&list1); while (link1 != NULL) { verify_list (&link1); /* pretend this link is the head */ _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); link1 = _dbus_list_get_prev_link (&list1, link1); --i; } _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* Test remove */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { if ((i % 2) == 0) { if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); verify_list (&list1); verify_list (&list2); } --i; } _dbus_assert (all_odd_values (&list1)); _dbus_assert (all_odd_values (&list2)); _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* test removing the other half of the elements */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; while (i >= 0) { if ((i % 2) != 0) { if (!_dbus_list_remove (&list1, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); if (!_dbus_list_remove (&list2, _DBUS_INT_TO_POINTER (i))) _dbus_assert_not_reached ("element should have been in list"); verify_list (&list1); verify_list (&list2); } --i; } _dbus_assert (all_even_values (&list1)); _dbus_assert (all_even_values (&list2)); /* clear list using remove_link */ while (list1 != NULL) { _dbus_list_remove_link (&list1, list1); verify_list (&list1); } while (list2 != NULL) { _dbus_list_remove_link (&list2, list2); verify_list (&list2); } /* Test remove link more generally */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } --i; link2 = _dbus_list_get_first_link (&list2); while (link2 != NULL) { DBusList *next = _dbus_list_get_next_link (&list2, link2); _dbus_assert (_DBUS_POINTER_TO_INT (link2->data) == i); if ((i % 2) == 0) _dbus_list_remove_link (&list2, link2); verify_list (&list2); link2 = next; --i; } _dbus_assert (all_odd_values (&list2)); _dbus_list_clear (&list2); i = 0; link1 = _dbus_list_get_first_link (&list1); while (link1 != NULL) { DBusList *next = _dbus_list_get_next_link (&list1, link1); _dbus_assert (_DBUS_POINTER_TO_INT (link1->data) == i); if ((i % 2) != 0) _dbus_list_remove_link (&list1, link1); verify_list (&list1); link1 = next; ++i; } _dbus_assert (all_even_values (&list1)); _dbus_list_clear (&list1); /* Test copying a list */ i = 0; while (i < 10) { _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (i)); _dbus_list_prepend (&list2, _DBUS_INT_TO_POINTER (i)); ++i; } /* bad pointers, because they are allowed in the copy dest */ copy1 = _DBUS_INT_TO_POINTER (0x342234); copy2 = _DBUS_INT_TO_POINTER (23); _dbus_list_copy (&list1, ©1); verify_list (&list1); verify_list (©1); _dbus_assert (lists_equal (&list1, ©1)); _dbus_list_copy (&list2, ©2); verify_list (&list2); verify_list (©2); _dbus_assert (lists_equal (&list2, ©2)); /* Now test copying empty lists */ _dbus_list_clear (&list1); _dbus_list_clear (&list2); _dbus_list_clear (©1); _dbus_list_clear (©2); /* bad pointers, because they are allowed in the copy dest */ copy1 = _DBUS_INT_TO_POINTER (0x342234); copy2 = _DBUS_INT_TO_POINTER (23); _dbus_list_copy (&list1, ©1); verify_list (&list1); verify_list (©1); _dbus_assert (lists_equal (&list1, ©1)); _dbus_list_copy (&list2, ©2); verify_list (&list2); verify_list (©2); _dbus_assert (lists_equal (&list2, ©2)); _dbus_list_clear (&list1); _dbus_list_clear (&list2); /* insert_before on empty list */ _dbus_list_insert_before (&list1, NULL, _DBUS_INT_TO_POINTER (0)); verify_list (&list1); /* inserting before first element */ _dbus_list_insert_before (&list1, list1, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); /* inserting in the middle */ _dbus_list_insert_before (&list1, list1->next, _DBUS_INT_TO_POINTER (1)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); /* using insert_before to append */ _dbus_list_insert_before (&list1, NULL, _DBUS_INT_TO_POINTER (-1)); verify_list (&list1); _dbus_assert (is_descending_sequence (&list1)); _dbus_list_clear (&list1); /* insert_after on empty list */ _dbus_list_insert_after (&list1, NULL, _DBUS_INT_TO_POINTER (0)); verify_list (&list1); /* inserting after first element */ _dbus_list_insert_after (&list1, list1, _DBUS_INT_TO_POINTER (1)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); /* inserting at the end */ _dbus_list_insert_after (&list1, list1->next, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); /* using insert_after to prepend */ _dbus_list_insert_after (&list1, NULL, _DBUS_INT_TO_POINTER (-1)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); _dbus_list_clear (&list1); /* using remove_last */ _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (2)); _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (1)); _dbus_list_append (&list1, _DBUS_INT_TO_POINTER (3)); _dbus_list_remove_last (&list1, _DBUS_INT_TO_POINTER (2)); verify_list (&list1); _dbus_assert (is_ascending_sequence (&list1)); _dbus_list_clear (&list1); return TRUE; }
/* this function is self-cancelling if you cancel the transaction */ dbus_bool_t bus_service_add_owner (BusService *service, DBusConnection *connection, dbus_uint32_t flags, BusTransaction *transaction, DBusError *error) { BusOwner *bus_owner; DBusList *bus_owner_link; _DBUS_ASSERT_ERROR_IS_CLEAR (error); /* Send service acquired message first, OOM will result * in cancelling the transaction */ if (service->owners == NULL) { if (!bus_driver_send_service_acquired (connection, service->name, transaction, error)) return FALSE; } bus_owner_link = _bus_service_find_owner_link (service, connection); if (bus_owner_link == NULL) { bus_owner = bus_owner_new (service, connection, flags); if (bus_owner == NULL) { BUS_SET_OOM (error); return FALSE; } bus_owner_set_flags (bus_owner, flags); if (!(flags & DBUS_NAME_FLAG_REPLACE_EXISTING) || service->owners == NULL) { if (!_dbus_list_append (&service->owners, bus_owner)) { bus_owner_unref (bus_owner); BUS_SET_OOM (error); return FALSE; } } else { if (!_dbus_list_insert_after (&service->owners, _dbus_list_get_first_link (&service->owners), bus_owner)) { bus_owner_unref (bus_owner); BUS_SET_OOM (error); return FALSE; } } } else { /* Update the link since we are already in the queue * No need for operations that can produce OOM */ bus_owner = (BusOwner *) bus_owner_link->data; if (flags & DBUS_NAME_FLAG_REPLACE_EXISTING) { DBusList *link; _dbus_list_unlink (&service->owners, bus_owner_link); link = _dbus_list_get_first_link (&service->owners); _dbus_assert (link != NULL); _dbus_list_insert_after_link (&service->owners, link, bus_owner_link); } bus_owner_set_flags (bus_owner, flags); return TRUE; } if (!add_cancel_ownership_to_transaction (transaction, service, bus_owner)) { bus_service_unlink_owner (service, bus_owner); BUS_SET_OOM (error); return FALSE; } return TRUE; }
dbus_bool_t bus_config_parser_content (BusConfigParser *parser, const DBusString *content, DBusError *error) { DBusString content_sane; dbus_bool_t retval; retval = FALSE; if (!_dbus_string_init (&content_sane)) { BUS_SET_OOM (error); goto out; } if (!_dbus_string_copy (content, 0, &content_sane, 0)) { BUS_SET_OOM (error); goto out_content; } /* rip out white space */ _dbus_string_chop_white (&content_sane); if (_dbus_string_get_length (&content_sane) == 0) { /* optimise, there is no content */ retval = TRUE; goto out_content; } switch (parser->type) { case ELEMENT_SERVICEDIR: { char *cpath; /* copy the sane data into a char array */ if (!_dbus_string_copy_data(&content_sane, &cpath)) { BUS_SET_OOM (error); goto out_content; } /* append the dynamic char string to service dirs */ if (!_dbus_list_append (&parser->service_dirs, cpath)) { dbus_free (cpath); BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_SERVICEHELPER: { if (!_dbus_string_copy (&content_sane, 0, &parser->service_helper, 0)) { BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_USER: { if (!_dbus_string_copy (&content_sane, 0, &parser->user, 0)) { BUS_SET_OOM (error); goto out_content; } } break; case ELEMENT_TYPE: { if (!_dbus_string_copy (&content_sane, 0, &parser->bus_type, 0)) { BUS_SET_OOM (error); goto out_content; } } break; default: { /* we don't care about the others... really */ _dbus_verbose (" CONTENTS We dont care '%s' type '%i'\n", _dbus_string_get_const_data (&content_sane), parser->type); break; } } /* woot! */ retval = TRUE; out_content: _dbus_string_free (&content_sane); out: return retval; }
dbus_bool_t bus_expire_list_test (const DBusString *test_data_dir) { DBusLoop *loop; BusExpireList *list; long tv_sec, tv_usec; long tv_sec_not_expired, tv_usec_not_expired; long tv_sec_expired, tv_usec_expired; long tv_sec_past, tv_usec_past; TestExpireItem *item; int next_interval; dbus_bool_t result = FALSE; loop = _dbus_loop_new (); _dbus_assert (loop != NULL); #define EXPIRE_AFTER 100 list = bus_expire_list_new (loop, EXPIRE_AFTER, test_expire_func, NULL); _dbus_assert (list != NULL); _dbus_get_current_time (&tv_sec, &tv_usec); tv_sec_not_expired = tv_sec; tv_usec_not_expired = tv_usec; time_add_milliseconds (&tv_sec_not_expired, &tv_usec_not_expired, EXPIRE_AFTER - 1); tv_sec_expired = tv_sec; tv_usec_expired = tv_usec; time_add_milliseconds (&tv_sec_expired, &tv_usec_expired, EXPIRE_AFTER); tv_sec_past = tv_sec - 1; tv_usec_past = tv_usec; item = dbus_new0 (TestExpireItem, 1); if (item == NULL) goto oom; item->item.added_tv_sec = tv_sec; item->item.added_tv_usec = tv_usec; if (!_dbus_list_append (&list->items, item)) _dbus_assert_not_reached ("out of memory"); next_interval = do_expiration_with_current_time (list, tv_sec_not_expired, tv_usec_not_expired); _dbus_assert (item->expire_count == 0); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == 1); next_interval = do_expiration_with_current_time (list, tv_sec_expired, tv_usec_expired); _dbus_assert (item->expire_count == 1); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == -1); next_interval = do_expiration_with_current_time (list, tv_sec_past, tv_usec_past); _dbus_assert (item->expire_count == 1); _dbus_verbose ("next_interval = %d\n", next_interval); _dbus_assert (next_interval == 1000 + EXPIRE_AFTER); _dbus_list_clear (&list->items); dbus_free (item); bus_expire_list_free (list); _dbus_loop_unref (loop); result = TRUE; oom: return result; }
/** * Verifies that the range of type_str from type_pos to type_end is a * valid signature. If this function returns #TRUE, it will be safe * to iterate over the signature with a types-only #DBusTypeReader. * The range passed in should NOT include the terminating * nul/DBUS_TYPE_INVALID. * * @param type_str the string * @param type_pos where the typecodes start * @param len length of typecodes * @returns #DBUS_VALID if valid, reason why invalid otherwise */ DBusValidity _dbus_validate_signature_with_reason (const DBusString *type_str, int type_pos, int len) { const unsigned char *p; const unsigned char *end; int last; int struct_depth; int array_depth; int dict_entry_depth; DBusValidity result; int element_count; DBusList *element_count_stack; result = DBUS_VALID; element_count_stack = NULL; if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } _dbus_assert (type_str != NULL); _dbus_assert (type_pos < _DBUS_INT32_MAX - len); _dbus_assert (len >= 0); _dbus_assert (type_pos >= 0); if (len > DBUS_MAXIMUM_SIGNATURE_LENGTH) { result = DBUS_INVALID_SIGNATURE_TOO_LONG; goto out; } p = _dbus_string_get_const_data_len (type_str, type_pos, 0); end = _dbus_string_get_const_data_len (type_str, type_pos + len, 0); struct_depth = 0; array_depth = 0; dict_entry_depth = 0; last = DBUS_TYPE_INVALID; while (p != end) { switch (*p) { case DBUS_TYPE_BYTE: case DBUS_TYPE_BOOLEAN: case DBUS_TYPE_INT16: case DBUS_TYPE_UINT16: case DBUS_TYPE_INT32: case DBUS_TYPE_UINT32: case DBUS_TYPE_INT64: case DBUS_TYPE_UINT64: case DBUS_TYPE_DOUBLE: case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: case DBUS_TYPE_SIGNATURE: case DBUS_TYPE_VARIANT: break; case DBUS_TYPE_ARRAY: array_depth += 1; if (array_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION; goto out; } break; case DBUS_STRUCT_BEGIN_CHAR: struct_depth += 1; if (struct_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION; goto out; } if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } break; case DBUS_STRUCT_END_CHAR: if (struct_depth == 0) { result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED; goto out; } if (last == DBUS_STRUCT_BEGIN_CHAR) { result = DBUS_INVALID_STRUCT_HAS_NO_FIELDS; goto out; } _dbus_list_pop_last (&element_count_stack); struct_depth -= 1; break; case DBUS_DICT_ENTRY_BEGIN_CHAR: if (last != DBUS_TYPE_ARRAY) { result = DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY; goto out; } dict_entry_depth += 1; if (dict_entry_depth > DBUS_MAXIMUM_TYPE_RECURSION_DEPTH) { result = DBUS_INVALID_EXCEEDED_MAXIMUM_DICT_ENTRY_RECURSION; goto out; } if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (0))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } break; case DBUS_DICT_ENTRY_END_CHAR: if (dict_entry_depth == 0) { result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED; goto out; } dict_entry_depth -= 1; element_count = _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); if (element_count != 2) { if (element_count == 0) result = DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS; else if (element_count == 1) result = DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD; else result = DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS; goto out; } break; case DBUS_TYPE_STRUCT: /* doesn't appear in signatures */ case DBUS_TYPE_DICT_ENTRY: /* ditto */ default: result = DBUS_INVALID_UNKNOWN_TYPECODE; goto out; } if (*p != DBUS_TYPE_ARRAY && *p != DBUS_DICT_ENTRY_BEGIN_CHAR && *p != DBUS_STRUCT_BEGIN_CHAR) { element_count = _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack)); ++element_count; if (!_dbus_list_append (&element_count_stack, _DBUS_INT_TO_POINTER (element_count))) { result = DBUS_VALIDITY_UNKNOWN_OOM_ERROR; goto out; } } if (array_depth > 0) { if (*p == DBUS_TYPE_ARRAY && p != end) { const char *p1; p1 = p + 1; if (*p1 == DBUS_STRUCT_END_CHAR || *p1 == DBUS_DICT_ENTRY_END_CHAR) { result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; goto out; } } else { array_depth = 0; } } if (last == DBUS_DICT_ENTRY_BEGIN_CHAR && !dbus_type_is_basic (*p)) { result = DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE; goto out; } last = *p; ++p; } if (array_depth > 0) { result = DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE; goto out; } if (struct_depth > 0) { result = DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED; goto out; } if (dict_entry_depth > 0) { result = DBUS_INVALID_DICT_ENTRY_STARTED_BUT_NOT_ENDED; goto out; } _dbus_assert (last != DBUS_TYPE_ARRAY); _dbus_assert (last != DBUS_STRUCT_BEGIN_CHAR); _dbus_assert (last != DBUS_DICT_ENTRY_BEGIN_CHAR); result = DBUS_VALID; out: _dbus_list_clear (&element_count_stack); return result; }
/** * Split paths into a list of char strings * * @param dirs string with pathes * @param suffix string concated to each path in dirs * @param dir_list contains a list of splitted pathes * return #TRUE is pathes could be splittes,#FALSE in oom case */ dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, const char *suffix, DBusList **dir_list) { int start; int i; int len; char *cpath; DBusString file_suffix; start = 0; i = 0; _dbus_string_init_const (&file_suffix, suffix); len = _dbus_string_get_length (dirs); while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i)) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, i - start, &path, 0)) { _dbus_string_free (&path); goto oom; } _dbus_string_chop_white (&path); /* check for an empty path */ if (_dbus_string_get_length (&path) == 0) goto next; if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } next: _dbus_string_free (&path); start = i + 1; } if (start != len) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, len - start, &path, 0)) { _dbus_string_free (&path); goto oom; } if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } _dbus_string_free (&path); } return TRUE; oom: _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); _dbus_list_clear (dir_list); return FALSE; }
static dbus_bool_t bus_driver_handle_list_queued_owners (DBusConnection *connection, BusTransaction *transaction, DBusMessage *message, DBusError *error) { const char *text; DBusList *base_names; DBusList *link; DBusString str; BusRegistry *registry; BusService *service; DBusMessage *reply; DBusMessageIter iter, array_iter; char *dbus_service_name = DBUS_SERVICE_DBUS; _DBUS_ASSERT_ERROR_IS_CLEAR (error); registry = bus_connection_get_registry (connection); base_names = NULL; text = NULL; reply = NULL; if (! dbus_message_get_args (message, error, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID)) goto failed; _dbus_string_init_const (&str, text); service = bus_registry_lookup (registry, &str); if (service == NULL && _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) { /* ORG_FREEDESKTOP_DBUS owns itself */ if (! _dbus_list_append (&base_names, dbus_service_name)) goto oom; } else if (service == NULL) { dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, "Could not get owners of name '%s': no such name", text); goto failed; } else { if (!bus_service_list_queued_owners (service, &base_names, error)) goto failed; } _dbus_assert (base_names != NULL); reply = dbus_message_new_method_return (message); if (reply == NULL) goto oom; dbus_message_iter_init_append (reply, &iter); if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter)) goto oom; link = _dbus_list_get_first_link (&base_names); while (link != NULL) { char *uname; _dbus_assert (link->data != NULL); uname = (char *)link->data; if (!dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &uname)) goto oom; link = _dbus_list_get_next_link (&base_names, link); } if (! dbus_message_iter_close_container (&iter, &array_iter)) goto oom; if (! bus_transaction_send_from_driver (transaction, connection, reply)) goto oom; dbus_message_unref (reply); return TRUE; oom: BUS_SET_OOM (error); failed: _DBUS_ASSERT_ERROR_IS_SET (error); if (reply) dbus_message_unref (reply); if (base_names) _dbus_list_clear (&base_names); return FALSE; }
static dbus_bool_t test_command_line (const char *arg1, ...) { int i, original_argc, shell_argc; char **shell_argv; char **original_argv; char *command_line, *tmp; DBusString str; DBusList *list = NULL, *node; va_list var_args; DBusError error; va_start (var_args, arg1); _dbus_list_append (&list, (char *)arg1); do { tmp = va_arg (var_args, char *); if (!tmp) break; _dbus_list_append (&list, tmp); } while (tmp); va_end (var_args); original_argc = _dbus_list_get_length (&list); original_argv = dbus_new (char *, original_argc); _dbus_string_init (&str); for (i = 0, node = _dbus_list_get_first_link (&list); i < original_argc && node; i++, node = _dbus_list_get_next_link (&list, node)) { original_argv[i] = node->data; if (i > 0) _dbus_string_append_byte (&str, ' '); _dbus_string_append (&str, original_argv[i]); } _dbus_list_clear (&list); command_line = _dbus_string_get_data (&str); printf ("\n\nTesting command line '%s'\n", command_line); dbus_error_init (&error); if (!_dbus_shell_parse_argv (command_line, &shell_argc, &shell_argv, &error)) { fprintf (stderr, "Error parsing command line: %s\n", error.message ? error.message : ""); return FALSE; } else { if (shell_argc != original_argc) { printf ("Number of arguments returned (%d) don't match original (%d)\n", shell_argc, original_argc); return FALSE; } printf ("Number of arguments: %d\n", shell_argc); for (i = 0; i < shell_argc; i++) { char *unquoted; unquoted = _dbus_shell_unquote (original_argv[i]); if (strcmp (unquoted ? unquoted : "", shell_argv[i] ? shell_argv[i] : "")) { printf ("Position %d, returned argument (%s) does not match original (%s)\n", i, shell_argv[i], unquoted); dbus_free (unquoted); return FALSE; } dbus_free (unquoted); if (shell_argv[i]) printf ("Argument %d = %s\n", i, shell_argv[i]); } dbus_free_string_array (shell_argv); } _dbus_string_free (&str); return TRUE; }