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