00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
00305
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
00316
00317
00318 dbus_connection_unref (connection);
00319
00320 return client_transport;
00321 }
00322
00323
00326 #endif
00327