Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

dbus-server-debug-pipe.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */ 00002 /* dbus-server-debug-pipe.c In-proc debug server implementation 00003 * 00004 * Copyright (C) 2003 CodeFactory AB 00005 * Copyright (C) 2003, 2004 Red Hat, Inc. 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 * 00023 */ 00024 00025 #include "dbus-internals.h" 00026 #include "dbus-server-debug-pipe.h" 00027 #include "dbus-transport-unix.h" 00028 #include "dbus-connection-internal.h" 00029 #include "dbus-hash.h" 00030 #include "dbus-string.h" 00031 #include "dbus-protocol.h" 00032 00033 #ifdef DBUS_BUILD_TESTS 00034 00049 typedef struct DBusServerDebugPipe DBusServerDebugPipe; 00050 00055 struct DBusServerDebugPipe 00056 { 00057 DBusServer base; 00059 char *name; 00061 dbus_bool_t disconnected; 00062 }; 00063 00064 /* FIXME not threadsafe (right now the test suite doesn't use threads anyhow ) */ 00065 static DBusHashTable *server_pipe_hash; 00066 static int server_pipe_hash_refcount = 0; 00067 00068 static dbus_bool_t 00069 pipe_hash_ref (void) 00070 { 00071 if (!server_pipe_hash) 00072 { 00073 _dbus_assert (server_pipe_hash_refcount == 0); 00074 00075 server_pipe_hash = _dbus_hash_table_new (DBUS_HASH_STRING, NULL, NULL); 00076 00077 if (!server_pipe_hash) 00078 return FALSE; 00079 } 00080 00081 server_pipe_hash_refcount = 1; 00082 00083 return TRUE; 00084 } 00085 00086 static void 00087 pipe_hash_unref (void) 00088 { 00089 _dbus_assert (server_pipe_hash != NULL); 00090 _dbus_assert (server_pipe_hash_refcount > 0); 00091 00092 server_pipe_hash_refcount -= 1; 00093 if (server_pipe_hash_refcount == 0) 00094 { 00095 _dbus_hash_table_unref (server_pipe_hash); 00096 server_pipe_hash = NULL; 00097 } 00098 } 00099 00100 static void 00101 debug_finalize (DBusServer *server) 00102 { 00103 DBusServerDebugPipe *debug_server = (DBusServerDebugPipe*) server; 00104 00105 pipe_hash_unref (); 00106 00107 _dbus_server_finalize_base (server); 00108 00109 dbus_free (debug_server->name); 00110 dbus_free (server); 00111 } 00112 00113 static void 00114 debug_disconnect (DBusServer *server) 00115 { 00116 ((DBusServerDebugPipe*)server)->disconnected = TRUE; 00117 } 00118 00119 static DBusServerVTable debug_vtable = { 00120 debug_finalize, 00121 debug_disconnect 00122 }; 00123 00131 DBusServer* 00132 _dbus_server_debug_pipe_new (const char *server_name, 00133 DBusError *error) 00134 { 00135 DBusServerDebugPipe *debug_server; 00136 DBusString address; 00137 00138 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00139 00140 if (!pipe_hash_ref ()) 00141 return NULL; 00142 00143 if (_dbus_hash_table_lookup_string (server_pipe_hash, server_name) != NULL) 00144 { 00145 dbus_set_error (error, DBUS_ERROR_ADDRESS_IN_USE, NULL); 00146 pipe_hash_unref (); 00147 return NULL; 00148 } 00149 00150 debug_server = dbus_new0 (DBusServerDebugPipe, 1); 00151 if (debug_server == NULL) 00152 goto nomem_0; 00153 00154 if (!_dbus_string_init (&address)) 00155 goto nomem_1; 00156 00157 if (!_dbus_string_append (&address, "debug-pipe:name=") || 00158 !_dbus_string_append (&address, server_name)) 00159 goto nomem_2; 00160 00161 debug_server->name = _dbus_strdup (server_name); 00162 if (debug_server->name == NULL) 00163 goto nomem_2; 00164 00165 if (!_dbus_server_init_base (&debug_server->base, 00166 &debug_vtable, &address)) 00167 goto nomem_3; 00168 00169 if (!_dbus_hash_table_insert_string (server_pipe_hash, 00170 debug_server->name, 00171 debug_server)) 00172 goto nomem_4; 00173 00174 _dbus_string_free (&address); 00175 00176 /* server keeps the pipe hash ref */ 00177 00178 return (DBusServer *)debug_server; 00179 00180 nomem_4: 00181 _dbus_server_finalize_base (&debug_server->base); 00182 nomem_3: 00183 dbus_free (debug_server->name); 00184 nomem_2: 00185 _dbus_string_free (&address); 00186 nomem_1: 00187 dbus_free (debug_server); 00188 nomem_0: 00189 pipe_hash_unref (); 00190 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00191 return NULL; 00192 } 00193 00203 DBusTransport* 00204 _dbus_transport_debug_pipe_new (const char *server_name, 00205 DBusError *error) 00206 { 00207 DBusTransport *client_transport; 00208 DBusTransport *server_transport; 00209 DBusConnection *connection; 00210 int client_fd, server_fd; 00211 DBusServer *server; 00212 DBusString address; 00213 00214 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00215 00216 if (server_pipe_hash == NULL) 00217 { 00218 dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL); 00219 return NULL; 00220 } 00221 00222 server = _dbus_hash_table_lookup_string (server_pipe_hash, 00223 server_name); 00224 if (server == NULL || 00225 ((DBusServerDebugPipe*)server)->disconnected) 00226 { 00227 dbus_set_error (error, DBUS_ERROR_NO_SERVER, NULL); 00228 return NULL; 00229 } 00230 00231 if (!_dbus_string_init (&address)) 00232 { 00233 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00234 return NULL; 00235 } 00236 00237 if (!_dbus_string_append (&address, "debug-pipe:name=") || 00238 !_dbus_string_append (&address, server_name)) 00239 { 00240 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00241 _dbus_string_free (&address); 00242 return NULL; 00243 } 00244 00245 if (!_dbus_full_duplex_pipe (&client_fd, &server_fd, FALSE, 00246 NULL)) 00247 { 00248 _dbus_verbose ("failed to create full duplex pipe\n"); 00249 dbus_set_error (error, DBUS_ERROR_FAILED, "Could not create full-duplex pipe"); 00250 _dbus_string_free (&address); 00251 return NULL; 00252 } 00253 00254 _dbus_fd_set_close_on_exec (client_fd); 00255 _dbus_fd_set_close_on_exec (server_fd); 00256 00257 client_transport = _dbus_transport_new_for_fd (client_fd, 00258 FALSE, &address); 00259 if (client_transport == NULL) 00260 { 00261 _dbus_close (client_fd, NULL); 00262 _dbus_close (server_fd, NULL); 00263 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00264 _dbus_string_free (&address); 00265 return NULL; 00266 } 00267 00268 _dbus_string_free (&address); 00269 00270 client_fd = -1; 00271 00272 server_transport = _dbus_transport_new_for_fd (server_fd, 00273 TRUE, NULL); 00274 if (server_transport == NULL) 00275 { 00276 _dbus_transport_unref (client_transport); 00277 _dbus_close (server_fd, NULL); 00278 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00279 return NULL; 00280 } 00281 00282 server_fd = -1; 00283 00284 if (!_dbus_transport_set_auth_mechanisms (server_transport, 00285 (const char**) server->auth_mechanisms)) 00286 { 00287 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00288 _dbus_transport_unref (server_transport); 00289 _dbus_transport_unref (client_transport); 00290 return FALSE; 00291 } 00292 00293 connection = _dbus_connection_new_for_transport (server_transport); 00294 _dbus_transport_unref (server_transport); 00295 server_transport = NULL; 00296 00297 if (connection == NULL) 00298 { 00299 _dbus_transport_unref (client_transport); 00300 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00301 return NULL; 00302 } 00303 00304 /* See if someone wants to handle this new connection, 00305 * self-referencing for paranoia 00306 */ 00307 if (server->new_connection_function) 00308 { 00309 dbus_server_ref (server); 00310 (* server->new_connection_function) (server, connection, 00311 server->new_connection_data); 00312 dbus_server_unref (server); 00313 } 00314 00315 /* If no one grabbed a reference, the connection will die, 00316 * and the client transport will get an immediate disconnect 00317 */ 00318 dbus_connection_unref (connection); 00319 00320 return client_transport; 00321 } 00322 00323 00326 #endif /* DBUS_BUILD_TESTS */ 00327

Generated on Mon Jun 27 07:48:22 2005 for D-BUS by doxygen 1.3.7