<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>dbus-server-unix.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>dbus-server-unix.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-server-unix.c Server implementation for Unix network protocols.</font> 00003 <font class="comment"> *</font> 00004 <font class="comment"> * Copyright (C) 2002, 2003 Red Hat Inc.</font> 00005 <font class="comment"> *</font> 00006 <font class="comment"> * Licensed under the Academic Free License version 2.0</font> 00007 <font class="comment"> * </font> 00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font> 00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font> 00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font> 00011 <font class="comment"> * (at your option) any later version.</font> 00012 <font class="comment"> *</font> 00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font> 00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</font> 00016 <font class="comment"> * GNU General Public License for more details.</font> 00017 <font class="comment"> * </font> 00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font> 00019 <font class="comment"> * along with this program; if not, write to the Free Software</font> 00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00021 <font class="comment"> *</font> 00022 <font class="comment"> */</font> 00023 00024 <font class="preprocessor">#include "dbus-internals.h"</font> 00025 <font class="preprocessor">#include "dbus-server-unix.h"</font> 00026 <font class="preprocessor">#include "dbus-transport-unix.h"</font> 00027 <font class="preprocessor">#include "dbus-connection-internal.h"</font> 00028 <font class="preprocessor">#include "dbus-string.h"</font> 00029 <font class="preprocessor">#include <sys/types.h></font> 00030 <font class="preprocessor">#include <unistd.h></font> 00031 <a name="l00043"></a><a class="code" href="group__DBusServerUnix.html#a0">00043</a> <font class="keyword">typedef</font> <font class="keyword">struct </font><a class="code" href="structDBusServerUnix.html">DBusServerUnix</a> DBusServerUnix; 00044 <a name="l00049"></a><a class="code" href="structDBusServerUnix.html">00049</a> <font class="keyword">struct </font>DBusServerUnix 00050 { <a name="l00051"></a><a class="code" href="structDBusServerUnix.html#m0">00051</a> <a class="code" href="structDBusServer.html">DBusServer</a> <a class="code" href="structDBusServerUnix.html#m0">base</a>; <a name="l00052"></a><a class="code" href="structDBusServerUnix.html#m1">00052</a> <font class="keywordtype">int</font> <a class="code" href="structDBusServerUnix.html#m1">fd</a>; <a name="l00053"></a><a class="code" href="structDBusServerUnix.html#m2">00053</a> <a class="code" href="structDBusWatch.html">DBusWatch</a> *<a class="code" href="structDBusServerUnix.html#m2">watch</a>; <a name="l00054"></a><a class="code" href="structDBusServerUnix.html#m3">00054</a> <font class="keywordtype">char</font> *<a class="code" href="structDBusServerUnix.html#m3">socket_name</a>; 00055 }; 00056 00057 <font class="keyword">static</font> <font class="keywordtype">void</font> 00058 unix_finalize (<a class="code" href="structDBusServer.html">DBusServer</a> *server) 00059 { 00060 DBusServerUnix *unix_server = (DBusServerUnix*) server; 00061 00062 dbus_free (unix_server-><a class="code" href="structDBusServerUnix.html#m3">socket_name</a>); 00063 00064 _dbus_server_finalize_base (server); 00065 00066 dbus_free (server); 00067 } 00068 00074 <font class="comment">/* Return value is just for memory, not other failures. */</font> 00075 <font class="keyword">static</font> dbus_bool_t 00076 handle_new_client_fd (<a class="code" href="structDBusServer.html">DBusServer</a> *server, 00077 <font class="keywordtype">int</font> client_fd) 00078 { 00079 <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection; 00080 <a class="code" href="structDBusTransport.html">DBusTransport</a> *transport; 00081 00082 _dbus_verbose (<font class="stringliteral">"Creating new client connection with fd %d\n"</font>, client_fd); 00083 00084 <font class="keywordflow">if</font> (!_dbus_set_fd_nonblocking (client_fd, NULL)) 00085 <font class="keywordflow">return</font> TRUE; 00086 00087 transport = _dbus_transport_new_for_fd (client_fd, TRUE, NULL); 00088 <font class="keywordflow">if</font> (transport == NULL) 00089 { 00090 close (client_fd); 00091 <font class="keywordflow">return</font> FALSE; 00092 } 00093 00094 <font class="keywordflow">if</font> (!_dbus_transport_set_auth_mechanisms (transport, 00095 (<font class="keyword">const</font> <font class="keywordtype">char</font> **) server-><a class="code" href="structDBusServer.html#m10">auth_mechanisms</a>)) 00096 { 00097 _dbus_transport_unref (transport); 00098 <font class="keywordflow">return</font> FALSE; 00099 } 00100 00101 <font class="comment">/* note that client_fd is now owned by the transport, and will be</font> 00102 <font class="comment"> * closed on transport disconnection/finalization</font> 00103 <font class="comment"> */</font> 00104 00105 connection = _dbus_connection_new_for_transport (transport); 00106 _dbus_transport_unref (transport); 00107 00108 <font class="keywordflow">if</font> (connection == NULL) 00109 <font class="keywordflow">return</font> FALSE; 00110 00111 <font class="comment">/* See if someone wants to handle this new connection,</font> 00112 <font class="comment"> * self-referencing for paranoia</font> 00113 <font class="comment"> */</font> 00114 <font class="keywordflow">if</font> (server-><a class="code" href="structDBusServer.html#m7">new_connection_function</a>) 00115 { 00116 dbus_server_ref (server); 00117 00118 (* server-><a class="code" href="structDBusServer.html#m7">new_connection_function</a>) (server, connection, 00119 server-><a class="code" href="structDBusServer.html#m8">new_connection_data</a>); 00120 dbus_server_unref (server); 00121 } 00122 00123 <font class="comment">/* If no one grabbed a reference, the connection will die. */</font> 00124 dbus_connection_unref (connection); 00125 00126 <font class="keywordflow">return</font> TRUE; 00127 } 00128 00129 <font class="keyword">static</font> dbus_bool_t 00130 unix_handle_watch (<a class="code" href="structDBusWatch.html">DBusWatch</a> *watch, 00131 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> flags, 00132 <font class="keywordtype">void</font> *data) 00133 { 00134 <a class="code" href="structDBusServer.html">DBusServer</a> *server = data; 00135 DBusServerUnix *unix_server = data; 00136 00137 _dbus_assert (watch == unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a>); 00138 00139 _dbus_verbose (<font class="stringliteral">"Handling client connection, flags 0x%x\n"</font>, flags); 00140 00141 <font class="keywordflow">if</font> (flags & DBUS_WATCH_READABLE) 00142 { 00143 <font class="keywordtype">int</font> client_fd; 00144 <font class="keywordtype">int</font> listen_fd; 00145 00146 listen_fd = dbus_watch_get_fd (watch); 00147 00148 client_fd = _dbus_accept (listen_fd); 00149 00150 <font class="keywordflow">if</font> (client_fd < 0) 00151 { 00152 <font class="comment">/* EINTR handled for us */</font> 00153 00154 <font class="keywordflow">if</font> (errno == EAGAIN || errno == EWOULDBLOCK) 00155 _dbus_verbose (<font class="stringliteral">"No client available to accept after all\n"</font>); 00156 <font class="keywordflow">else</font> 00157 _dbus_verbose (<font class="stringliteral">"Failed to accept a client connection: %s\n"</font>, 00158 _dbus_strerror (errno)); 00159 } 00160 <font class="keywordflow">else</font> 00161 { 00162 _dbus_fd_set_close_on_exec (client_fd); 00163 00164 <font class="keywordflow">if</font> (!handle_new_client_fd (server, client_fd)) 00165 _dbus_verbose (<font class="stringliteral">"Rejected client connection due to lack of memory\n"</font>); 00166 } 00167 } 00168 00169 <font class="keywordflow">if</font> (flags & DBUS_WATCH_ERROR) 00170 _dbus_verbose (<font class="stringliteral">"Error on server listening socket\n"</font>); 00171 00172 <font class="keywordflow">if</font> (flags & DBUS_WATCH_HANGUP) 00173 _dbus_verbose (<font class="stringliteral">"Hangup on server listening socket\n"</font>); 00174 00175 <font class="keywordflow">return</font> TRUE; 00176 } 00177 00178 <font class="keyword">static</font> <font class="keywordtype">void</font> 00179 unix_disconnect (<a class="code" href="structDBusServer.html">DBusServer</a> *server) 00180 { 00181 DBusServerUnix *unix_server = (DBusServerUnix*) server; 00182 00183 <font class="keywordflow">if</font> (unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a>) 00184 { 00185 _dbus_server_remove_watch (server, 00186 unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a>); 00187 _dbus_watch_unref (unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a>); 00188 unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a> = NULL; 00189 } 00190 00191 close (unix_server-><a class="code" href="structDBusServerUnix.html#m1">fd</a>); 00192 unix_server-><a class="code" href="structDBusServerUnix.html#m1">fd</a> = -1; 00193 00194 <font class="keywordflow">if</font> (unix_server-><a class="code" href="structDBusServerUnix.html#m3">socket_name</a> != NULL) 00195 { 00196 <a class="code" href="structDBusString.html">DBusString</a> tmp; 00197 _dbus_string_init_const (&tmp, unix_server-><a class="code" href="structDBusServerUnix.html#m3">socket_name</a>); 00198 _dbus_delete_file (&tmp, NULL); 00199 } 00200 } 00201 00202 <font class="keyword">static</font> <a class="code" href="structDBusServerVTable.html">DBusServerVTable</a> unix_vtable = { 00203 unix_finalize, 00204 unix_disconnect 00205 }; 00206 00220 <a class="code" href="structDBusServer.html">DBusServer</a>* <a name="l00221"></a><a class="code" href="group__DBusServerUnix.html#a6">00221</a> _dbus_server_new_for_fd (<font class="keywordtype">int</font> fd, 00222 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *address) 00223 { 00224 DBusServerUnix *unix_server; 00225 <a class="code" href="structDBusWatch.html">DBusWatch</a> *watch; 00226 00227 unix_server = dbus_new0 (DBusServerUnix, 1); 00228 <font class="keywordflow">if</font> (unix_server == NULL) 00229 <font class="keywordflow">return</font> NULL; 00230 00231 watch = _dbus_watch_new (fd, 00232 DBUS_WATCH_READABLE, 00233 TRUE, 00234 unix_handle_watch, unix_server, 00235 NULL); 00236 <font class="keywordflow">if</font> (watch == NULL) 00237 { 00238 dbus_free (unix_server); 00239 <font class="keywordflow">return</font> NULL; 00240 } 00241 00242 <font class="keywordflow">if</font> (!_dbus_server_init_base (&unix_server-><a class="code" href="structDBusServerUnix.html#m0">base</a>, 00243 &unix_vtable, address)) 00244 { 00245 _dbus_watch_unref (watch); 00246 dbus_free (unix_server); 00247 <font class="keywordflow">return</font> NULL; 00248 } 00249 00250 <font class="keywordflow">if</font> (!_dbus_server_add_watch (&unix_server-><a class="code" href="structDBusServerUnix.html#m0">base</a>, 00251 watch)) 00252 { 00253 _dbus_server_finalize_base (&unix_server-><a class="code" href="structDBusServerUnix.html#m0">base</a>); 00254 _dbus_watch_unref (watch); 00255 dbus_free (unix_server); 00256 <font class="keywordflow">return</font> NULL; 00257 } 00258 00259 unix_server-><a class="code" href="structDBusServerUnix.html#m1">fd</a> = fd; 00260 unix_server-><a class="code" href="structDBusServerUnix.html#m2">watch</a> = watch; 00261 00262 <font class="keywordflow">return</font> (<a class="code" href="structDBusServer.html">DBusServer</a>*) unix_server; 00263 } 00264 00273 <a class="code" href="structDBusServer.html">DBusServer</a>* <a name="l00274"></a><a class="code" href="group__DBusServerUnix.html#a7">00274</a> _dbus_server_new_for_domain_socket (<font class="keyword">const</font> <font class="keywordtype">char</font> *path, 00275 dbus_bool_t <font class="keyword">abstract</font>, 00276 <a class="code" href="structDBusError.html">DBusError</a> *error) 00277 { 00278 <a class="code" href="structDBusServer.html">DBusServer</a> *server; 00279 DBusServerUnix *unix_server; 00280 <font class="keywordtype">int</font> listen_fd; 00281 <a class="code" href="structDBusString.html">DBusString</a> address; 00282 <font class="keywordtype">char</font> *path_copy; 00283 00284 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00285 00286 <font class="keywordflow">if</font> (!_dbus_string_init (&address)) 00287 { 00288 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00289 <font class="keywordflow">return</font> NULL; 00290 } 00291 00292 <font class="keywordflow">if</font> ((<font class="keyword">abstract</font> && 00293 !_dbus_string_append (&address, <font class="stringliteral">"unix:abstract="</font>)) || 00294 (!<font class="keyword">abstract</font> && 00295 !_dbus_string_append (&address, <font class="stringliteral">"unix:path="</font>)) || 00296 !_dbus_string_append (&address, path)) 00297 { 00298 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00299 <font class="keywordflow">goto</font> failed_0; 00300 } 00301 00302 path_copy = _dbus_strdup (path); 00303 <font class="keywordflow">if</font> (path_copy == NULL) 00304 { 00305 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00306 <font class="keywordflow">goto</font> failed_0; 00307 } 00308 00309 listen_fd = _dbus_listen_unix_socket (path, <font class="keyword">abstract</font>, error); 00310 _dbus_fd_set_close_on_exec (listen_fd); 00311 00312 <font class="keywordflow">if</font> (listen_fd < 0) 00313 { 00314 _DBUS_ASSERT_ERROR_IS_SET (error); 00315 <font class="keywordflow">goto</font> failed_1; 00316 } 00317 00318 server = _dbus_server_new_for_fd (listen_fd, &address); 00319 <font class="keywordflow">if</font> (server == NULL) 00320 { 00321 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00322 <font class="keywordflow">goto</font> failed_2; 00323 } 00324 00325 unix_server = (DBusServerUnix*) server; 00326 unix_server-><a class="code" href="structDBusServerUnix.html#m3">socket_name</a> = path_copy; 00327 00328 _dbus_string_free (&address); 00329 00330 <font class="keywordflow">return</font> server; 00331 00332 failed_2: 00333 _dbus_close (listen_fd, NULL); 00334 failed_1: 00335 dbus_free (path_copy); 00336 failed_0: 00337 _dbus_string_free (&address); 00338 00339 <font class="keywordflow">return</font> NULL; 00340 } 00341 00351 <a class="code" href="structDBusServer.html">DBusServer</a>* <a name="l00352"></a><a class="code" href="group__DBusServerUnix.html#a8">00352</a> _dbus_server_new_for_tcp_socket (<font class="keyword">const</font> <font class="keywordtype">char</font> *host, 00353 dbus_uint32_t port, 00354 <a class="code" href="structDBusError.html">DBusError</a> *error) 00355 { 00356 <a class="code" href="structDBusServer.html">DBusServer</a> *server; 00357 <font class="keywordtype">int</font> listen_fd; 00358 <a class="code" href="structDBusString.html">DBusString</a> address; 00359 00360 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 00361 00362 <font class="keywordflow">if</font> (!_dbus_string_init (&address)) 00363 { 00364 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00365 <font class="keywordflow">return</font> NULL; 00366 } 00367 00368 <font class="keywordflow">if</font> (host == NULL) 00369 host = <font class="stringliteral">"localhost"</font>; 00370 00371 <font class="keywordflow">if</font> (!_dbus_string_append (&address, <font class="stringliteral">"tcp:host="</font>) || 00372 !_dbus_string_append (&address, host) || 00373 !_dbus_string_append (&address, <font class="stringliteral">",port="</font>) || 00374 !_dbus_string_append_int (&address, port)) 00375 { 00376 _dbus_string_free (&address); 00377 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00378 <font class="keywordflow">return</font> NULL; 00379 } 00380 00381 listen_fd = _dbus_listen_tcp_socket (host, port, error); 00382 _dbus_fd_set_close_on_exec (listen_fd); 00383 00384 <font class="keywordflow">if</font> (listen_fd < 0) 00385 { 00386 _dbus_string_free (&address); 00387 <font class="keywordflow">return</font> NULL; 00388 } 00389 00390 server = _dbus_server_new_for_fd (listen_fd, &address); 00391 <font class="keywordflow">if</font> (server == NULL) 00392 { 00393 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 00394 close (listen_fd); 00395 _dbus_string_free (&address); 00396 <font class="keywordflow">return</font> NULL; 00397 } 00398 00399 _dbus_string_free (&address); 00400 00401 <font class="keywordflow">return</font> server; 00402 00403 00404 } 00405 </pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:26 2004 for D-BUS by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>