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