/** * Releases the server's address and stops listening for * new clients. If called more than once, only the first * call has an effect. Does not modify the server's * reference count. * * @param server the server. */ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); dbus_server_ref (server); SERVER_LOCK (server); _dbus_server_disconnect_unlocked (server); SERVER_UNLOCK (server); dbus_server_unref (server); }
static ServerData* serverdata_new (DBusLoop *loop, DBusServer *server) { ServerData *sd; sd = dbus_new0 (ServerData, 1); if (sd == NULL) return NULL; sd->loop = loop; sd->server = server; dbus_server_ref (sd->server); _dbus_loop_ref (sd->loop); return sd; }
/* * watch_handler * Callback for D-BUS to handle messages on a file-descriptor */ static void sbus_watch_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *data) { struct sbus_watch_ctx *watch = talloc_get_type(data, struct sbus_watch_ctx); enum dbus_conn_type type; union dbus_conn_pointer dbus_p; /* conn may get freed inside a handle, save the data we need for later */ type = watch->conn->type; dbus_p = watch->conn->dbus; /* Take a reference while handling watch */ if (type == SBUS_SERVER) { dbus_server_ref(dbus_p.server); } else { dbus_connection_ref(dbus_p.conn); } /* Fire if readable */ if (flags & TEVENT_FD_READ) { if (watch->dbus_read_watch) { dbus_watch_handle(watch->dbus_read_watch, DBUS_WATCH_READABLE); } } /* Fire if writeable */ if (flags & TEVENT_FD_WRITE) { if (watch->dbus_write_watch) { dbus_watch_handle(watch->dbus_write_watch, DBUS_WATCH_WRITABLE); } } /* Release reference once done */ if (type == SBUS_SERVER) { dbus_server_unref(dbus_p.server); } else { dbus_connection_unref(dbus_p.conn); } }
/** * Releases the server's address and stops listening for * new clients. If called more than once, only the first * call has an effect. Does not modify the server's * reference count. * * @param server the server. */ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); dbus_server_ref (server); SERVER_LOCK (server); _dbus_assert (server->vtable->disconnect != NULL); if (!server->disconnected) { /* this has to be first so recursive calls to disconnect don't happen */ server->disconnected = TRUE; (* server->vtable->disconnect) (server); } SERVER_UNLOCK (server); dbus_server_unref (server); }
/** * Creates the client-side transport for * a debug-pipe connection connected to the * given debug-pipe server name. * * @param server_name name of server to connect to * @param error address where an error can be returned. * @returns #NULL on no memory or transport */ DBusTransport* _dbus_transport_debug_pipe_new (const char *server_name, DBusError *error) { DBusTransport *client_transport; DBusTransport *server_transport; DBusConnection *connection; int client_fd, server_fd; DBusServer *server; DBusString address; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (server_pipe_hash == NULL) { dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL); return NULL; } server = _dbus_hash_table_lookup_string (server_pipe_hash, server_name); if (server == NULL || ((DBusServerDebugPipe*)server)->disconnected) { dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL); return NULL; } if (!_dbus_string_init (&address)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } if (!_dbus_string_append (&address, "debug-pipe:name=") || !_dbus_string_append (&address, server_name)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&address); return NULL; } if (!_dbus_full_duplex_pipe (&client_fd, &server_fd, FALSE, NULL)) { _dbus_verbose ("failed to create full duplex pipe\n"); dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create full-duplex pipe"); _dbus_string_free (&address); return NULL; } _dbus_fd_set_close_on_exec (client_fd); _dbus_fd_set_close_on_exec (server_fd); client_transport = _dbus_transport_new_for_socket (client_fd, NULL, &address); if (client_transport == NULL) { _dbus_close_socket (client_fd, NULL); _dbus_close_socket (server_fd, NULL); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_string_free (&address); return NULL; } _dbus_string_free (&address); client_fd = -1; server_transport = _dbus_transport_new_for_socket (server_fd, &server->guid_hex, NULL); if (server_transport == NULL) { _dbus_transport_unref (client_transport); _dbus_close_socket (server_fd, NULL); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } server_fd = -1; if (!_dbus_transport_set_auth_mechanisms (server_transport, (const char**) server->auth_mechanisms)) { dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); _dbus_transport_unref (server_transport); _dbus_transport_unref (client_transport); return NULL; } connection = _dbus_connection_new_for_transport (server_transport); _dbus_transport_unref (server_transport); server_transport = NULL; if (connection == NULL) { _dbus_transport_unref (client_transport); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; } /* See if someone wants to handle this new connection, * self-referencing for paranoia */ if (server->new_connection_function) { dbus_server_ref (server); (* server->new_connection_function) (server, connection, server->new_connection_data); dbus_server_unref (server); } /* If no one grabbed a reference, the connection will die, * and the client transport will get an immediate disconnect */ _dbus_connection_close_if_only_one_ref (connection); dbus_connection_unref (connection); return client_transport; }