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) == DBUS_DISPATCH_NEED_MEMORY)
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 if (watch == unix_transport->read_watch &&
00721 (flags & DBUS_WATCH_READABLE))
00722 {
00723 #if 1
00724 _dbus_verbose ("handling read watch\n");
00725 #endif
00726 if (!do_authentication (transport, TRUE, FALSE))
00727 return FALSE;
00728
00729 if (!do_reading (transport))
00730 {
00731 _dbus_verbose ("no memory to read\n");
00732 return FALSE;
00733 }
00734 }
00735 else if (watch == unix_transport->write_watch &&
00736 (flags & DBUS_WATCH_WRITABLE))
00737 {
00738 #if 0
00739 _dbus_verbose ("handling write watch, messages_need_sending = %d\n",
00740 transport->messages_need_sending);
00741 #endif
00742 if (!do_authentication (transport, FALSE, TRUE))
00743 return FALSE;
00744
00745 if (!do_writing (transport))
00746 {
00747 _dbus_verbose ("no memory to write\n");
00748 return FALSE;
00749 }
00750 }
00751 #ifdef DBUS_ENABLE_VERBOSE_MODE
00752 else
00753 {
00754 if (watch == unix_transport->read_watch)
00755 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
00756 flags);
00757 else if (watch == unix_transport->write_watch)
00758 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
00759 flags);
00760 else
00761 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
00762 watch, dbus_watch_get_fd (watch));
00763 }
00764 #endif
00765
00766 if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
00767 {
00768 _dbus_transport_disconnect (transport);
00769 return TRUE;
00770 }
00771
00772 return TRUE;
00773 }
00774
00775 static void
00776 unix_disconnect (DBusTransport *transport)
00777 {
00778 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00779
00780 free_watches (transport);
00781
00782 _dbus_close (unix_transport->fd, NULL);
00783 unix_transport->fd = -1;
00784 }
00785
00786 static dbus_bool_t
00787 unix_connection_set (DBusTransport *transport)
00788 {
00789 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00790
00791 _dbus_watch_set_handler (unix_transport->write_watch,
00792 _dbus_connection_handle_watch,
00793 transport->connection, NULL);
00794
00795 _dbus_watch_set_handler (unix_transport->read_watch,
00796 _dbus_connection_handle_watch,
00797 transport->connection, NULL);
00798
00799 if (!_dbus_connection_add_watch (transport->connection,
00800 unix_transport->write_watch))
00801 return FALSE;
00802
00803 if (!_dbus_connection_add_watch (transport->connection,
00804 unix_transport->read_watch))
00805 {
00806 _dbus_connection_remove_watch (transport->connection,
00807 unix_transport->write_watch);
00808 return FALSE;
00809 }
00810
00811 check_read_watch (transport);
00812 check_write_watch (transport);
00813
00814 return TRUE;
00815 }
00816
00817 static void
00818 unix_messages_pending (DBusTransport *transport,
00819 int messages_pending)
00820 {
00821 check_write_watch (transport);
00822 }
00823
00831 static void
00832 unix_do_iteration (DBusTransport *transport,
00833 unsigned int flags,
00834 int timeout_milliseconds)
00835 {
00836 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
00837 DBusPollFD poll_fd;
00838 int poll_res;
00839 int poll_timeout;
00840
00841 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n",
00842 flags & DBUS_ITERATION_DO_READING ? "read" : "",
00843 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
00844 timeout_milliseconds,
00845 unix_transport->read_watch,
00846 unix_transport->write_watch);
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857 poll_fd.fd = unix_transport->fd;
00858 poll_fd.events = 0;
00859
00860 if (_dbus_transport_get_is_authenticated (transport))
00861 {
00862 if (unix_transport->read_watch &&
00863 (flags & DBUS_ITERATION_DO_READING))
00864 poll_fd.events |= _DBUS_POLLIN;
00865
00866 if (unix_transport->write_watch &&
00867 (flags & DBUS_ITERATION_DO_WRITING))
00868 poll_fd.events |= _DBUS_POLLOUT;
00869 }
00870 else
00871 {
00872 DBusAuthState auth_state;
00873
00874 auth_state = _dbus_auth_do_work (transport->auth);
00875
00876 if (transport->receive_credentials_pending ||
00877 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
00878 poll_fd.events |= _DBUS_POLLIN;
00879
00880 if (transport->send_credentials_pending ||
00881 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
00882 poll_fd.events |= _DBUS_POLLOUT;
00883 }
00884
00885 if (poll_fd.events)
00886 {
00887 if (flags & DBUS_ITERATION_BLOCK)
00888 poll_timeout = timeout_milliseconds;
00889 else
00890 poll_timeout = 0;
00891
00892
00893
00894
00895
00896
00897 if (flags & DBUS_ITERATION_BLOCK)
00898 _dbus_connection_unlock (transport->connection);
00899
00900 again:
00901 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
00902
00903 if (poll_res < 0 && errno == EINTR)
00904 goto again;
00905
00906 if (flags & DBUS_ITERATION_BLOCK)
00907 _dbus_connection_lock (transport->connection);
00908
00909 if (poll_res >= 0)
00910 {
00911 if (poll_fd.revents & _DBUS_POLLERR)
00912 do_io_error (transport);
00913 else
00914 {
00915 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
00916 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
00917
00918 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
00919 need_read, need_write);
00920 do_authentication (transport, need_read, need_write);
00921
00922 if (need_read && (flags & DBUS_ITERATION_DO_READING))
00923 do_reading (transport);
00924 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
00925 do_writing (transport);
00926 }
00927 }
00928 else
00929 {
00930 _dbus_verbose ("Error from _dbus_poll(): %s\n",
00931 _dbus_strerror (errno));
00932 }
00933 }
00934 }
00935
00936 static void
00937 unix_live_messages_changed (DBusTransport *transport)
00938 {
00939
00940 check_read_watch (transport);
00941 }
00942
00943 static DBusTransportVTable 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 DBusTransport*
00965 _dbus_transport_new_for_fd (int fd,
00966 dbus_bool_t server,
00967 const DBusString *address)
00968 {
00969 DBusTransportUnix *unix_transport;
00970
00971 unix_transport = dbus_new0 (DBusTransportUnix, 1);
00972 if (unix_transport == NULL)
00973 return NULL;
00974
00975 if (!_dbus_string_init (&unix_transport->encoded_outgoing))
00976 goto failed_0;
00977
00978 if (!_dbus_string_init (&unix_transport->encoded_incoming))
00979 goto failed_1;
00980
00981 unix_transport->write_watch = _dbus_watch_new (fd,
00982 DBUS_WATCH_WRITABLE,
00983 FALSE,
00984 NULL, NULL, NULL);
00985 if (unix_transport->write_watch == NULL)
00986 goto failed_2;
00987
00988 unix_transport->read_watch = _dbus_watch_new (fd,
00989 DBUS_WATCH_READABLE,
00990 FALSE,
00991 NULL, NULL, NULL);
00992 if (unix_transport->read_watch == NULL)
00993 goto failed_3;
00994
00995 if (!_dbus_transport_init_base (&unix_transport->base,
00996 &unix_vtable,
00997 server, address))
00998 goto failed_4;
00999
01000 unix_transport->fd = fd;
01001 unix_transport->message_bytes_written = 0;
01002
01003
01004 unix_transport->max_bytes_read_per_iteration = 2048;
01005 unix_transport->max_bytes_written_per_iteration = 2048;
01006
01007 return (DBusTransport*) unix_transport;
01008
01009 failed_4:
01010 _dbus_watch_unref (unix_transport->read_watch);
01011 failed_3:
01012 _dbus_watch_unref (unix_transport->write_watch);
01013 failed_2:
01014 _dbus_string_free (&unix_transport->encoded_incoming);
01015 failed_1:
01016 _dbus_string_free (&unix_transport->encoded_outgoing);
01017 failed_0:
01018 dbus_free (unix_transport);
01019 return NULL;
01020 }
01021
01034 DBusTransport*
01035 _dbus_transport_new_for_domain_socket (const char *path,
01036 dbus_bool_t abstract,
01037 DBusError *error)
01038 {
01039 int fd;
01040 DBusTransport *transport;
01041 DBusString address;
01042
01043 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01044
01045 if (!_dbus_string_init (&address))
01046 {
01047 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01048 return NULL;
01049 }
01050
01051 fd = -1;
01052
01053 if ((abstract &&
01054 !_dbus_string_append (&address, "unix:abstract=")) ||
01055 (!abstract &&
01056 !_dbus_string_append (&address, "unix:path=")) ||
01057 !_dbus_string_append (&address, path))
01058 {
01059 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01060 goto failed_0;
01061 }
01062
01063 fd = _dbus_connect_unix_socket (path, abstract, error);
01064 if (fd < 0)
01065 {
01066 _DBUS_ASSERT_ERROR_IS_SET (error);
01067 goto failed_0;
01068 }
01069
01070 _dbus_fd_set_close_on_exec (fd);
01071
01072 _dbus_verbose ("Successfully connected to unix socket %s\n",
01073 path);
01074
01075 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
01076 if (transport == NULL)
01077 {
01078 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01079 goto failed_1;
01080 }
01081
01082 _dbus_string_free (&address);
01083
01084 return transport;
01085
01086 failed_1:
01087 _dbus_close (fd, NULL);
01088 failed_0:
01089 _dbus_string_free (&address);
01090 return NULL;
01091 }
01092
01101 DBusTransport*
01102 _dbus_transport_new_for_tcp_socket (const char *host,
01103 dbus_int32_t port,
01104 DBusError *error)
01105 {
01106 int fd;
01107 DBusTransport *transport;
01108 DBusString address;
01109
01110 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01111
01112 if (!_dbus_string_init (&address))
01113 {
01114 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01115 return NULL;
01116 }
01117
01118 if (!_dbus_string_append (&address, "tcp:host=") ||
01119 !_dbus_string_append (&address, host) ||
01120 !_dbus_string_append (&address, ",port=") ||
01121 !_dbus_string_append_int (&address, port))
01122 {
01123 _dbus_string_free (&address);
01124 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01125 return NULL;
01126 }
01127
01128 fd = _dbus_connect_tcp_socket (host, port, error);
01129 if (fd < 0)
01130 {
01131 _DBUS_ASSERT_ERROR_IS_SET (error);
01132 _dbus_string_free (&address);
01133 return NULL;
01134 }
01135
01136 _dbus_fd_set_close_on_exec (fd);
01137
01138 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
01139 host, port);
01140
01141 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
01142 if (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 return transport;
01153 }
01154