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