/** * Called to notify the D-Bus library when a previously-added watch is * ready for reading or writing, or has an exception such as a hangup. * * If this function returns #FALSE, then the file descriptor may still * be ready for reading or writing, but more memory is needed in order * to do the reading or writing. If you ignore the #FALSE return, your * application may spin in a busy loop on the file descriptor until * memory becomes available, but nothing more catastrophic should * happen. * * dbus_watch_handle() cannot be called during the * DBusAddWatchFunction, as the connection will not be ready to handle * that watch yet. * * It is not allowed to reference a DBusWatch after it has been passed * to remove_function. * * @param watch the DBusWatch object. * @param flags the poll condition using #DBusWatchFlags values * @returns #FALSE if there wasn't enough memory */ dbus_bool_t dbus_watch_handle (DBusWatch *watch, unsigned int flags) { _dbus_return_val_if_fail (watch != NULL, FALSE); #ifndef DBUS_DISABLE_CHECKS if (!_dbus_pollable_is_valid (watch->fd) || watch->flags == 0) { _dbus_warn_check_failed ("Watch is invalid, it should have been removed"); return TRUE; } #endif _dbus_return_val_if_fail (_dbus_pollable_is_valid (watch->fd) /* fails if watch was removed */, TRUE); _dbus_watch_sanitize_condition (watch, &flags); if (flags == 0) { _dbus_verbose ("After sanitization, watch flags on fd %" DBUS_POLLABLE_FORMAT " were 0\n", _dbus_pollable_printable (watch->fd)); return TRUE; } else return (* watch->handler) (watch, flags, watch->handler_data); }
/** * Starts a service that will request ownership of the given name. * The returned result will be one of be one of * #DBUS_START_REPLY_SUCCESS or #DBUS_START_REPLY_ALREADY_RUNNING if * successful. Pass #NULL if you don't care about the result. * * The flags parameter is for future expansion, currently you should * specify 0. * * @param connection the connection * @param name the name we want the new service to request * @param flags the flags (should always be 0 for now) * @param result a place to store the result or #NULL * @param error location to store any errors * @returns #TRUE if the activation succeeded, #FALSE if not */ dbus_bool_t dbus_bus_start_service_by_name (DBusConnection *connection, const char *name, dbus_uint32_t flags, dbus_uint32_t *result, DBusError *error) { DBusMessage *msg; DBusMessage *reply; _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE); msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "StartServiceByName"); if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID)) { dbus_message_unref (msg); _DBUS_SET_OOM (error); return FALSE; } reply = dbus_connection_send_with_reply_and_block (connection, msg, -1, error); dbus_message_unref (msg); if (reply == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); return FALSE; } if (dbus_set_error_from_message (error, reply)) { _DBUS_ASSERT_ERROR_IS_SET (error); dbus_message_unref (reply); return FALSE; } if (result != NULL && !dbus_message_get_args (reply, error, DBUS_TYPE_UINT32, result, DBUS_TYPE_INVALID)) { _DBUS_ASSERT_ERROR_IS_SET (error); dbus_message_unref (reply); return FALSE; } dbus_message_unref (reply); return TRUE; }
/** * Checks whether a certain name has an owner. * * @param connection the connection * @param name the name * @param error location to store any errors * @returns #TRUE if the name exists, #FALSE if not or on error */ dbus_bool_t dbus_bus_name_has_owner (DBusConnection *connection, const char *name, DBusError *error) { DBusMessage *message, *reply; dbus_bool_t exists; _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (name != NULL, FALSE); _dbus_return_val_if_fail (_dbus_check_is_valid_bus_name (name), FALSE); _dbus_return_val_if_error_is_set (error, FALSE); message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "NameHasOwner"); if (message == NULL) { _DBUS_SET_OOM (error); return FALSE; } if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { dbus_message_unref (message); _DBUS_SET_OOM (error); return FALSE; } reply = dbus_connection_send_with_reply_and_block (connection, message, -1, error); dbus_message_unref (message); if (reply == NULL) { _DBUS_ASSERT_ERROR_IS_SET (error); return FALSE; } if (!dbus_message_get_args (reply, error, DBUS_TYPE_BOOLEAN, &exists, DBUS_TYPE_INVALID)) { _DBUS_ASSERT_ERROR_IS_SET (error); dbus_message_unref (reply); return FALSE; } dbus_message_unref (reply); return exists; }
/** * Returns whether a watch is enabled or not. If not * enabled, it should not be polled by the main loop. * * @param watch the DBusWatch object * @returns #TRUE if the watch is enabled */ dbus_bool_t dbus_watch_get_enabled (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, FALSE); return watch->enabled; }
/** * Sets a notification function to be called when the reply is * received or the pending call times out. * * @param pending the pending call * @param function notifier function * @param user_data data to pass to notifier function * @param free_user_data function to free the user data * @returns #FALSE if not enough memory */ dbus_bool_t dbus_pending_call_set_notify (DBusPendingCall *pending, DBusPendingCallNotifyFunction function, void *user_data, DBusFreeFunction free_user_data) { dbus_bool_t ret = FALSE; _dbus_return_val_if_fail (pending != NULL, FALSE); CONNECTION_LOCK (pending->connection); /* could invoke application code! */ if (!_dbus_pending_call_set_data_unlocked (pending, notify_user_data_slot, user_data, free_user_data)) goto out; pending->function = function; ret = TRUE; out: CONNECTION_UNLOCK (pending->connection); return ret; }
/** * Gets data previously set with dbus_watch_set_data() * or #NULL if none. * * @param watch the DBusWatch object. * @returns previously-set data. */ void* dbus_watch_get_data (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, NULL); return watch->data; }
/** * Stores a pointer on a DBusServer, along * with an optional function to be used for freeing * the data when the data is set again, or when * the server is finalized. The slot number * must have been allocated with dbus_server_allocate_data_slot(). * * @param server the server * @param slot the slot number * @param data the data to store * @param free_data_func finalizer function for the data * @returns #TRUE if there was enough memory to store the data */ dbus_bool_t dbus_server_set_data (DBusServer *server, int slot, void *data, DBusFreeFunction free_data_func) { DBusFreeFunction old_free_func; void *old_data; dbus_bool_t retval; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); retval = _dbus_data_slot_list_set (&slot_allocator, &server->slot_list, slot, data, free_data_func, &old_free_func, &old_data); SERVER_UNLOCK (server); if (retval) { /* Do the actual free outside the server lock */ if (old_free_func) (* old_free_func) (old_data); } return retval; }
/** * Deprecated former name of dbus_watch_get_unix_fd(). * * @param watch the DBusWatch object. * @returns the file descriptor to watch. */ int dbus_watch_get_fd (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, -1); return dbus_watch_get_unix_fd(watch); }
/** * Called to notify the D-Bus library when a previously-added watch is * ready for reading or writing, or has an exception such as a hangup. * * If this function returns #FALSE, then the file descriptor may still * be ready for reading or writing, but more memory is needed in order * to do the reading or writing. If you ignore the #FALSE return, your * application may spin in a busy loop on the file descriptor until * memory becomes available, but nothing more catastrophic should * happen. * * dbus_watch_handle() cannot be called during the * DBusAddWatchFunction, as the connection will not be ready to handle * that watch yet. * * It is not allowed to reference a DBusWatch after it has been passed * to remove_function. * * @param watch the DBusWatch object. * @param flags the poll condition using #DBusWatchFlags values * @returns #FALSE if there wasn't enough memory */ dbus_bool_t dbus_watch_handle (DBusWatch *watch, unsigned int flags) { #ifndef DBUS_DISABLE_CHECKS if (watch->fd < 0 || watch->flags == 0) { _dbus_warn_check_failed ("Watch is invalid, it should have been removed\n"); return TRUE; } #endif _dbus_return_val_if_fail (watch->fd >= 0 /* fails if watch was removed */, TRUE); _dbus_watch_sanitize_condition (watch, &flags); if (flags == 0) { _dbus_verbose ("After sanitization, watch flags on fd %d were 0\n", watch->fd); return TRUE; } else return (* watch->handler) (watch, flags, watch->handler_data); }
/** * Sets the authentication mechanisms that this server offers to * clients, as a #NULL-terminated array of mechanism names. This * function only affects connections created <em>after</em> it is * called. Pass #NULL instead of an array to use all available * mechanisms (this is the default behavior). * * The D-Bus specification describes some of the supported mechanisms. * * @param server the server * @param mechanisms #NULL-terminated array of mechanisms * @returns #FALSE if no memory */ dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server, const char **mechanisms) { char **copy; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); if (mechanisms != NULL) { copy = _dbus_dup_string_array (mechanisms); if (copy == NULL) return FALSE; } else copy = NULL; dbus_free_string_array (server->auth_mechanisms); server->auth_mechanisms = copy; SERVER_UNLOCK (server); return TRUE; }
/** * Gets flags from DBusWatchFlags indicating * what conditions should be monitored on the * file descriptor. * * The flags returned will only contain DBUS_WATCH_READABLE * and DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or * DBUS_WATCH_ERROR; all watches implicitly include a watch * for hangups, errors, and other exceptional conditions. * * @param watch the DBusWatch object. * @returns the conditions to watch. */ unsigned int dbus_watch_get_flags (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, 0); _dbus_assert ((watch->flags & VALID_WATCH_FLAGS) == watch->flags); return watch->flags; }
/** * Stores a pointer on a #DBusPendingCall, along * with an optional function to be used for freeing * the data when the data is set again, or when * the pending call is finalized. The slot number * must have been allocated with dbus_pending_call_allocate_data_slot(). * * @param pending the pending_call * @param slot the slot number * @param data the data to store * @param free_data_func finalizer function for the data * @returns #TRUE if there was enough memory to store the data */ dbus_bool_t dbus_pending_call_set_data (DBusPendingCall *pending, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func) { dbus_bool_t retval; _dbus_return_val_if_fail (pending != NULL, FALSE); _dbus_return_val_if_fail (slot >= 0, FALSE); CONNECTION_LOCK (pending->connection); retval = _dbus_pending_call_set_data_unlocked (pending, slot, data, free_data_func); CONNECTION_UNLOCK (pending->connection); return retval; }
/** * A "container type" can contain basic types, or nested * container types. #DBUS_TYPE_INVALID is not a container type. * * This function will crash if passed a typecode that isn't * in dbus-protocol.h * * @returns #TRUE if type is a container */ dbus_bool_t dbus_type_is_container (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); return TYPE_IS_CONTAINER (typecode); }
/** * Checks whether an error occurred (the error is set). * * @param error the error object * @returns #TRUE if an error occurred */ dbus_bool_t dbus_error_is_set (const DBusError *error) { _dbus_return_val_if_fail (error != NULL, FALSE); _dbus_assert ((error->name != NULL && error->message != NULL) || (error->name == NULL && error->message == NULL)); return error->name != NULL; }
/** * Increments the reference count of a DBusServer. * * @param server the server. * @returns the server */ DBusServer * dbus_server_ref (DBusServer *server) { _dbus_return_val_if_fail (server != NULL, NULL); _dbus_return_val_if_fail (server->refcount.value > 0, NULL); #ifdef DBUS_HAVE_ATOMIC_INT _dbus_atomic_inc (&server->refcount); #else SERVER_LOCK (server); _dbus_assert (server->refcount.value > 0); server->refcount.value += 1; SERVER_UNLOCK (server); #endif return server; }
/** * Allocates an integer ID to be used for storing application-specific * data on any DBusPendingCall. The allocated ID may then be used * with dbus_pending_call_set_data() and dbus_pending_call_get_data(). * The passed-in slot must be initialized to -1, and is filled in * with the slot ID. If the passed-in slot is not -1, it's assumed * to be already allocated, and its refcount is incremented. * * The allocated slot is global, i.e. all DBusPendingCall objects will * have a slot with the given integer ID reserved. * * @param slot_p address of a global variable storing the slot * @returns #FALSE on failure (no memory) */ dbus_bool_t dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p) { _dbus_return_val_if_fail (slot_p != NULL, FALSE); return _dbus_data_slot_allocator_alloc (&slot_allocator, &_DBUS_LOCK_NAME (pending_call_slots), slot_p); }
/** * Sets the unique name of the connection. Can only be used if you * registered with the bus manually (i.e. if you did not call * dbus_bus_register()). Can only be called once per connection. * * @param connection the connection * @param unique_name the unique name * @returns #FALSE if not enough memory */ dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection, const char *unique_name) { BusData *bd; _dbus_return_val_if_fail (connection != NULL, FALSE); _dbus_return_val_if_fail (unique_name != NULL, FALSE); bd = ensure_bus_data (connection); if (bd == NULL) return FALSE; _dbus_assert (bd->unique_name == NULL); bd->unique_name = _dbus_strdup (unique_name); return bd->unique_name != NULL; }
/** * Increments the reference count on a pending call. * * @param pending the pending call object * @returns the pending call object */ DBusPendingCall * dbus_pending_call_ref (DBusPendingCall *pending) { _dbus_return_val_if_fail (pending != NULL, NULL); _dbus_atomic_inc (&pending->refcount); return pending; }
/** * Convenience function for returning the element type of an array; * This function allows you to avoid initializing a sub-iterator and * getting its current type. * * Undefined behavior results if you invoke this function when the * current type of the iterator is not #DBUS_TYPE_ARRAY. * * @param iter pointer to an iterator * @returns current array element type */ int dbus_signature_iter_get_element_type (const DBusSignatureIter *iter) { DBusSignatureRealIter *real_iter = (DBusSignatureRealIter *) iter; _dbus_return_val_if_fail (dbus_signature_iter_get_current_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID); return _dbus_first_type_in_signature_c_str (real_iter->pos, 1); }
/** * Gets the reply, or returns #NULL if none has been received * yet. Ownership of the reply message passes to the caller. This * function can only be called once per pending call, since the reply * message is tranferred to the caller. * * @param pending the pending call * @returns the reply message or #NULL. */ DBusMessage* dbus_pending_call_steal_reply (DBusPendingCall *pending) { DBusMessage *message; _dbus_return_val_if_fail (pending != NULL, NULL); _dbus_return_val_if_fail (pending->completed, NULL); _dbus_return_val_if_fail (pending->reply != NULL, NULL); CONNECTION_LOCK (pending->connection); message = pending->reply; pending->reply = NULL; CONNECTION_UNLOCK (pending->connection); return message; }
/** * A "basic type" is a somewhat arbitrary concept, but the intent is * to include those types that are fully-specified by a single * typecode, with no additional type information or nested values. So * all numbers and strings are basic types and structs, arrays, and * variants are not basic types. #DBUS_TYPE_INVALID is not a basic * type. * * This function will crash if passed a typecode that isn't * in dbus-protocol.h * * @returns #TRUE if type is basic */ dbus_bool_t dbus_type_is_basic (int typecode) { /* only reasonable (non-line-noise) typecodes are allowed */ _dbus_return_val_if_fail (_dbus_type_is_valid (typecode) || typecode == DBUS_TYPE_INVALID, FALSE); /* everything that isn't invalid or a container */ return !(typecode == DBUS_TYPE_INVALID || TYPE_IS_CONTAINER (typecode)); }
/** * Returns a socket to be watched, on UNIX this will return -1 if our * transport is not socket-based so dbus_watch_get_unix_fd() is * preferred. * * On Windows, dbus_watch_get_unix_fd() returns -1 but this function * returns a Winsock socket (assuming the transport is socket-based, * as it always is for now). * * @param watch the DBusWatch object. * @returns the socket to watch. */ int dbus_watch_get_socket (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, -1); #ifdef DBUS_UNIX return watch->fd; #else return _dbus_socket_get_int (watch->fd); #endif }
/** * Checks whether the error is set and has the given * name. * @param error the error * @param name the name * @returns #TRUE if the given named error occurred */ dbus_bool_t dbus_error_has_name (const DBusError *error, const char *name) { _dbus_return_val_if_fail (error != NULL, FALSE); _dbus_return_val_if_fail (name != NULL, FALSE); _dbus_assert ((error->name != NULL && error->message != NULL) || (error->name == NULL && error->message == NULL)); if (error->name != NULL) { DBusString str1, str2; _dbus_string_init_const (&str1, error->name); _dbus_string_init_const (&str2, name); return _dbus_string_equal (&str1, &str2); } else return FALSE; }
/** * Checks whether the pending call has received a reply * yet, or not. * * @param pending the pending call * @returns #TRUE if a reply has been received */ dbus_bool_t dbus_pending_call_get_completed (DBusPendingCall *pending) { dbus_bool_t completed; _dbus_return_val_if_fail (pending != NULL, FALSE); CONNECTION_LOCK (pending->connection); completed = pending->completed; CONNECTION_UNLOCK (pending->connection); return completed; }
/** * Returns the address of the server, as a newly-allocated * string which must be freed by the caller. * * @param server the server * @returns the address or #NULL if no memory */ char* dbus_server_get_address (DBusServer *server) { char *retval; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); retval = _dbus_strdup (server->address); SERVER_UNLOCK (server); return retval; }
/** * Returns #TRUE if the server is still listening for new connections. * * @param server the server. */ dbus_bool_t dbus_server_get_is_connected (DBusServer *server) { dbus_bool_t retval; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); retval = !server->disconnected; SERVER_UNLOCK (server); return retval; }
/** * Gets the unique name of the connection. Only possible after the * connection has been registered with the message bus. * * The name remains valid for the duration of the connection and * should not be freed by the caller. * * @param connection the connection * @returns the unique name or NULL on error */ const char* dbus_bus_get_unique_name (DBusConnection *connection) { BusData *bd; _dbus_return_val_if_fail (connection != NULL, NULL); bd = ensure_bus_data (connection); if (bd == NULL) return NULL; return bd->unique_name; }
/** * Increments the reference count on a pending call. * * @param pending the pending call object * @returns the pending call object */ DBusPendingCall * dbus_pending_call_ref (DBusPendingCall *pending) { dbus_int32_t old_refcount; _dbus_return_val_if_fail (pending != NULL, NULL); old_refcount = _dbus_atomic_inc (&pending->refcount); _dbus_pending_call_trace_ref (pending, old_refcount, old_refcount + 1, "ref"); return pending; }
/** * Returns the unique ID of the server, as a newly-allocated * string which must be freed by the caller. This ID is * normally used by clients to tell when two #DBusConnection * would be equivalent (because the server address passed * to dbus_connection_open() will have the same guid in the * two cases). dbus_connection_open() can re-use an existing * connection with the same ID instead of opening a new * connection. * * This is an ID unique to each #DBusServer. Remember that * a #DBusServer represents only one mode of connecting, * so e.g. a bus daemon can listen on multiple addresses * which will mean it has multiple #DBusServer each with * their own ID. * * The ID is not a UUID in the sense of RFC4122; the details * are explained in the D-Bus specification. * * @param server the server * @returns the id of the server or #NULL if no memory */ char* dbus_server_get_id (DBusServer *server) { char *retval; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); retval = NULL; _dbus_string_copy_data (&server->guid_hex, &retval); SERVER_UNLOCK (server); return retval; }
/** * Returns a UNIX file descriptor to be watched, * which may be a pipe, socket, or other type of * descriptor. On UNIX this is preferred to * dbus_watch_get_socket() since it works with * more kinds of #DBusWatch. * * Always returns -1 on Windows. On Windows you use * dbus_watch_get_socket() to get a Winsock socket to watch. * * @param watch the DBusWatch object. * @returns the file descriptor to watch. */ int dbus_watch_get_unix_fd (DBusWatch *watch) { _dbus_return_val_if_fail (watch != NULL, -1); /* FIXME remove #ifdef and do this on a lower level * (watch should have set_socket and set_unix_fd and track * which it has, and the transport should provide the * appropriate watch type) */ #ifdef DBUS_UNIX return watch->fd; #else return dbus_watch_get_socket( watch ); #endif }