/** * Creates a new server listening on the given file descriptor. The * file descriptor should be nonblocking (use * _dbus_set_fd_nonblocking() to make it so). The file descriptor * should be listening for connections, that is, listen() should have * been successfully invoked on it. The server will use accept() to * accept new client connections. * * @param fds list of file descriptors. * @param n_fds number of file descriptors * @param address the server's address * @param noncefile to be used for authentication (NULL if not needed) * @returns the new server, or #NULL if no memory. * */ DBusServer* _dbus_server_new_for_socket (int *fds, int n_fds, const DBusString *address, DBusNonceFile *noncefile) { DBusServerSocket *socket_server; DBusServer *server; int i; socket_server = dbus_new0 (DBusServerSocket, 1); if (socket_server == NULL) return NULL; socket_server->noncefile = noncefile; socket_server->fds = dbus_new (int, n_fds); if (!socket_server->fds) goto failed_0; socket_server->watch = dbus_new0 (DBusWatch *, n_fds); if (!socket_server->watch) goto failed_1; for (i = 0 ; i < n_fds ; i++) { DBusWatch *watch; watch = _dbus_watch_new (fds[i], DBUS_WATCH_READABLE, TRUE, socket_handle_watch, socket_server, NULL); if (watch == NULL) goto failed_2; socket_server->n_fds++; socket_server->fds[i] = fds[i]; socket_server->watch[i] = watch; } if (!_dbus_server_init_base (&socket_server->base, &socket_vtable, address)) goto failed_2; server = (DBusServer*)socket_server; SERVER_LOCK (server); for (i = 0 ; i < n_fds ; i++) { if (!_dbus_server_add_watch (&socket_server->base, socket_server->watch[i])) { int j; for (j = 0 ; j < i ; j++) _dbus_server_remove_watch (server, socket_server->watch[j]); SERVER_UNLOCK (server); _dbus_server_finalize_base (&socket_server->base); goto failed_2; } } SERVER_UNLOCK (server); return (DBusServer*) socket_server; failed_2: for (i = 0 ; i < n_fds ; i++) { if (socket_server->watch[i] != NULL) { _dbus_watch_unref (socket_server->watch[i]); socket_server->watch[i] = NULL; } } dbus_free (socket_server->watch); failed_1: dbus_free (socket_server->fds); failed_0: dbus_free (socket_server); return NULL; }
/** * Creates a new debug server using an in-process pipe * * @param server_name the name of the server. * @param error address where an error can be returned. * @returns a new server, or #NULL on failure. */ DBusServer* _dbus_server_debug_pipe_new (const char *server_name, DBusError *error) { DBusServerDebugPipe *debug_server; DBusString address; DBusString name_str; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!pipe_hash_ref ()) return NULL; if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL) { dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL); pipe_hash_unref (); return NULL; } debug_server = dbus_new0 (DBusServerDebugPipe, 1); if (debug_server == NULL) goto nomem_0; if (!_dbus_string_init (&address)) goto nomem_1; _dbus_string_init_const (&name_str, server_name); if (!_dbus_string_append (&address, "debug-pipe:name=") || !_dbus_address_append_escaped (&address, &name_str)) goto nomem_2; debug_server->name = _dbus_strdup (server_name); if (debug_server->name == NULL) goto nomem_2; if (!_dbus_server_init_base (&debug_server->base, &debug_vtable, &address)) goto nomem_3; if (!_dbus_hash_table_insert_string (server_pipe_hash, debug_server->name, debug_server)) goto nomem_4; _dbus_string_free (&address); /* server keeps the pipe hash ref */ return (DBusServer *)debug_server; nomem_4: _dbus_server_finalize_base (&debug_server->base); nomem_3: dbus_free (debug_server->name); nomem_2: _dbus_string_free (&address); nomem_1: dbus_free (debug_server); nomem_0: pipe_hash_unref (); dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); return NULL; }