00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "dbus-internals.h"
00025 #include "dbus-connection-internal.h"
00026 #include "dbus-transport-unix.h"
00027 #include "dbus-transport-protected.h"
00028 #include "dbus-watch.h"
00029 #include <sys/types.h>
00030 #include <sys/time.h>
00031 #include <unistd.h>
00032
00033
00045 typedef struct DBusTransportUnix DBusTransportUnix;
00046
00050 struct DBusTransportUnix
00051 {
00052 DBusTransport base;
00053 int fd;
00054 DBusWatch *read_watch;
00055 DBusWatch *write_watch;
00057 int max_bytes_read_per_iteration;
00058 int max_bytes_written_per_iteration;
00060 int message_bytes_written;
00064 DBusString encoded_outgoing;
00067 DBusString encoded_incoming;
00070 };
00071
00072 static void
00073 free_watches (DBusTransport *transport)
00074 {
00075 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00076
00077 if (unix_transport->read_watch)
00078 {
00079 if (transport->connection)
00080 _dbus_connection_remove_watch (transport->connection,
00081 unix_transport->read_watch);
00082 _dbus_watch_invalidate (unix_transport->read_watch);
00083 _dbus_watch_unref (unix_transport->read_watch);
00084 unix_transport->read_watch = NULL;
00085 }
00086
00087 if (unix_transport->write_watch)
00088 {
00089 if (transport->connection)
00090 _dbus_connection_remove_watch (transport->connection,
00091 unix_transport->write_watch);
00092 _dbus_watch_invalidate (unix_transport->write_watch);
00093 _dbus_watch_unref (unix_transport->write_watch);
00094 unix_transport->write_watch = NULL;
00095 }
00096 }
00097
00098 static void
00099 unix_finalize (DBusTransport *transport)
00100 {
00101 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00102
00103 free_watches (transport);
00104
00105 _dbus_string_free (&unix_transport->encoded_outgoing);
00106 _dbus_string_free (&unix_transport->encoded_incoming);
00107
00108 _dbus_transport_finalize_base (transport);
00109
00110 _dbus_assert (unix_transport->read_watch == NULL);
00111 _dbus_assert (unix_transport->write_watch == NULL);
00112
00113 dbus_free (transport);
00114 }
00115
00116 static void
00117 check_write_watch (DBusTransport *transport)
00118 {
00119 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00120 dbus_bool_t need_write_watch;
00121
00122 if (transport->connection == NULL)
00123 return;
00124
00125 if (transport->disconnected)
00126 {
00127 _dbus_assert (unix_transport->write_watch == NULL);
00128 return;
00129 }
00130
00131 _dbus_transport_ref (transport);
00132
00133 if (_dbus_transport_get_is_authenticated (transport))
00134 need_write_watch = transport->messages_need_sending;
00135 else
00136 need_write_watch = transport->send_credentials_pending ||
00137 _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
00138
00139 _dbus_connection_toggle_watch (transport->connection,
00140 unix_transport->write_watch,
00141 need_write_watch);
00142
00143 _dbus_transport_unref (transport);
00144 }
00145
00146 static void
00147 check_read_watch (DBusTransport *transport)
00148 {
00149 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00150 dbus_bool_t need_read_watch;
00151
00152 if (transport->connection == NULL)
00153 return;
00154
00155 if (transport->disconnected)
00156 {
00157 _dbus_assert (unix_transport->read_watch == NULL);
00158 return;
00159 }
00160
00161 _dbus_transport_ref (transport);
00162
00163 if (_dbus_transport_get_is_authenticated (transport))
00164 need_read_watch =
00165 _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
00166 else
00167 need_read_watch = transport->receive_credentials_pending ||
00168 _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
00169
00170 _dbus_connection_toggle_watch (transport->connection,
00171 unix_transport->read_watch,
00172 need_read_watch);
00173
00174 _dbus_transport_unref (transport);
00175 }
00176
00177 static void
00178 do_io_error (DBusTransport *transport)
00179 {
00180 _dbus_transport_ref (transport);
00181 _dbus_transport_disconnect (transport);
00182 _dbus_transport_unref (transport);
00183 }
00184
00185
00186 static dbus_bool_t
00187 read_data_into_auth (DBusTransport *transport,
00188 dbus_bool_t *oom)
00189 {
00190 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00191 DBusString *buffer;
00192 int bytes_read;
00193
00194 *oom = FALSE;
00195
00196 _dbus_auth_get_buffer (transport->auth, &buffer);
00197
00198 bytes_read = _dbus_read (unix_transport->fd,
00199 buffer, unix_transport->max_bytes_read_per_iteration);
00200
00201 _dbus_auth_return_buffer (transport->auth, buffer,
00202 bytes_read > 0 ? bytes_read : 0);
00203
00204 if (bytes_read > 0)
00205 {
00206 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
00207
00208 return TRUE;
00209 }
00210 else if (bytes_read < 0)
00211 {
00212
00213
00214 if (errno == ENOMEM)
00215 {
00216 *oom = TRUE;
00217 }
00218 else if (errno == EAGAIN ||
00219 errno == EWOULDBLOCK)
00220 ;
00221 else
00222 {
00223 _dbus_verbose ("Error reading from remote app: %s\n",
00224 _dbus_strerror (errno));
00225 do_io_error (transport);
00226 }
00227
00228 return FALSE;
00229 }
00230 else
00231 {
00232 _dbus_assert (bytes_read == 0);
00233
00234 _dbus_verbose ("Disconnected from remote app\n");
00235 do_io_error (transport);
00236
00237 return FALSE;
00238 }
00239 }
00240
00241
00242 static dbus_bool_t
00243 write_data_from_auth (DBusTransport *transport)
00244 {
00245 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00246 int bytes_written;
00247 const DBusString *buffer;
00248
00249 if (!_dbus_auth_get_bytes_to_send (transport->auth,
00250 &buffer))
00251 return FALSE;
00252
00253 bytes_written = _dbus_write (unix_transport->fd,
00254 buffer,
00255 0, _dbus_string_get_length (buffer));
00256
00257 if (bytes_written > 0)
00258 {
00259 _dbus_auth_bytes_sent (transport->auth, bytes_written);
00260 return TRUE;
00261 }
00262 else if (bytes_written < 0)
00263 {
00264
00265
00266 if (errno == EAGAIN ||
00267 errno == EWOULDBLOCK)
00268 ;
00269 else
00270 {
00271 _dbus_verbose ("Error writing to remote app: %s\n",
00272 _dbus_strerror (errno));
00273 do_io_error (transport);
00274 }
00275 }
00276
00277 return FALSE;
00278 }
00279
00280 static void
00281 exchange_credentials (DBusTransport *transport,
00282 dbus_bool_t do_reading,
00283 dbus_bool_t do_writing)
00284 {
00285 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00286
00287 if (do_writing && transport->send_credentials_pending)
00288 {
00289 if (_dbus_send_credentials_unix_socket (unix_transport->fd,
00290 NULL))
00291 {
00292 transport->send_credentials_pending = FALSE;
00293 }
00294 else
00295 {
00296 _dbus_verbose ("Failed to write credentials\n");
00297 do_io_error (transport);
00298 }
00299 }
00300
00301 if (do_reading && transport->receive_credentials_pending)
00302 {
00303 if (_dbus_read_credentials_unix_socket (unix_transport->fd,
00304 &transport->credentials,
00305 NULL))
00306 {
00307 transport->receive_credentials_pending = FALSE;
00308 }
00309 else
00310 {
00311 _dbus_verbose ("Failed to read credentials\n");
00312 do_io_error (transport);
00313 }
00314 }
00315
00316 if (!(transport->send_credentials_pending ||
00317 transport->receive_credentials_pending))
00318 {
00319 _dbus_auth_set_credentials (transport->auth,
00320 &transport->credentials);
00321 }
00322 }
00323
00324 static dbus_bool_t
00325 do_authentication (DBusTransport *transport,
00326 dbus_bool_t do_reading,
00327 dbus_bool_t do_writing)
00328 {
00329 dbus_bool_t oom;
00330
00331 _dbus_transport_ref (transport);
00332
00333 oom = FALSE;
00334
00335 while (!_dbus_transport_get_is_authenticated (transport) &&
00336 _dbus_transport_get_is_connected (transport))
00337 {
00338 exchange_credentials (transport, do_reading, do_writing);
00339
00340 if (transport->send_credentials_pending ||
00341 transport->receive_credentials_pending)
00342 {
00343 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
00344 transport->send_credentials_pending,
00345 transport->receive_credentials_pending);
00346 goto out;
00347 }
00348
00349 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
00350 switch (_dbus_auth_do_work (transport->auth))
00351 {
00352 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
00353 _dbus_verbose (" %s auth state: waiting for input\n",
00354 TRANSPORT_SIDE (transport));
00355 if (!do_reading || !read_data_into_auth (transport, &oom))
00356 goto out;
00357 break;
00358
00359 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
00360 _dbus_verbose (" %s auth state: waiting for memory\n",
00361 TRANSPORT_SIDE (transport));
00362 oom = TRUE;
00363 goto out;
00364 break;
00365
00366 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
00367 _dbus_verbose (" %s auth state: bytes to send\n",
00368 TRANSPORT_SIDE (transport));
00369 if (!do_writing || !write_data_from_auth (transport))
00370 goto out;
00371 break;
00372
00373 case DBUS_AUTH_STATE_NEED_DISCONNECT:
00374 _dbus_verbose (" %s auth state: need to disconnect\n",
00375 TRANSPORT_SIDE (transport));
00376 do_io_error (transport);
00377 break;
00378
00379 case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
00380 _dbus_verbose (" %s auth state: auth with unused bytes\n",
00381 TRANSPORT_SIDE (transport));
00382
00383 goto out;
00384 break;
00385
00386 case DBUS_AUTH_STATE_AUTHENTICATED:
00387 _dbus_verbose (" %s auth state: authenticated\n",
00388 TRANSPORT_SIDE (transport));
00389 break;
00390 }
00391 }
00392
00393 out:
00394 check_read_watch (transport);
00395 check_write_watch (transport);
00396 _dbus_transport_unref (transport);
00397
00398 if (oom)
00399 return FALSE;
00400 else
00401 return TRUE;
00402 }
00403
00404
00405 static dbus_bool_t
00406 do_writing (DBusTransport *transport)
00407 {
00408 int total;
00409 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00410 dbus_bool_t oom;
00411
00412
00413 if (!_dbus_transport_get_is_authenticated (transport))
00414 {
00415 _dbus_verbose ("Not authenticated, not writing anything\n");
00416 return TRUE;
00417 }
00418
00419 if (transport->disconnected)
00420 {
00421 _dbus_verbose ("Not connected, not writing anything\n");
00422 return TRUE;
00423 }
00424
00425 #if 0
00426 _dbus_verbose ("do_writing(), have_messages = %d\n",
00427 _dbus_connection_have_messages_to_send (transport->connection));
00428 #endif
00429
00430 oom = FALSE;
00431 total = 0;
00432
00433 while (!transport->disconnected &&
00434 _dbus_connection_have_messages_to_send (transport->connection))
00435 {
00436 int bytes_written;
00437 DBusMessage *message;
00438 const DBusString *header;
00439 const DBusString *body;
00440 int header_len, body_len;
00441 int total_bytes_to_write;
00442
00443 if (total > unix_transport->max_bytes_written_per_iteration)
00444 {
00445 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
00446 total, unix_transport->max_bytes_written_per_iteration);
00447 goto out;
00448 }
00449
00450 if (!dbus_watch_get_enabled (unix_transport->write_watch))
00451 {
00452 _dbus_verbose ("write watch disabled, not writing more stuff\n");
00453 goto out;
00454 }
00455
00456 message = _dbus_connection_get_message_to_send (transport->connection);
00457 _dbus_assert (message != NULL);
00458 _dbus_message_lock (message);
00459
00460 #if 0
00461 _dbus_verbose ("writing message %p\n", message);
00462 #endif
00463
00464 _dbus_message_get_network_data (message,
00465 &header, &body);
00466
00467 header_len = _dbus_string_get_length (header);
00468 body_len = _dbus_string_get_length (body);
00469
00470 if (_dbus_auth_needs_encoding (transport->auth))
00471 {
00472 if (_dbus_string_get_length (&unix_transport->encoded_outgoing) == 0)
00473 {
00474 if (!_dbus_auth_encode_data (transport->auth,
00475 header, &unix_transport->encoded_outgoing))
00476 {
00477 oom = TRUE;
00478 goto out;
00479 }
00480
00481 if (!_dbus_auth_encode_data (transport->auth,
00482 body, &unix_transport->encoded_outgoing))
00483 {
00484 _dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
00485 oom = TRUE;
00486 goto out;
00487 }
00488 }
00489
00490 total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_outgoing);
00491
00492 #if 0
00493 _dbus_verbose ("encoded message is %d bytes\n",
00494 total_bytes_to_write);
00495 #endif
00496
00497 bytes_written =
00498 _dbus_write (unix_transport->fd,
00499 &unix_transport->encoded_outgoing,
00500 unix_transport->message_bytes_written,
00501 total_bytes_to_write - unix_transport->message_bytes_written);
00502 }
00503 else
00504 {
00505 total_bytes_to_write = header_len + body_len;
00506
00507 #if 0
00508 _dbus_verbose ("message is %d bytes\n",
00509 total_bytes_to_write);
00510 #endif
00511
00512 if (unix_transport->message_bytes_written < header_len)
00513 {
00514 bytes_written =
00515 _dbus_write_two (unix_transport->fd,
00516 header,
00517 unix_transport->message_bytes_written,
00518 header_len - unix_transport->message_bytes_written,
00519 body,
00520 0, body_len);
00521 }
00522 else
00523 {
00524 bytes_written =
00525 _dbus_write (unix_transport->fd,
00526 body,
00527 (unix_transport->message_bytes_written - header_len),
00528 body_len -
00529 (unix_transport->message_bytes_written - header_len));
00530 }
00531 }
00532
00533 if (bytes_written < 0)
00534 {
00535
00536
00537 if (errno == EAGAIN ||
00538 errno == EWOULDBLOCK)
00539 goto out;
00540 else
00541 {
00542 _dbus_verbose ("Error writing to remote app: %s\n",
00543 _dbus_strerror (errno));
00544 do_io_error (transport);
00545 goto out;
00546 }
00547 }
00548 else
00549 {
00550 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
00551 total_bytes_to_write);
00552
00553 total += bytes_written;
00554 unix_transport->message_bytes_written += bytes_written;
00555
00556 _dbus_assert (unix_transport->message_bytes_written <=
00557 total_bytes_to_write);
00558
00559 if (unix_transport->message_bytes_written == total_bytes_to_write)
00560 {
00561 unix_transport->message_bytes_written = 0;
00562 _dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
00563
00564 _dbus_connection_message_sent (transport->connection,
00565 message);
00566 }
00567 }
00568 }
00569
00570 out:
00571 if (oom)
00572 return FALSE;
00573 else
00574 return TRUE;
00575 }
00576
00577
00578 static dbus_bool_t
00579 do_reading (DBusTransport *transport)
00580 {
00581 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00582 DBusString *buffer;
00583 int bytes_read;
00584 int total;
00585 dbus_bool_t oom;
00586
00587
00588 if (!_dbus_transport_get_is_authenticated (transport))
00589 return TRUE;
00590
00591 oom = FALSE;
00592
00593 total = 0;
00594
00595 again:
00596
00597
00598 check_read_watch (transport);
00599
00600 if (total > unix_transport->max_bytes_read_per_iteration)
00601 {
00602 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
00603 total, unix_transport->max_bytes_read_per_iteration);
00604 goto out;
00605 }
00606
00607 _dbus_assert (unix_transport->read_watch != NULL ||
00608 transport->disconnected);
00609
00610 if (transport->disconnected)
00611 goto out;
00612
00613 if (!dbus_watch_get_enabled (unix_transport->read_watch))
00614 return TRUE;
00615
00616 if (_dbus_auth_needs_decoding (transport->auth))
00617 {
00618 if (_dbus_string_get_length (&unix_transport->encoded_incoming) > 0)
00619 bytes_read = _dbus_string_get_length (&unix_transport->encoded_incoming);
00620 else
00621 bytes_read = _dbus_read (unix_transport->fd,
00622 &unix_transport->encoded_incoming,
00623 unix_transport->max_bytes_read_per_iteration);
00624
00625 _dbus_assert (_dbus_string_get_length (&unix_transport->encoded_incoming) ==
00626 bytes_read);
00627
00628 if (bytes_read > 0)
00629 {
00630 int orig_len;
00631
00632 _dbus_message_loader_get_buffer (transport->loader,
00633 &buffer);
00634
00635 orig_len = _dbus_string_get_length (buffer);
00636
00637 if (!_dbus_auth_decode_data (transport->auth,
00638 &unix_transport->encoded_incoming,
00639 buffer))
00640 {
00641 _dbus_verbose ("Out of memory decoding incoming data\n");
00642 oom = TRUE;
00643 goto out;
00644 }
00645
00646 _dbus_message_loader_return_buffer (transport->loader,
00647 buffer,
00648 _dbus_string_get_length (buffer) - orig_len);
00649
00650 _dbus_string_set_length (&unix_transport->encoded_incoming, 0);
00651 }
00652 }
00653 else
00654 {
00655 _dbus_message_loader_get_buffer (transport->loader,
00656 &buffer);
00657
00658 bytes_read = _dbus_read (unix_transport->fd,
00659 buffer, unix_transport->max_bytes_read_per_iteration);
00660
00661 _dbus_message_loader_return_buffer (transport->loader,
00662 buffer,
00663 bytes_read < 0 ? 0 : bytes_read);
00664 }
00665
00666 if (bytes_read < 0)
00667 {
00668
00669
00670 if (errno == ENOMEM)
00671 {
00672 _dbus_verbose ("Out of memory in read()/do_reading()\n");
00673 oom = TRUE;
00674 goto out;
00675 }
00676 else if (errno == EAGAIN ||
00677 errno == EWOULDBLOCK)
00678 goto out;
00679 else
00680 {
00681 _dbus_verbose ("Error reading from remote app: %s\n",
00682 _dbus_strerror (errno));
00683 do_io_error (transport);
00684 goto out;
00685 }
00686 }
00687 else if (bytes_read == 0)
00688 {
00689 _dbus_verbose ("Disconnected from remote app\n");
00690 do_io_error (transport);
00691 goto out;
00692 }
00693 else
00694 {
00695 _dbus_verbose (" read %d bytes\n", bytes_read);
00696
00697 total += bytes_read;
00698
00699 if (_dbus_transport_queue_messages (transport) == DBUS_DISPATCH_NEED_MEMORY)
00700 {
00701 oom = TRUE;
00702 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
00703 goto out;
00704 }
00705
00706
00707
00708
00709
00710 goto again;
00711 }
00712
00713 out:
00714 if (oom)
00715 return FALSE;
00716 else
00717 return TRUE;
00718 }
00719
00720 static dbus_bool_t
00721 unix_handle_watch (DBusTransport *transport,
00722 DBusWatch *watch,
00723 unsigned int flags)
00724 {
00725 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00726
00727 _dbus_assert (watch == unix_transport->read_watch ||
00728 watch == unix_transport->write_watch);
00729
00730 if (watch == unix_transport->read_watch &&
00731 (flags & DBUS_WATCH_READABLE))
00732 {
00733 #if 1
00734 _dbus_verbose ("handling read watch\n");
00735 #endif
00736 if (!do_authentication (transport, TRUE, FALSE))
00737 return FALSE;
00738
00739 if (!do_reading (transport))
00740 {
00741 _dbus_verbose ("no memory to read\n");
00742 return FALSE;
00743 }
00744 }
00745 else if (watch == unix_transport->write_watch &&
00746 (flags & DBUS_WATCH_WRITABLE))
00747 {
00748 #if 0
00749 _dbus_verbose ("handling write watch, messages_need_sending = %d\n",
00750 transport->messages_need_sending);
00751 #endif
00752 if (!do_authentication (transport, FALSE, TRUE))
00753 return FALSE;
00754
00755 if (!do_writing (transport))
00756 {
00757 _dbus_verbose ("no memory to write\n");
00758 return FALSE;
00759 }
00760 }
00761 #ifdef DBUS_ENABLE_VERBOSE_MODE
00762 else
00763 {
00764 if (watch == unix_transport->read_watch)
00765 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00766 flags);
00767 else if (watch == unix_transport->write_watch)
00768 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00769 flags);
00770 else
00771 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00772 watch, dbus_watch_get_fd (watch));
00773 }
00774 #endif
00775
00776 if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
00777 {
00778 _dbus_transport_disconnect (transport);
00779 return TRUE;
00780 }
00781
00782 return TRUE;
00783 }
00784
00785 static void
00786 unix_disconnect (DBusTransport *transport)
00787 {
00788 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00789
00790 free_watches (transport);
00791
00792 _dbus_close (unix_transport->fd, NULL);
00793 unix_transport->fd = -1;
00794 }
00795
00796 static dbus_bool_t
00797 unix_connection_set (DBusTransport *transport)
00798 {
00799 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00800
00801 _dbus_watch_set_handler (unix_transport->write_watch,
00802 _dbus_connection_handle_watch,
00803 transport->connection, NULL);
00804
00805 _dbus_watch_set_handler (unix_transport->read_watch,
00806 _dbus_connection_handle_watch,
00807 transport->connection, NULL);
00808
00809 if (!_dbus_connection_add_watch (transport->connection,
00810 unix_transport->write_watch))
00811 return FALSE;
00812
00813 if (!_dbus_connection_add_watch (transport->connection,
00814 unix_transport->read_watch))
00815 {
00816 _dbus_connection_remove_watch (transport->connection,
00817 unix_transport->write_watch);
00818 return FALSE;
00819 }
00820
00821 check_read_watch (transport);
00822 check_write_watch (transport);
00823
00824 return TRUE;
00825 }
00826
00827 static void
00828 unix_messages_pending (DBusTransport *transport,
00829 int messages_pending)
00830 {
00831 check_write_watch (transport);
00832 }
00833
00834
00842 static void
00843 unix_do_iteration (DBusTransport *transport,
00844 unsigned int flags,
00845 int timeout_milliseconds)
00846 {
00847 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00848 fd_set read_set;
00849 fd_set write_set;
00850 dbus_bool_t do_select;
00851 int select_res;
00852
00853 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n",
00854 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00855 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00856 timeout_milliseconds,
00857 unix_transport->read_watch,
00858 unix_transport->write_watch);
00859
00860
00861
00862
00863 again:
00864
00865 do_select = FALSE;
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876 FD_ZERO (&read_set);
00877 FD_ZERO (&write_set);
00878
00879 if (_dbus_transport_get_is_authenticated (transport))
00880 {
00881 if (unix_transport->read_watch &&
00882 (flags & DBUS_ITERATION_DO_READING))
00883 {
00884 FD_SET (unix_transport->fd, &read_set);
00885 do_select = TRUE;
00886 }
00887
00888 if (unix_transport->write_watch &&
00889 (flags & DBUS_ITERATION_DO_WRITING))
00890 {
00891 FD_SET (unix_transport->fd, &write_set);
00892 do_select = TRUE;
00893 }
00894 }
00895 else
00896 {
00897 DBusAuthState auth_state;
00898
00899 auth_state = _dbus_auth_do_work (transport->auth);
00900
00901 if (transport->receive_credentials_pending ||
00902 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
00903 {
00904 FD_SET (unix_transport->fd, &read_set);
00905 do_select = TRUE;
00906 }
00907
00908 if (transport->send_credentials_pending ||
00909 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
00910 {
00911 FD_SET (unix_transport->fd, &write_set);
00912 do_select = TRUE;
00913 }
00914 }
00915
00916 if (do_select)
00917 {
00918 fd_set err_set;
00919 struct timeval timeout;
00920 dbus_bool_t use_timeout;
00921
00922 FD_ZERO (&err_set);
00923 FD_SET (unix_transport->fd, &err_set);
00924
00925 if (flags & DBUS_ITERATION_BLOCK)
00926 {
00927 if (timeout_milliseconds >= 0)
00928 {
00929 timeout.tv_sec = timeout_milliseconds / 1000;
00930 timeout.tv_usec = (timeout_milliseconds % 1000) * 1000;
00931
00932
00933 use_timeout = TRUE;
00934 }
00935 else
00936 {
00937 use_timeout = FALSE;
00938 }
00939 }
00940 else
00941 {
00942
00943 timeout.tv_sec = 0;
00944 timeout.tv_usec = 0;
00945 use_timeout = TRUE;
00946 }
00947
00948
00949
00950
00951
00952
00953 if (flags & DBUS_ITERATION_BLOCK)
00954 _dbus_connection_unlock (transport->connection);
00955
00956 select_res = select (unix_transport->fd + 1,
00957 &read_set, &write_set, &err_set,
00958 use_timeout ? &timeout : NULL);
00959
00960 if (flags & DBUS_ITERATION_BLOCK)
00961 _dbus_connection_lock (transport->connection);
00962
00963
00964 if (select_res >= 0)
00965 {
00966 if (FD_ISSET (unix_transport->fd, &err_set))
00967 do_io_error (transport);
00968 else
00969 {
00970 dbus_bool_t need_read = FD_ISSET (unix_transport->fd, &read_set);
00971 dbus_bool_t need_write = FD_ISSET (unix_transport->fd, &write_set);
00972
00973 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
00974 need_read, need_write);
00975 do_authentication (transport, need_read, need_write);
00976
00977 if (need_read && (flags & DBUS_ITERATION_DO_READING))
00978 do_reading (transport);
00979 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
00980 do_writing (transport);
00981 }
00982 }
00983 else if (errno == EINTR)
00984 goto again;
00985 else
00986 {
00987 _dbus_verbose ("Error from select(): %s\n",
00988 _dbus_strerror (errno));
00989 }
00990 }
00991 }
00992
00993 static void
00994 unix_live_messages_changed (DBusTransport *transport)
00995 {
00996
00997 check_read_watch (transport);
00998 }
00999
01000 static DBusTransportVTable unix_vtable = {
01001 unix_finalize,
01002 unix_handle_watch,
01003 unix_disconnect,
01004 unix_connection_set,
01005 unix_messages_pending,
01006 unix_do_iteration,
01007 unix_live_messages_changed
01008 };
01009
01021 DBusTransport*
01022 _dbus_transport_new_for_fd (int fd,
01023 dbus_bool_t server,
01024 const DBusString *address)
01025 {
01026 DBusTransportUnix *unix_transport;
01027
01028 unix_transport = dbus_new0 (DBusTransportUnix, 1);
01029 if (unix_transport == NULL)
01030 return NULL;
01031
01032 if (!_dbus_string_init (&unix_transport->encoded_outgoing))
01033 goto failed_0;
01034
01035 if (!_dbus_string_init (&unix_transport->encoded_incoming))
01036 goto failed_1;
01037
01038 unix_transport->write_watch = _dbus_watch_new (fd,
01039 DBUS_WATCH_WRITABLE,
01040 FALSE,
01041 NULL, NULL, NULL);
01042 if (unix_transport->write_watch == NULL)
01043 goto failed_2;
01044
01045 unix_transport->read_watch = _dbus_watch_new (fd,
01046 DBUS_WATCH_READABLE,
01047 FALSE,
01048 NULL, NULL, NULL);
01049 if (unix_transport->read_watch == NULL)
01050 goto failed_3;
01051
01052 if (!_dbus_transport_init_base (&unix_transport->base,
01053 &unix_vtable,
01054 server, address))
01055 goto failed_4;
01056
01057 unix_transport->fd = fd;
01058 unix_transport->message_bytes_written = 0;
01059
01060
01061 unix_transport->max_bytes_read_per_iteration = 2048;
01062 unix_transport->max_bytes_written_per_iteration = 2048;
01063
01064 return (DBusTransport*) unix_transport;
01065
01066 failed_4:
01067 _dbus_watch_unref (unix_transport->read_watch);
01068 failed_3:
01069 _dbus_watch_unref (unix_transport->write_watch);
01070 failed_2:
01071 _dbus_string_free (&unix_transport->encoded_incoming);
01072 failed_1:
01073 _dbus_string_free (&unix_transport->encoded_outgoing);
01074 failed_0:
01075 dbus_free (unix_transport);
01076 return NULL;
01077 }
01078
01091 DBusTransport*
01092 _dbus_transport_new_for_domain_socket (const char *path,
01093 dbus_bool_t abstract,
01094 DBusError *error)
01095 {
01096 int fd;
01097 DBusTransport *transport;
01098 DBusString address;
01099
01100 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01101
01102 if (!_dbus_string_init (&address))
01103 {
01104 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01105 return NULL;
01106 }
01107
01108 fd = -1;
01109
01110 if ((abstract &&
01111 !_dbus_string_append (&address, "unix:abstract=")) ||
01112 (!abstract &&
01113 !_dbus_string_append (&address, "unix:path=")) ||
01114 !_dbus_string_append (&address, path))
01115 {
01116 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01117 goto failed_0;
01118 }
01119
01120 fd = _dbus_connect_unix_socket (path, abstract, error);
01121 if (fd < 0)
01122 {
01123 _DBUS_ASSERT_ERROR_IS_SET (error);
01124 goto failed_0;
01125 }
01126
01127 _dbus_fd_set_close_on_exec (fd);
01128
01129 _dbus_verbose ("Successfully connected to unix socket %s\n",
01130 path);
01131
01132 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
01133 if (transport == NULL)
01134 {
01135 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01136 goto failed_1;
01137 }
01138
01139 _dbus_string_free (&address);
01140
01141 return transport;
01142
01143 failed_1:
01144 _dbus_close (fd, NULL);
01145 failed_0:
01146 _dbus_string_free (&address);
01147 return NULL;
01148 }
01149
01158 DBusTransport*
01159 _dbus_transport_new_for_tcp_socket (const char *host,
01160 dbus_int32_t port,
01161 DBusError *error)
01162 {
01163 int fd;
01164 DBusTransport *transport;
01165 DBusString address;
01166
01167 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01168
01169 if (!_dbus_string_init (&address))
01170 {
01171 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01172 return NULL;
01173 }
01174
01175 if (!_dbus_string_append (&address, "tcp:host=") ||
01176 !_dbus_string_append (&address, host) ||
01177 !_dbus_string_append (&address, ",port=") ||
01178 !_dbus_string_append_int (&address, port))
01179 {
01180 _dbus_string_free (&address);
01181 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01182 return NULL;
01183 }
01184
01185 fd = _dbus_connect_tcp_socket (host, port, error);
01186 if (fd < 0)
01187 {
01188 _DBUS_ASSERT_ERROR_IS_SET (error);
01189 _dbus_string_free (&address);
01190 return NULL;
01191 }
01192
01193 _dbus_fd_set_close_on_exec (fd);
01194
01195 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
01196 host, port);
01197
01198 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
01199 if (transport == NULL)
01200 {
01201 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01202 _dbus_close (fd, NULL);
01203 _dbus_string_free (&address);
01204 fd = -1;
01205 }
01206
01207 _dbus_string_free (&address);
01208
01209 return transport;
01210 }
01211