<!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-transport-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-transport-unix.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font> 00002 <font class="comment">/* dbus-transport-unix.c UNIX socket subclasses of DBusTransport</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-connection-internal.h"</font> 00026 <font class="preprocessor">#include "dbus-transport-unix.h"</font> 00027 <font class="preprocessor">#include "dbus-transport-protected.h"</font> 00028 <font class="preprocessor">#include "dbus-watch.h"</font> 00029 00030 <a name="l00042"></a><a class="code" href="group__DBusTransportUnix.html#a0">00042</a> <font class="keyword">typedef</font> <font class="keyword">struct </font><a class="code" href="structDBusTransportUnix.html">DBusTransportUnix</a> DBusTransportUnix; 00043 <a name="l00047"></a><a class="code" href="structDBusTransportUnix.html">00047</a> <font class="keyword">struct </font>DBusTransportUnix 00048 { <a name="l00049"></a><a class="code" href="structDBusTransportUnix.html#m0">00049</a> <a class="code" href="structDBusTransport.html">DBusTransport</a> <a class="code" href="structDBusTransportUnix.html#m0">base</a>; <a name="l00050"></a><a class="code" href="structDBusTransportUnix.html#m1">00050</a> <font class="keywordtype">int</font> <a class="code" href="structDBusTransportUnix.html#m1">fd</a>; <a name="l00051"></a><a class="code" href="structDBusTransportUnix.html#m2">00051</a> <a class="code" href="structDBusWatch.html">DBusWatch</a> *<a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>; <a name="l00052"></a><a class="code" href="structDBusTransportUnix.html#m3">00052</a> <a class="code" href="structDBusWatch.html">DBusWatch</a> *<a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>; <a name="l00054"></a><a class="code" href="structDBusTransportUnix.html#m4">00054</a> <font class="keywordtype">int</font> <a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>; <a name="l00055"></a><a class="code" href="structDBusTransportUnix.html#m5">00055</a> <font class="keywordtype">int</font> <a class="code" href="structDBusTransportUnix.html#m5">max_bytes_written_per_iteration</a>; <a name="l00057"></a><a class="code" href="structDBusTransportUnix.html#m6">00057</a> <font class="keywordtype">int</font> <a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a>; <a name="l00061"></a><a class="code" href="structDBusTransportUnix.html#m7">00061</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>; <a name="l00064"></a><a class="code" href="structDBusTransportUnix.html#m8">00064</a> <a class="code" href="structDBusString.html">DBusString</a> <a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>; 00067 }; 00068 00069 <font class="keyword">static</font> <font class="keywordtype">void</font> 00070 free_watches (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00071 { 00072 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00073 00074 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>) 00075 { 00076 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>) 00077 _dbus_connection_remove_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00078 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>); 00079 _dbus_watch_invalidate (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>); 00080 _dbus_watch_unref (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>); 00081 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> = NULL; 00082 } 00083 00084 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>) 00085 { 00086 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>) 00087 _dbus_connection_remove_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00088 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00089 _dbus_watch_invalidate (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00090 _dbus_watch_unref (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00091 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> = NULL; 00092 } 00093 } 00094 00095 <font class="keyword">static</font> <font class="keywordtype">void</font> 00096 unix_finalize (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00097 { 00098 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00099 00100 free_watches (transport); 00101 00102 _dbus_string_free (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>); 00103 _dbus_string_free (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>); 00104 00105 _dbus_transport_finalize_base (transport); 00106 00107 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> == NULL); 00108 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> == NULL); 00109 00110 dbus_free (transport); 00111 } 00112 00113 <font class="keyword">static</font> <font class="keywordtype">void</font> 00114 check_write_watch (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00115 { 00116 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00117 dbus_bool_t need_write_watch; 00118 00119 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m2">connection</a> == NULL) 00120 <font class="keywordflow">return</font>; 00121 00122 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a>) 00123 { 00124 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> == NULL); 00125 <font class="keywordflow">return</font>; 00126 } 00127 00128 _dbus_transport_ref (transport); 00129 00130 <font class="keywordflow">if</font> (_dbus_transport_get_is_authenticated (transport)) 00131 need_write_watch = transport-><a class="code" href="structDBusTransport.html#m14">messages_need_sending</a>; 00132 <font class="keywordflow">else</font> 00133 need_write_watch = transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a> || 00134 _dbus_auth_do_work (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND; 00135 00136 _dbus_connection_toggle_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00137 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>, 00138 need_write_watch); 00139 00140 _dbus_transport_unref (transport); 00141 } 00142 00143 <font class="keyword">static</font> <font class="keywordtype">void</font> 00144 check_read_watch (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00145 { 00146 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00147 dbus_bool_t need_read_watch; 00148 00149 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m2">connection</a> == NULL) 00150 <font class="keywordflow">return</font>; 00151 00152 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a>) 00153 { 00154 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> == NULL); 00155 <font class="keywordflow">return</font>; 00156 } 00157 00158 _dbus_transport_ref (transport); 00159 00160 <font class="keywordflow">if</font> (_dbus_transport_get_is_authenticated (transport)) 00161 need_read_watch = 00162 _dbus_counter_get_value (transport-><a class="code" href="structDBusTransport.html#m7">live_messages_size</a>) < transport-><a class="code" href="structDBusTransport.html#m6">max_live_messages_size</a>; 00163 <font class="keywordflow">else</font> 00164 need_read_watch = transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a> || 00165 _dbus_auth_do_work (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>) == DBUS_AUTH_STATE_WAITING_FOR_INPUT; 00166 00167 _dbus_connection_toggle_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00168 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>, 00169 need_read_watch); 00170 00171 _dbus_transport_unref (transport); 00172 } 00173 00174 <font class="keyword">static</font> <font class="keywordtype">void</font> 00175 do_io_error (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00176 { 00177 _dbus_transport_ref (transport); 00178 _dbus_transport_disconnect (transport); 00179 _dbus_transport_unref (transport); 00180 } 00181 00182 <font class="comment">/* return value is whether we successfully read any new data. */</font> 00183 <font class="keyword">static</font> dbus_bool_t 00184 read_data_into_auth (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00185 dbus_bool_t *oom) 00186 { 00187 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00188 <a class="code" href="structDBusString.html">DBusString</a> *buffer; 00189 <font class="keywordtype">int</font> bytes_read; 00190 00191 *oom = FALSE; 00192 00193 _dbus_auth_get_buffer (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, &buffer); 00194 00195 bytes_read = _dbus_read (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00196 buffer, unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>); 00197 00198 _dbus_auth_return_buffer (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, buffer, 00199 bytes_read > 0 ? bytes_read : 0); 00200 00201 <font class="keywordflow">if</font> (bytes_read > 0) 00202 { 00203 _dbus_verbose (<font class="stringliteral">" read %d bytes in auth phase\n"</font>, bytes_read); 00204 00205 <font class="keywordflow">return</font> TRUE; 00206 } 00207 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (bytes_read < 0) 00208 { 00209 <font class="comment">/* EINTR already handled for us */</font> 00210 00211 <font class="keywordflow">if</font> (errno == ENOMEM) 00212 { 00213 *oom = TRUE; 00214 } 00215 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (errno == EAGAIN || 00216 errno == EWOULDBLOCK) 00217 ; <font class="comment">/* do nothing, just return FALSE below */</font> 00218 <font class="keywordflow">else</font> 00219 { 00220 _dbus_verbose (<font class="stringliteral">"Error reading from remote app: %s\n"</font>, 00221 _dbus_strerror (errno)); 00222 do_io_error (transport); 00223 } 00224 00225 <font class="keywordflow">return</font> FALSE; 00226 } 00227 <font class="keywordflow">else</font> 00228 { 00229 _dbus_assert (bytes_read == 0); 00230 00231 _dbus_verbose (<font class="stringliteral">"Disconnected from remote app\n"</font>); 00232 do_io_error (transport); 00233 00234 <font class="keywordflow">return</font> FALSE; 00235 } 00236 } 00237 00238 <font class="comment">/* Return value is whether we successfully wrote any bytes */</font> 00239 <font class="keyword">static</font> dbus_bool_t 00240 write_data_from_auth (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00241 { 00242 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00243 <font class="keywordtype">int</font> bytes_written; 00244 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *buffer; 00245 00246 <font class="keywordflow">if</font> (!_dbus_auth_get_bytes_to_send (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, 00247 &buffer)) 00248 <font class="keywordflow">return</font> FALSE; 00249 00250 bytes_written = _dbus_write (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00251 buffer, 00252 0, _dbus_string_get_length (buffer)); 00253 00254 <font class="keywordflow">if</font> (bytes_written > 0) 00255 { 00256 _dbus_auth_bytes_sent (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, bytes_written); 00257 <font class="keywordflow">return</font> TRUE; 00258 } 00259 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (bytes_written < 0) 00260 { 00261 <font class="comment">/* EINTR already handled for us */</font> 00262 00263 <font class="keywordflow">if</font> (errno == EAGAIN || 00264 errno == EWOULDBLOCK) 00265 ; 00266 <font class="keywordflow">else</font> 00267 { 00268 _dbus_verbose (<font class="stringliteral">"Error writing to remote app: %s\n"</font>, 00269 _dbus_strerror (errno)); 00270 do_io_error (transport); 00271 } 00272 } 00273 00274 <font class="keywordflow">return</font> FALSE; 00275 } 00276 00277 <font class="keyword">static</font> <font class="keywordtype">void</font> 00278 exchange_credentials (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00279 dbus_bool_t do_reading, 00280 dbus_bool_t do_writing) 00281 { 00282 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00283 00284 <font class="keywordflow">if</font> (do_writing && transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a>) 00285 { 00286 <font class="keywordflow">if</font> (_dbus_send_credentials_unix_socket (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00287 NULL)) 00288 { 00289 transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a> = FALSE; 00290 } 00291 <font class="keywordflow">else</font> 00292 { 00293 _dbus_verbose (<font class="stringliteral">"Failed to write credentials\n"</font>); 00294 do_io_error (transport); 00295 } 00296 } 00297 00298 <font class="keywordflow">if</font> (do_reading && transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a>) 00299 { 00300 <font class="keywordflow">if</font> (_dbus_read_credentials_unix_socket (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00301 &transport-><a class="code" href="structDBusTransport.html#m5">credentials</a>, 00302 NULL)) 00303 { 00304 transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a> = FALSE; 00305 } 00306 <font class="keywordflow">else</font> 00307 { 00308 _dbus_verbose (<font class="stringliteral">"Failed to read credentials\n"</font>); 00309 do_io_error (transport); 00310 } 00311 } 00312 00313 <font class="keywordflow">if</font> (!(transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a> || 00314 transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a>)) 00315 { 00316 _dbus_auth_set_credentials (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, 00317 &transport-><a class="code" href="structDBusTransport.html#m5">credentials</a>); 00318 } 00319 } 00320 00321 <font class="keyword">static</font> dbus_bool_t 00322 do_authentication (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00323 dbus_bool_t do_reading, 00324 dbus_bool_t do_writing) 00325 { 00326 dbus_bool_t oom; 00327 00328 _dbus_transport_ref (transport); 00329 00330 oom = FALSE; 00331 00332 <font class="keywordflow">while</font> (!_dbus_transport_get_is_authenticated (transport) && 00333 _dbus_transport_get_is_connected (transport)) 00334 { 00335 exchange_credentials (transport, do_reading, do_writing); 00336 00337 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a> || 00338 transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a>) 00339 { 00340 _dbus_verbose (<font class="stringliteral">"send_credentials_pending = %d receive_credentials_pending = %d\n"</font>, 00341 transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a>, 00342 transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a>); 00343 <font class="keywordflow">goto</font> out; 00344 } 00345 00346 <font class="preprocessor">#define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")</font> 00347 <font class="preprocessor"></font> <font class="keywordflow">switch</font> (_dbus_auth_do_work (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>)) 00348 { 00349 <font class="keywordflow">case</font> DBUS_AUTH_STATE_WAITING_FOR_INPUT: 00350 _dbus_verbose (<font class="stringliteral">" %s auth state: waiting for input\n"</font>, 00351 TRANSPORT_SIDE (transport)); 00352 <font class="keywordflow">if</font> (!do_reading || !read_data_into_auth (transport, &oom)) 00353 <font class="keywordflow">goto</font> out; 00354 <font class="keywordflow">break</font>; 00355 00356 <font class="keywordflow">case</font> DBUS_AUTH_STATE_WAITING_FOR_MEMORY: 00357 _dbus_verbose (<font class="stringliteral">" %s auth state: waiting for memory\n"</font>, 00358 TRANSPORT_SIDE (transport)); 00359 oom = TRUE; 00360 <font class="keywordflow">goto</font> out; 00361 <font class="keywordflow">break</font>; 00362 00363 <font class="keywordflow">case</font> DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND: 00364 _dbus_verbose (<font class="stringliteral">" %s auth state: bytes to send\n"</font>, 00365 TRANSPORT_SIDE (transport)); 00366 <font class="keywordflow">if</font> (!do_writing || !write_data_from_auth (transport)) 00367 <font class="keywordflow">goto</font> out; 00368 <font class="keywordflow">break</font>; 00369 00370 <font class="keywordflow">case</font> DBUS_AUTH_STATE_NEED_DISCONNECT: 00371 _dbus_verbose (<font class="stringliteral">" %s auth state: need to disconnect\n"</font>, 00372 TRANSPORT_SIDE (transport)); 00373 do_io_error (transport); 00374 <font class="keywordflow">break</font>; 00375 00376 <font class="keywordflow">case</font> DBUS_AUTH_STATE_AUTHENTICATED: 00377 _dbus_verbose (<font class="stringliteral">" %s auth state: authenticated\n"</font>, 00378 TRANSPORT_SIDE (transport)); 00379 <font class="keywordflow">break</font>; 00380 } 00381 } 00382 00383 out: 00384 check_read_watch (transport); 00385 check_write_watch (transport); 00386 _dbus_transport_unref (transport); 00387 00388 <font class="keywordflow">if</font> (oom) 00389 <font class="keywordflow">return</font> FALSE; 00390 <font class="keywordflow">else</font> 00391 <font class="keywordflow">return</font> TRUE; 00392 } 00393 00394 <font class="comment">/* returns false on oom */</font> 00395 <font class="keyword">static</font> dbus_bool_t 00396 do_writing (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00397 { 00398 <font class="keywordtype">int</font> total; 00399 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00400 dbus_bool_t oom; 00401 00402 <font class="comment">/* No messages without authentication! */</font> 00403 <font class="keywordflow">if</font> (!_dbus_transport_get_is_authenticated (transport)) 00404 { 00405 _dbus_verbose (<font class="stringliteral">"Not authenticated, not writing anything\n"</font>); 00406 <font class="keywordflow">return</font> TRUE; 00407 } 00408 00409 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a>) 00410 { 00411 _dbus_verbose (<font class="stringliteral">"Not connected, not writing anything\n"</font>); 00412 <font class="keywordflow">return</font> TRUE; 00413 } 00414 00415 <font class="preprocessor">#if 0</font> 00416 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"do_writing(), have_messages = %d\n"</font>, 00417 _dbus_connection_have_messages_to_send (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>)); 00418 <font class="preprocessor">#endif</font> 00419 <font class="preprocessor"></font> 00420 oom = FALSE; 00421 total = 0; 00422 00423 <font class="keywordflow">while</font> (!transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a> && 00424 _dbus_connection_have_messages_to_send (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>)) 00425 { 00426 <font class="keywordtype">int</font> bytes_written; 00427 <a class="code" href="structDBusMessage.html">DBusMessage</a> *message; 00428 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *header; 00429 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *body; 00430 <font class="keywordtype">int</font> header_len, body_len; 00431 <font class="keywordtype">int</font> total_bytes_to_write; 00432 00433 <font class="keywordflow">if</font> (total > unix_transport-><a class="code" href="structDBusTransportUnix.html#m5">max_bytes_written_per_iteration</a>) 00434 { 00435 _dbus_verbose (<font class="stringliteral">"%d bytes exceeds %d bytes written per iteration, returning\n"</font>, 00436 total, unix_transport-><a class="code" href="structDBusTransportUnix.html#m5">max_bytes_written_per_iteration</a>); 00437 <font class="keywordflow">goto</font> out; 00438 } 00439 00440 <font class="keywordflow">if</font> (!dbus_watch_get_enabled (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>)) 00441 { 00442 _dbus_verbose (<font class="stringliteral">"write watch disabled, not writing more stuff\n"</font>); 00443 <font class="keywordflow">goto</font> out; 00444 } 00445 00446 message = _dbus_connection_get_message_to_send (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>); 00447 _dbus_assert (message != NULL); 00448 _dbus_message_lock (message); 00449 00450 <font class="preprocessor">#if 0</font> 00451 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"writing message %p\n"</font>, message); 00452 <font class="preprocessor">#endif</font> 00453 <font class="preprocessor"></font> 00454 _dbus_message_get_network_data (message, 00455 &header, &body); 00456 00457 header_len = _dbus_string_get_length (header); 00458 body_len = _dbus_string_get_length (body); 00459 00460 <font class="keywordflow">if</font> (_dbus_auth_needs_encoding (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>)) 00461 { 00462 <font class="keywordflow">if</font> (_dbus_string_get_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>) == 0) 00463 { 00464 <font class="keywordflow">if</font> (!_dbus_auth_encode_data (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, 00465 header, &unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>)) 00466 { 00467 oom = TRUE; 00468 <font class="keywordflow">goto</font> out; 00469 } 00470 00471 <font class="keywordflow">if</font> (!_dbus_auth_encode_data (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, 00472 body, &unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>)) 00473 { 00474 _dbus_string_set_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>, 0); 00475 oom = TRUE; 00476 <font class="keywordflow">goto</font> out; 00477 } 00478 } 00479 00480 total_bytes_to_write = _dbus_string_get_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>); 00481 00482 <font class="preprocessor">#if 0</font> 00483 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"encoded message is %d bytes\n"</font>, 00484 total_bytes_to_write); 00485 <font class="preprocessor">#endif</font> 00486 <font class="preprocessor"></font> 00487 bytes_written = 00488 _dbus_write (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00489 &unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>, 00490 unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a>, 00491 total_bytes_to_write - unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a>); 00492 } 00493 <font class="keywordflow">else</font> 00494 { 00495 total_bytes_to_write = header_len + body_len; 00496 00497 <font class="preprocessor">#if 0</font> 00498 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"message is %d bytes\n"</font>, 00499 total_bytes_to_write); 00500 <font class="preprocessor">#endif</font> 00501 <font class="preprocessor"></font> 00502 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> < header_len) 00503 { 00504 bytes_written = 00505 _dbus_write_two (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00506 header, 00507 unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a>, 00508 header_len - unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a>, 00509 body, 00510 0, body_len); 00511 } 00512 <font class="keywordflow">else</font> 00513 { 00514 bytes_written = 00515 _dbus_write (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00516 body, 00517 (unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> - header_len), 00518 body_len - 00519 (unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> - header_len)); 00520 } 00521 } 00522 00523 <font class="keywordflow">if</font> (bytes_written < 0) 00524 { 00525 <font class="comment">/* EINTR already handled for us */</font> 00526 00527 <font class="keywordflow">if</font> (errno == EAGAIN || 00528 errno == EWOULDBLOCK) 00529 <font class="keywordflow">goto</font> out; 00530 <font class="keywordflow">else</font> 00531 { 00532 _dbus_verbose (<font class="stringliteral">"Error writing to remote app: %s\n"</font>, 00533 _dbus_strerror (errno)); 00534 do_io_error (transport); 00535 <font class="keywordflow">goto</font> out; 00536 } 00537 } 00538 <font class="keywordflow">else</font> 00539 { 00540 _dbus_verbose (<font class="stringliteral">" wrote %d bytes of %d\n"</font>, bytes_written, 00541 total_bytes_to_write); 00542 00543 total += bytes_written; 00544 unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> += bytes_written; 00545 00546 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> <= 00547 total_bytes_to_write); 00548 00549 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> == total_bytes_to_write) 00550 { 00551 unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> = 0; 00552 _dbus_string_set_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>, 0); 00553 00554 _dbus_connection_message_sent (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00555 message); 00556 } 00557 } 00558 } 00559 00560 out: 00561 <font class="keywordflow">if</font> (oom) 00562 <font class="keywordflow">return</font> FALSE; 00563 <font class="keywordflow">else</font> 00564 <font class="keywordflow">return</font> TRUE; 00565 } 00566 00567 <font class="comment">/* returns false on out-of-memory */</font> 00568 <font class="keyword">static</font> dbus_bool_t 00569 do_reading (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00570 { 00571 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00572 <a class="code" href="structDBusString.html">DBusString</a> *buffer; 00573 <font class="keywordtype">int</font> bytes_read; 00574 <font class="keywordtype">int</font> total; 00575 dbus_bool_t oom; 00576 00577 <font class="comment">/* No messages without authentication! */</font> 00578 <font class="keywordflow">if</font> (!_dbus_transport_get_is_authenticated (transport)) 00579 <font class="keywordflow">return</font> TRUE; 00580 00581 oom = FALSE; 00582 00583 total = 0; 00584 00585 again: 00586 00587 <font class="comment">/* See if we've exceeded max messages and need to disable reading */</font> 00588 check_read_watch (transport); 00589 00590 <font class="keywordflow">if</font> (total > unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>) 00591 { 00592 _dbus_verbose (<font class="stringliteral">"%d bytes exceeds %d bytes read per iteration, returning\n"</font>, 00593 total, unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>); 00594 <font class="keywordflow">goto</font> out; 00595 } 00596 00597 _dbus_assert (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> != NULL || 00598 transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a>); 00599 00600 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m12">disconnected</a>) 00601 <font class="keywordflow">goto</font> out; 00602 00603 <font class="keywordflow">if</font> (!dbus_watch_get_enabled (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>)) 00604 <font class="keywordflow">return</font> TRUE; 00605 00606 <font class="keywordflow">if</font> (_dbus_auth_needs_decoding (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>)) 00607 { 00608 <font class="keywordflow">if</font> (_dbus_string_get_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>) > 0) 00609 bytes_read = _dbus_string_get_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>); 00610 <font class="keywordflow">else</font> 00611 bytes_read = _dbus_read (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00612 &unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>, 00613 unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>); 00614 00615 _dbus_assert (_dbus_string_get_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>) == 00616 bytes_read); 00617 00618 <font class="keywordflow">if</font> (bytes_read > 0) 00619 { 00620 <font class="keywordtype">int</font> orig_len; 00621 00622 _dbus_message_loader_get_buffer (transport-><a class="code" href="structDBusTransport.html#m3">loader</a>, 00623 &buffer); 00624 00625 orig_len = _dbus_string_get_length (buffer); 00626 00627 <font class="keywordflow">if</font> (!_dbus_auth_decode_data (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>, 00628 &unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>, 00629 buffer)) 00630 { 00631 _dbus_verbose (<font class="stringliteral">"Out of memory decoding incoming data\n"</font>); 00632 oom = TRUE; 00633 <font class="keywordflow">goto</font> out; 00634 } 00635 00636 _dbus_message_loader_return_buffer (transport-><a class="code" href="structDBusTransport.html#m3">loader</a>, 00637 buffer, 00638 _dbus_string_get_length (buffer) - orig_len); 00639 00640 _dbus_string_set_length (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>, 0); 00641 } 00642 } 00643 <font class="keywordflow">else</font> 00644 { 00645 _dbus_message_loader_get_buffer (transport-><a class="code" href="structDBusTransport.html#m3">loader</a>, 00646 &buffer); 00647 00648 bytes_read = _dbus_read (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, 00649 buffer, unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a>); 00650 00651 _dbus_message_loader_return_buffer (transport-><a class="code" href="structDBusTransport.html#m3">loader</a>, 00652 buffer, 00653 bytes_read < 0 ? 0 : bytes_read); 00654 } 00655 00656 <font class="keywordflow">if</font> (bytes_read < 0) 00657 { 00658 <font class="comment">/* EINTR already handled for us */</font> 00659 00660 <font class="keywordflow">if</font> (errno == ENOMEM) 00661 { 00662 _dbus_verbose (<font class="stringliteral">"Out of memory in read()/do_reading()\n"</font>); 00663 oom = TRUE; 00664 <font class="keywordflow">goto</font> out; 00665 } 00666 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (errno == EAGAIN || 00667 errno == EWOULDBLOCK) 00668 <font class="keywordflow">goto</font> out; 00669 <font class="keywordflow">else</font> 00670 { 00671 _dbus_verbose (<font class="stringliteral">"Error reading from remote app: %s\n"</font>, 00672 _dbus_strerror (errno)); 00673 do_io_error (transport); 00674 <font class="keywordflow">goto</font> out; 00675 } 00676 } 00677 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (bytes_read == 0) 00678 { 00679 _dbus_verbose (<font class="stringliteral">"Disconnected from remote app\n"</font>); 00680 do_io_error (transport); 00681 <font class="keywordflow">goto</font> out; 00682 } 00683 <font class="keywordflow">else</font> 00684 { 00685 _dbus_verbose (<font class="stringliteral">" read %d bytes\n"</font>, bytes_read); 00686 00687 total += bytes_read; 00688 00689 <font class="keywordflow">if</font> (_dbus_transport_queue_messages (transport) == DBUS_DISPATCH_NEED_MEMORY) 00690 { 00691 oom = TRUE; 00692 _dbus_verbose (<font class="stringliteral">" out of memory when queueing messages we just read in the transport\n"</font>); 00693 <font class="keywordflow">goto</font> out; 00694 } 00695 00696 <font class="comment">/* Try reading more data until we get EAGAIN and return, or</font> 00697 <font class="comment"> * exceed max bytes per iteration. If in blocking mode of</font> 00698 <font class="comment"> * course we'll block instead of returning.</font> 00699 <font class="comment"> */</font> 00700 <font class="keywordflow">goto</font> again; 00701 } 00702 00703 out: 00704 <font class="keywordflow">if</font> (oom) 00705 <font class="keywordflow">return</font> FALSE; 00706 <font class="keywordflow">else</font> 00707 <font class="keywordflow">return</font> TRUE; 00708 } 00709 00710 <font class="keyword">static</font> dbus_bool_t 00711 unix_handle_watch (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00712 <a class="code" href="structDBusWatch.html">DBusWatch</a> *watch, 00713 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> flags) 00714 { 00715 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00716 00717 _dbus_assert (watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> || 00718 watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00719 00720 <font class="keywordflow">if</font> (watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> && 00721 (flags & DBUS_WATCH_READABLE)) 00722 { 00723 <font class="preprocessor">#if 1</font> 00724 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"handling read watch\n"</font>); 00725 <font class="preprocessor">#endif</font> 00726 <font class="preprocessor"></font> <font class="keywordflow">if</font> (!do_authentication (transport, TRUE, FALSE)) 00727 <font class="keywordflow">return</font> FALSE; 00728 00729 <font class="keywordflow">if</font> (!do_reading (transport)) 00730 { 00731 _dbus_verbose (<font class="stringliteral">"no memory to read\n"</font>); 00732 <font class="keywordflow">return</font> FALSE; 00733 } 00734 } 00735 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> && 00736 (flags & DBUS_WATCH_WRITABLE)) 00737 { 00738 <font class="preprocessor">#if 0</font> 00739 <font class="preprocessor"></font> _dbus_verbose (<font class="stringliteral">"handling write watch, messages_need_sending = %d\n"</font>, 00740 transport-><a class="code" href="structDBusTransport.html#m14">messages_need_sending</a>); 00741 <font class="preprocessor">#endif</font> 00742 <font class="preprocessor"></font> <font class="keywordflow">if</font> (!do_authentication (transport, FALSE, TRUE)) 00743 <font class="keywordflow">return</font> FALSE; 00744 00745 <font class="keywordflow">if</font> (!do_writing (transport)) 00746 { 00747 _dbus_verbose (<font class="stringliteral">"no memory to write\n"</font>); 00748 <font class="keywordflow">return</font> FALSE; 00749 } 00750 } 00751 <font class="preprocessor">#ifdef DBUS_ENABLE_VERBOSE_MODE</font> 00752 <font class="preprocessor"></font> <font class="keywordflow">else</font> 00753 { 00754 <font class="keywordflow">if</font> (watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>) 00755 _dbus_verbose (<font class="stringliteral">"asked to handle read watch with non-read condition 0x%x\n"</font>, 00756 flags); 00757 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (watch == unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>) 00758 _dbus_verbose (<font class="stringliteral">"asked to handle write watch with non-write condition 0x%x\n"</font>, 00759 flags); 00760 <font class="keywordflow">else</font> 00761 _dbus_verbose (<font class="stringliteral">"asked to handle watch %p on fd %d that we don't recognize\n"</font>, 00762 watch, dbus_watch_get_fd (watch)); 00763 } 00764 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_ENABLE_VERBOSE_MODE */</font> 00765 00766 <font class="keywordflow">if</font> (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR)) 00767 { 00768 _dbus_transport_disconnect (transport); 00769 <font class="keywordflow">return</font> TRUE; 00770 } 00771 00772 <font class="keywordflow">return</font> TRUE; 00773 } 00774 00775 <font class="keyword">static</font> <font class="keywordtype">void</font> 00776 unix_disconnect (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00777 { 00778 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00779 00780 free_watches (transport); 00781 00782 _dbus_close (unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>, NULL); 00783 unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a> = -1; 00784 } 00785 00786 <font class="keyword">static</font> dbus_bool_t 00787 unix_connection_set (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00788 { 00789 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00790 00791 _dbus_watch_set_handler (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>, 00792 _dbus_connection_handle_watch, 00793 transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, NULL); 00794 00795 _dbus_watch_set_handler (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>, 00796 _dbus_connection_handle_watch, 00797 transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, NULL); 00798 00799 <font class="keywordflow">if</font> (!_dbus_connection_add_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00800 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>)) 00801 <font class="keywordflow">return</font> FALSE; 00802 00803 <font class="keywordflow">if</font> (!_dbus_connection_add_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00804 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>)) 00805 { 00806 _dbus_connection_remove_watch (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>, 00807 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00808 <font class="keywordflow">return</font> FALSE; 00809 } 00810 00811 check_read_watch (transport); 00812 check_write_watch (transport); 00813 00814 <font class="keywordflow">return</font> TRUE; 00815 } 00816 00817 <font class="keyword">static</font> <font class="keywordtype">void</font> 00818 unix_messages_pending (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00819 <font class="keywordtype">int</font> messages_pending) 00820 { 00821 check_write_watch (transport); 00822 } 00823 00831 <font class="keyword">static</font> <font class="keywordtype">void</font> 00832 unix_do_iteration (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport, 00833 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> flags, 00834 <font class="keywordtype">int</font> timeout_milliseconds) 00835 { 00836 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport; 00837 <a class="code" href="structDBusPollFD.html">DBusPollFD</a> poll_fd; 00838 <font class="keywordtype">int</font> poll_res; 00839 <font class="keywordtype">int</font> poll_timeout; 00840 00841 _dbus_verbose (<font class="stringliteral">" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n"</font>, 00842 flags & DBUS_ITERATION_DO_READING ? <font class="stringliteral">"read"</font> : <font class="stringliteral">""</font>, 00843 flags & DBUS_ITERATION_DO_WRITING ? <font class="stringliteral">"write"</font> : <font class="stringliteral">""</font>, 00844 timeout_milliseconds, 00845 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>, 00846 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 00847 00848 <font class="comment">/* the passed in DO_READING/DO_WRITING flags indicate whether to</font> 00849 <font class="comment"> * read/write messages, but regardless of those we may need to block</font> 00850 <font class="comment"> * for reading/writing to do auth. But if we do reading for auth,</font> 00851 <font class="comment"> * we don't want to read any messages yet if not given DO_READING.</font> 00852 <font class="comment"> *</font> 00853 <font class="comment"> * Also, if read_watch == NULL or write_watch == NULL, we don't</font> 00854 <font class="comment"> * want to read/write so don't.</font> 00855 <font class="comment"> */</font> 00856 00857 poll_fd.<a class="code" href="structDBusPollFD.html#m0">fd</a> = unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a>; 00858 poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a> = 0; 00859 00860 <font class="keywordflow">if</font> (_dbus_transport_get_is_authenticated (transport)) 00861 { 00862 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> && 00863 (flags & DBUS_ITERATION_DO_READING)) 00864 poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a> |= _DBUS_POLLIN; 00865 00866 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> && 00867 (flags & DBUS_ITERATION_DO_WRITING)) 00868 poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a> |= _DBUS_POLLOUT; 00869 } 00870 <font class="keywordflow">else</font> 00871 { 00872 DBusAuthState auth_state; 00873 00874 auth_state = _dbus_auth_do_work (transport-><a class="code" href="structDBusTransport.html#m4">auth</a>); 00875 00876 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m16">receive_credentials_pending</a> || 00877 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT) 00878 poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a> |= _DBUS_POLLIN; 00879 00880 <font class="keywordflow">if</font> (transport-><a class="code" href="structDBusTransport.html#m15">send_credentials_pending</a> || 00881 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) 00882 poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a> |= _DBUS_POLLOUT; 00883 } 00884 00885 <font class="keywordflow">if</font> (poll_fd.<a class="code" href="structDBusPollFD.html#m1">events</a>) 00886 { 00887 <font class="keywordflow">if</font> (flags & DBUS_ITERATION_BLOCK) 00888 poll_timeout = timeout_milliseconds; 00889 <font class="keywordflow">else</font> 00890 poll_timeout = 0; 00891 00892 <font class="comment">/* For blocking selects we drop the connection lock here</font> 00893 <font class="comment"> * to avoid blocking out connection access during a potentially</font> 00894 <font class="comment"> * indefinite blocking call. The io path is still protected</font> 00895 <font class="comment"> * by the io_path_cond condvar, so we won't reenter this.</font> 00896 <font class="comment"> */</font> 00897 <font class="keywordflow">if</font> (flags & DBUS_ITERATION_BLOCK) 00898 _dbus_connection_unlock (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>); 00899 00900 again: 00901 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout); 00902 00903 <font class="keywordflow">if</font> (poll_res < 0 && errno == EINTR) 00904 <font class="keywordflow">goto</font> again; 00905 00906 <font class="keywordflow">if</font> (flags & DBUS_ITERATION_BLOCK) 00907 _dbus_connection_lock (transport-><a class="code" href="structDBusTransport.html#m2">connection</a>); 00908 00909 <font class="keywordflow">if</font> (poll_res >= 0) 00910 { 00911 <font class="keywordflow">if</font> (poll_fd.<a class="code" href="structDBusPollFD.html#m2">revents</a> & _DBUS_POLLERR) 00912 do_io_error (transport); 00913 <font class="keywordflow">else</font> 00914 { 00915 dbus_bool_t need_read = (poll_fd.<a class="code" href="structDBusPollFD.html#m2">revents</a> & _DBUS_POLLIN) > 0; 00916 dbus_bool_t need_write = (poll_fd.<a class="code" href="structDBusPollFD.html#m2">revents</a> & _DBUS_POLLOUT) > 0; 00917 00918 _dbus_verbose (<font class="stringliteral">"in iteration, need_read=%d need_write=%d\n"</font>, 00919 need_read, need_write); 00920 do_authentication (transport, need_read, need_write); 00921 00922 <font class="keywordflow">if</font> (need_read && (flags & DBUS_ITERATION_DO_READING)) 00923 do_reading (transport); 00924 <font class="keywordflow">if</font> (need_write && (flags & DBUS_ITERATION_DO_WRITING)) 00925 do_writing (transport); 00926 } 00927 } 00928 <font class="keywordflow">else</font> 00929 { 00930 _dbus_verbose (<font class="stringliteral">"Error from _dbus_poll(): %s\n"</font>, 00931 _dbus_strerror (errno)); 00932 } 00933 } 00934 } 00935 00936 <font class="keyword">static</font> <font class="keywordtype">void</font> 00937 unix_live_messages_changed (<a class="code" href="structDBusTransport.html">DBusTransport</a> *transport) 00938 { 00939 <font class="comment">/* See if we should look for incoming messages again */</font> 00940 check_read_watch (transport); 00941 } 00942 00943 <font class="keyword">static</font> <a class="code" href="structDBusTransportVTable.html">DBusTransportVTable</a> unix_vtable = { 00944 unix_finalize, 00945 unix_handle_watch, 00946 unix_disconnect, 00947 unix_connection_set, 00948 unix_messages_pending, 00949 unix_do_iteration, 00950 unix_live_messages_changed 00951 }; 00952 00964 <a class="code" href="structDBusTransport.html">DBusTransport</a>* <a name="l00965"></a><a class="code" href="group__DBusTransportUnix.html#a19">00965</a> _dbus_transport_new_for_fd (<font class="keywordtype">int</font> fd, 00966 dbus_bool_t server, 00967 <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *address) 00968 { 00969 DBusTransportUnix *unix_transport; 00970 00971 unix_transport = dbus_new0 (DBusTransportUnix, 1); 00972 <font class="keywordflow">if</font> (unix_transport == NULL) 00973 <font class="keywordflow">return</font> NULL; 00974 00975 <font class="keywordflow">if</font> (!_dbus_string_init (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>)) 00976 <font class="keywordflow">goto</font> failed_0; 00977 00978 <font class="keywordflow">if</font> (!_dbus_string_init (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>)) 00979 <font class="keywordflow">goto</font> failed_1; 00980 00981 unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> = _dbus_watch_new (fd, 00982 DBUS_WATCH_WRITABLE, 00983 FALSE, 00984 NULL, NULL, NULL); 00985 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a> == NULL) 00986 <font class="keywordflow">goto</font> failed_2; 00987 00988 unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> = _dbus_watch_new (fd, 00989 DBUS_WATCH_READABLE, 00990 FALSE, 00991 NULL, NULL, NULL); 00992 <font class="keywordflow">if</font> (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a> == NULL) 00993 <font class="keywordflow">goto</font> failed_3; 00994 00995 <font class="keywordflow">if</font> (!_dbus_transport_init_base (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m0">base</a>, 00996 &unix_vtable, 00997 server, address)) 00998 <font class="keywordflow">goto</font> failed_4; 00999 01000 unix_transport-><a class="code" href="structDBusTransportUnix.html#m1">fd</a> = fd; 01001 unix_transport-><a class="code" href="structDBusTransportUnix.html#m6">message_bytes_written</a> = 0; 01002 01003 <font class="comment">/* These values should probably be tunable or something. */</font> 01004 unix_transport-><a class="code" href="structDBusTransportUnix.html#m4">max_bytes_read_per_iteration</a> = 2048; 01005 unix_transport-><a class="code" href="structDBusTransportUnix.html#m5">max_bytes_written_per_iteration</a> = 2048; 01006 01007 <font class="keywordflow">return</font> (<a class="code" href="structDBusTransport.html">DBusTransport</a>*) unix_transport; 01008 01009 failed_4: 01010 _dbus_watch_unref (unix_transport-><a class="code" href="structDBusTransportUnix.html#m2">read_watch</a>); 01011 failed_3: 01012 _dbus_watch_unref (unix_transport-><a class="code" href="structDBusTransportUnix.html#m3">write_watch</a>); 01013 failed_2: 01014 _dbus_string_free (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m8">encoded_incoming</a>); 01015 failed_1: 01016 _dbus_string_free (&unix_transport-><a class="code" href="structDBusTransportUnix.html#m7">encoded_outgoing</a>); 01017 failed_0: 01018 dbus_free (unix_transport); 01019 <font class="keywordflow">return</font> NULL; 01020 } 01021 01034 <a class="code" href="structDBusTransport.html">DBusTransport</a>* <a name="l01035"></a><a class="code" href="group__DBusTransportUnix.html#a20">01035</a> _dbus_transport_new_for_domain_socket (<font class="keyword">const</font> <font class="keywordtype">char</font> *path, 01036 dbus_bool_t <font class="keyword">abstract</font>, 01037 <a class="code" href="structDBusError.html">DBusError</a> *error) 01038 { 01039 <font class="keywordtype">int</font> fd; 01040 <a class="code" href="structDBusTransport.html">DBusTransport</a> *transport; 01041 <a class="code" href="structDBusString.html">DBusString</a> address; 01042 01043 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01044 01045 <font class="keywordflow">if</font> (!_dbus_string_init (&address)) 01046 { 01047 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01048 <font class="keywordflow">return</font> NULL; 01049 } 01050 01051 fd = -1; 01052 01053 <font class="keywordflow">if</font> ((<font class="keyword">abstract</font> && 01054 !_dbus_string_append (&address, <font class="stringliteral">"unix:abstract="</font>)) || 01055 (!<font class="keyword">abstract</font> && 01056 !_dbus_string_append (&address, <font class="stringliteral">"unix:path="</font>)) || 01057 !_dbus_string_append (&address, path)) 01058 { 01059 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01060 <font class="keywordflow">goto</font> failed_0; 01061 } 01062 01063 fd = _dbus_connect_unix_socket (path, <font class="keyword">abstract</font>, error); 01064 <font class="keywordflow">if</font> (fd < 0) 01065 { 01066 _DBUS_ASSERT_ERROR_IS_SET (error); 01067 <font class="keywordflow">goto</font> failed_0; 01068 } 01069 01070 _dbus_fd_set_close_on_exec (fd); 01071 01072 _dbus_verbose (<font class="stringliteral">"Successfully connected to unix socket %s\n"</font>, 01073 path); 01074 01075 transport = _dbus_transport_new_for_fd (fd, FALSE, &address); 01076 <font class="keywordflow">if</font> (transport == NULL) 01077 { 01078 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01079 <font class="keywordflow">goto</font> failed_1; 01080 } 01081 01082 _dbus_string_free (&address); 01083 01084 <font class="keywordflow">return</font> transport; 01085 01086 failed_1: 01087 _dbus_close (fd, NULL); 01088 failed_0: 01089 _dbus_string_free (&address); 01090 <font class="keywordflow">return</font> NULL; 01091 } 01092 01101 <a class="code" href="structDBusTransport.html">DBusTransport</a>* <a name="l01102"></a><a class="code" href="group__DBusTransportUnix.html#a21">01102</a> _dbus_transport_new_for_tcp_socket (<font class="keyword">const</font> <font class="keywordtype">char</font> *host, 01103 dbus_int32_t port, 01104 <a class="code" href="structDBusError.html">DBusError</a> *error) 01105 { 01106 <font class="keywordtype">int</font> fd; 01107 <a class="code" href="structDBusTransport.html">DBusTransport</a> *transport; 01108 <a class="code" href="structDBusString.html">DBusString</a> address; 01109 01110 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 01111 01112 <font class="keywordflow">if</font> (!_dbus_string_init (&address)) 01113 { 01114 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01115 <font class="keywordflow">return</font> NULL; 01116 } 01117 01118 <font class="keywordflow">if</font> (!_dbus_string_append (&address, <font class="stringliteral">"tcp:host="</font>) || 01119 !_dbus_string_append (&address, host) || 01120 !_dbus_string_append (&address, <font class="stringliteral">",port="</font>) || 01121 !_dbus_string_append_int (&address, port)) 01122 { 01123 _dbus_string_free (&address); 01124 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01125 <font class="keywordflow">return</font> NULL; 01126 } 01127 01128 fd = _dbus_connect_tcp_socket (host, port, error); 01129 <font class="keywordflow">if</font> (fd < 0) 01130 { 01131 _DBUS_ASSERT_ERROR_IS_SET (error); 01132 _dbus_string_free (&address); 01133 <font class="keywordflow">return</font> NULL; 01134 } 01135 01136 _dbus_fd_set_close_on_exec (fd); 01137 01138 _dbus_verbose (<font class="stringliteral">"Successfully connected to tcp socket %s:%d\n"</font>, 01139 host, port); 01140 01141 transport = _dbus_transport_new_for_fd (fd, FALSE, &address); 01142 <font class="keywordflow">if</font> (transport == NULL) 01143 { 01144 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 01145 _dbus_close (fd, NULL); 01146 _dbus_string_free (&address); 01147 fd = -1; 01148 } 01149 01150 _dbus_string_free (&address); 01151 01152 <font class="keywordflow">return</font> transport; 01153 } 01154 </pre></div><hr><address align="right"><small>Generated on Wed Jun 9 05:01:27 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>