1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-transport-unix.c UNIX socket subclasses of DBusTransport
4 * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
6 * Licensed under the Academic Free License version 2.1
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus-internals.h"
25 #include "dbus-connection-internal.h"
26 #include "dbus-transport-unix.h"
27 #include "dbus-transport-protected.h"
28 #include "dbus-watch.h"
32 * @defgroup DBusTransportUnix DBusTransport implementations for UNIX
33 * @ingroup DBusInternals
34 * @brief Implementation details of DBusTransport on UNIX
40 * Opaque object representing a Unix file descriptor transport.
42 typedef struct DBusTransportUnix DBusTransportUnix;
45 * Implementation details of DBusTransportUnix. All members are private.
47 struct DBusTransportUnix
49 DBusTransport base; /**< Parent instance */
50 int fd; /**< File descriptor. */
51 DBusWatch *read_watch; /**< Watch for readability. */
52 DBusWatch *write_watch; /**< Watch for writability. */
54 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
55 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
57 int message_bytes_written; /**< Number of bytes of current
58 * outgoing message that have
61 DBusString encoded_outgoing; /**< Encoded version of current
64 DBusString encoded_incoming; /**< Encoded version of current
70 free_watches (DBusTransport *transport)
72 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
74 if (unix_transport->read_watch)
76 if (transport->connection)
77 _dbus_connection_remove_watch (transport->connection,
78 unix_transport->read_watch);
79 _dbus_watch_invalidate (unix_transport->read_watch);
80 _dbus_watch_unref (unix_transport->read_watch);
81 unix_transport->read_watch = NULL;
84 if (unix_transport->write_watch)
86 if (transport->connection)
87 _dbus_connection_remove_watch (transport->connection,
88 unix_transport->write_watch);
89 _dbus_watch_invalidate (unix_transport->write_watch);
90 _dbus_watch_unref (unix_transport->write_watch);
91 unix_transport->write_watch = NULL;
96 unix_finalize (DBusTransport *transport)
98 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
100 free_watches (transport);
102 _dbus_string_free (&unix_transport->encoded_outgoing);
103 _dbus_string_free (&unix_transport->encoded_incoming);
105 _dbus_transport_finalize_base (transport);
107 _dbus_assert (unix_transport->read_watch == NULL);
108 _dbus_assert (unix_transport->write_watch == NULL);
110 dbus_free (transport);
114 check_write_watch (DBusTransport *transport)
116 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
119 if (transport->connection == NULL)
122 if (transport->disconnected)
124 _dbus_assert (unix_transport->write_watch == NULL);
128 _dbus_transport_ref (transport);
130 if (_dbus_transport_get_is_authenticated (transport))
131 needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
134 if (transport->send_credentials_pending)
138 DBusAuthState auth_state;
140 auth_state = _dbus_auth_do_work (transport->auth);
142 /* If we need memory we install the write watch just in case,
143 * if there's no need for it, it will get de-installed
144 * next time we try reading.
146 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
147 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
154 _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
155 needed, transport->connection, unix_transport->write_watch,
157 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
159 _dbus_connection_toggle_watch (transport->connection,
160 unix_transport->write_watch,
163 _dbus_transport_unref (transport);
167 check_read_watch (DBusTransport *transport)
169 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
170 dbus_bool_t need_read_watch;
172 _dbus_verbose ("%s: fd = %d\n",
173 _DBUS_FUNCTION_NAME, unix_transport->fd);
175 if (transport->connection == NULL)
178 if (transport->disconnected)
180 _dbus_assert (unix_transport->read_watch == NULL);
184 _dbus_transport_ref (transport);
186 if (_dbus_transport_get_is_authenticated (transport))
188 _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
191 if (transport->receive_credentials_pending)
192 need_read_watch = TRUE;
195 /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
196 * is to avoid spinning on the file descriptor when we're waiting
197 * to write or for some other part of the auth process
199 DBusAuthState auth_state;
201 auth_state = _dbus_auth_do_work (transport->auth);
203 /* If we need memory we install the read watch just in case,
204 * if there's no need for it, it will get de-installed
205 * next time we try reading. If we're authenticated we
206 * install it since we normally have it installed while
209 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
210 auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
211 auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
212 need_read_watch = TRUE;
214 need_read_watch = FALSE;
218 _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
219 _dbus_connection_toggle_watch (transport->connection,
220 unix_transport->read_watch,
223 _dbus_transport_unref (transport);
227 do_io_error (DBusTransport *transport)
229 _dbus_transport_ref (transport);
230 _dbus_transport_disconnect (transport);
231 _dbus_transport_unref (transport);
234 /* return value is whether we successfully read any new data. */
236 read_data_into_auth (DBusTransport *transport,
239 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
245 _dbus_auth_get_buffer (transport->auth, &buffer);
247 bytes_read = _dbus_read (unix_transport->fd,
248 buffer, unix_transport->max_bytes_read_per_iteration);
250 _dbus_auth_return_buffer (transport->auth, buffer,
251 bytes_read > 0 ? bytes_read : 0);
255 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
259 else if (bytes_read < 0)
261 /* EINTR already handled for us */
267 else if (errno == EAGAIN ||
268 errno == EWOULDBLOCK)
269 ; /* do nothing, just return FALSE below */
272 _dbus_verbose ("Error reading from remote app: %s\n",
273 _dbus_strerror (errno));
274 do_io_error (transport);
281 _dbus_assert (bytes_read == 0);
283 _dbus_verbose ("Disconnected from remote app\n");
284 do_io_error (transport);
290 /* Return value is whether we successfully wrote any bytes */
292 write_data_from_auth (DBusTransport *transport)
294 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
296 const DBusString *buffer;
298 if (!_dbus_auth_get_bytes_to_send (transport->auth,
302 bytes_written = _dbus_write (unix_transport->fd,
304 0, _dbus_string_get_length (buffer));
306 if (bytes_written > 0)
308 _dbus_auth_bytes_sent (transport->auth, bytes_written);
311 else if (bytes_written < 0)
313 /* EINTR already handled for us */
315 if (errno == EAGAIN ||
316 errno == EWOULDBLOCK)
320 _dbus_verbose ("Error writing to remote app: %s\n",
321 _dbus_strerror (errno));
322 do_io_error (transport);
330 exchange_credentials (DBusTransport *transport,
331 dbus_bool_t do_reading,
332 dbus_bool_t do_writing)
334 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
336 if (do_writing && transport->send_credentials_pending)
338 if (_dbus_send_credentials_unix_socket (unix_transport->fd,
341 transport->send_credentials_pending = FALSE;
345 _dbus_verbose ("Failed to write credentials\n");
346 do_io_error (transport);
350 if (do_reading && transport->receive_credentials_pending)
352 if (_dbus_read_credentials_unix_socket (unix_transport->fd,
353 &transport->credentials,
356 transport->receive_credentials_pending = FALSE;
360 _dbus_verbose ("Failed to read credentials\n");
361 do_io_error (transport);
365 if (!(transport->send_credentials_pending ||
366 transport->receive_credentials_pending))
368 _dbus_auth_set_credentials (transport->auth,
369 &transport->credentials);
374 do_authentication (DBusTransport *transport,
375 dbus_bool_t do_reading,
376 dbus_bool_t do_writing,
377 dbus_bool_t *auth_completed)
380 dbus_bool_t orig_auth_state;
384 orig_auth_state = _dbus_transport_get_is_authenticated (transport);
386 /* This is essential to avoid the check_write_watch() at the end,
387 * we don't want to add a write watch in do_iteration before
388 * we try writing and get EAGAIN
393 *auth_completed = FALSE;
397 _dbus_transport_ref (transport);
399 while (!_dbus_transport_get_is_authenticated (transport) &&
400 _dbus_transport_get_is_connected (transport))
402 exchange_credentials (transport, do_reading, do_writing);
404 if (transport->send_credentials_pending ||
405 transport->receive_credentials_pending)
407 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
408 transport->send_credentials_pending,
409 transport->receive_credentials_pending);
413 #define TRANSPORT_SIDE(t) ((t)->is_server ? "server" : "client")
414 switch (_dbus_auth_do_work (transport->auth))
416 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
417 _dbus_verbose (" %s auth state: waiting for input\n",
418 TRANSPORT_SIDE (transport));
419 if (!do_reading || !read_data_into_auth (transport, &oom))
423 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
424 _dbus_verbose (" %s auth state: waiting for memory\n",
425 TRANSPORT_SIDE (transport));
430 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
431 _dbus_verbose (" %s auth state: bytes to send\n",
432 TRANSPORT_SIDE (transport));
433 if (!do_writing || !write_data_from_auth (transport))
437 case DBUS_AUTH_STATE_NEED_DISCONNECT:
438 _dbus_verbose (" %s auth state: need to disconnect\n",
439 TRANSPORT_SIDE (transport));
440 do_io_error (transport);
443 case DBUS_AUTH_STATE_AUTHENTICATED:
444 _dbus_verbose (" %s auth state: authenticated\n",
445 TRANSPORT_SIDE (transport));
452 *auth_completed = (orig_auth_state != _dbus_transport_get_is_authenticated (transport));
454 check_read_watch (transport);
455 check_write_watch (transport);
456 _dbus_transport_unref (transport);
464 /* returns false on oom */
466 do_writing (DBusTransport *transport)
469 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
472 /* No messages without authentication! */
473 if (!_dbus_transport_get_is_authenticated (transport))
475 _dbus_verbose ("Not authenticated, not writing anything\n");
479 if (transport->disconnected)
481 _dbus_verbose ("Not connected, not writing anything\n");
486 _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
487 _dbus_connection_has_messages_to_send_unlocked (transport->connection),
494 while (!transport->disconnected &&
495 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
498 DBusMessage *message;
499 const DBusString *header;
500 const DBusString *body;
501 int header_len, body_len;
502 int total_bytes_to_write;
504 if (total > unix_transport->max_bytes_written_per_iteration)
506 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
507 total, unix_transport->max_bytes_written_per_iteration);
511 message = _dbus_connection_get_message_to_send (transport->connection);
512 _dbus_assert (message != NULL);
513 _dbus_message_lock (message);
516 _dbus_verbose ("writing message %p\n", message);
519 _dbus_message_get_network_data (message,
522 header_len = _dbus_string_get_length (header);
523 body_len = _dbus_string_get_length (body);
525 if (_dbus_auth_needs_encoding (transport->auth))
527 if (_dbus_string_get_length (&unix_transport->encoded_outgoing) == 0)
529 if (!_dbus_auth_encode_data (transport->auth,
530 header, &unix_transport->encoded_outgoing))
536 if (!_dbus_auth_encode_data (transport->auth,
537 body, &unix_transport->encoded_outgoing))
539 _dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
545 total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_outgoing);
548 _dbus_verbose ("encoded message is %d bytes\n",
549 total_bytes_to_write);
553 _dbus_write (unix_transport->fd,
554 &unix_transport->encoded_outgoing,
555 unix_transport->message_bytes_written,
556 total_bytes_to_write - unix_transport->message_bytes_written);
560 total_bytes_to_write = header_len + body_len;
563 _dbus_verbose ("message is %d bytes\n",
564 total_bytes_to_write);
567 if (unix_transport->message_bytes_written < header_len)
570 _dbus_write_two (unix_transport->fd,
572 unix_transport->message_bytes_written,
573 header_len - unix_transport->message_bytes_written,
580 _dbus_write (unix_transport->fd,
582 (unix_transport->message_bytes_written - header_len),
584 (unix_transport->message_bytes_written - header_len));
588 if (bytes_written < 0)
590 /* EINTR already handled for us */
592 if (errno == EAGAIN ||
593 errno == EWOULDBLOCK)
597 _dbus_verbose ("Error writing to remote app: %s\n",
598 _dbus_strerror (errno));
599 do_io_error (transport);
605 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
606 total_bytes_to_write);
608 total += bytes_written;
609 unix_transport->message_bytes_written += bytes_written;
611 _dbus_assert (unix_transport->message_bytes_written <=
612 total_bytes_to_write);
614 if (unix_transport->message_bytes_written == total_bytes_to_write)
616 unix_transport->message_bytes_written = 0;
617 _dbus_string_set_length (&unix_transport->encoded_outgoing, 0);
619 _dbus_connection_message_sent (transport->connection,
632 /* returns false on out-of-memory */
634 do_reading (DBusTransport *transport)
636 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
642 _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
645 /* No messages without authentication! */
646 if (!_dbus_transport_get_is_authenticated (transport))
655 /* See if we've exceeded max messages and need to disable reading */
656 check_read_watch (transport);
658 if (total > unix_transport->max_bytes_read_per_iteration)
660 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
661 total, unix_transport->max_bytes_read_per_iteration);
665 _dbus_assert (unix_transport->read_watch != NULL ||
666 transport->disconnected);
668 if (transport->disconnected)
671 if (!dbus_watch_get_enabled (unix_transport->read_watch))
674 if (_dbus_auth_needs_decoding (transport->auth))
676 if (_dbus_string_get_length (&unix_transport->encoded_incoming) > 0)
677 bytes_read = _dbus_string_get_length (&unix_transport->encoded_incoming);
679 bytes_read = _dbus_read (unix_transport->fd,
680 &unix_transport->encoded_incoming,
681 unix_transport->max_bytes_read_per_iteration);
683 _dbus_assert (_dbus_string_get_length (&unix_transport->encoded_incoming) ==
690 _dbus_message_loader_get_buffer (transport->loader,
693 orig_len = _dbus_string_get_length (buffer);
695 if (!_dbus_auth_decode_data (transport->auth,
696 &unix_transport->encoded_incoming,
699 _dbus_verbose ("Out of memory decoding incoming data\n");
704 _dbus_message_loader_return_buffer (transport->loader,
706 _dbus_string_get_length (buffer) - orig_len);
708 _dbus_string_set_length (&unix_transport->encoded_incoming, 0);
713 _dbus_message_loader_get_buffer (transport->loader,
716 bytes_read = _dbus_read (unix_transport->fd,
717 buffer, unix_transport->max_bytes_read_per_iteration);
719 _dbus_message_loader_return_buffer (transport->loader,
721 bytes_read < 0 ? 0 : bytes_read);
726 /* EINTR already handled for us */
730 _dbus_verbose ("Out of memory in read()/do_reading()\n");
734 else if (errno == EAGAIN ||
735 errno == EWOULDBLOCK)
739 _dbus_verbose ("Error reading from remote app: %s\n",
740 _dbus_strerror (errno));
741 do_io_error (transport);
745 else if (bytes_read == 0)
747 _dbus_verbose ("Disconnected from remote app\n");
748 do_io_error (transport);
753 _dbus_verbose (" read %d bytes\n", bytes_read);
757 if (!_dbus_transport_queue_messages (transport))
760 _dbus_verbose (" out of memory when queueing messages we just read in the transport\n");
764 /* Try reading more data until we get EAGAIN and return, or
765 * exceed max bytes per iteration. If in blocking mode of
766 * course we'll block instead of returning.
779 unix_handle_watch (DBusTransport *transport,
783 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
785 _dbus_assert (watch == unix_transport->read_watch ||
786 watch == unix_transport->write_watch);
787 _dbus_assert (watch != NULL);
789 /* Disconnect in case of an error. In case of hangup do not
790 * disconnect the transport because data can still be in the buffer
791 * and do_reading may need several iteration to read it all (because
792 * of its max_bytes_read_per_iteration limit). The condition where
793 * flags == HANGUP (without READABLE) probably never happen in fact.
795 if ((flags & DBUS_WATCH_ERROR) ||
796 ((flags & DBUS_WATCH_HANGUP) && !(flags & DBUS_WATCH_READABLE)))
798 _dbus_verbose ("Hang up or error on watch\n");
799 _dbus_transport_disconnect (transport);
803 if (watch == unix_transport->read_watch &&
804 (flags & DBUS_WATCH_READABLE))
806 dbus_bool_t auth_finished;
808 _dbus_verbose ("handling read watch %p flags = %x\n",
811 if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
814 /* We don't want to do a read immediately following
815 * a successful authentication. This is so we
816 * have a chance to propagate the authentication
817 * state further up. Specifically, we need to
818 * process any pending data from the auth object.
822 if (!do_reading (transport))
824 _dbus_verbose ("no memory to read\n");
830 _dbus_verbose ("Not reading anything since we just completed the authentication\n");
833 else if (watch == unix_transport->write_watch &&
834 (flags & DBUS_WATCH_WRITABLE))
837 _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
838 _dbus_connection_has_messages_to_send_unlocked (transport->connection));
840 if (!do_authentication (transport, FALSE, TRUE, NULL))
843 if (!do_writing (transport))
845 _dbus_verbose ("no memory to write\n");
849 /* See if we still need the write watch */
850 check_write_watch (transport);
852 #ifdef DBUS_ENABLE_VERBOSE_MODE
855 if (watch == unix_transport->read_watch)
856 _dbus_verbose ("asked to handle read watch with non-read condition 0x%x\n",
858 else if (watch == unix_transport->write_watch)
859 _dbus_verbose ("asked to handle write watch with non-write condition 0x%x\n",
862 _dbus_verbose ("asked to handle watch %p on fd %d that we don't recognize\n",
863 watch, dbus_watch_get_fd (watch));
865 #endif /* DBUS_ENABLE_VERBOSE_MODE */
871 unix_disconnect (DBusTransport *transport)
873 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
875 free_watches (transport);
877 _dbus_close (unix_transport->fd, NULL);
878 unix_transport->fd = -1;
882 unix_connection_set (DBusTransport *transport)
884 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
886 _dbus_watch_set_handler (unix_transport->write_watch,
887 _dbus_connection_handle_watch,
888 transport->connection, NULL);
890 _dbus_watch_set_handler (unix_transport->read_watch,
891 _dbus_connection_handle_watch,
892 transport->connection, NULL);
894 if (!_dbus_connection_add_watch (transport->connection,
895 unix_transport->write_watch))
898 if (!_dbus_connection_add_watch (transport->connection,
899 unix_transport->read_watch))
901 _dbus_connection_remove_watch (transport->connection,
902 unix_transport->write_watch);
906 check_read_watch (transport);
907 check_write_watch (transport);
913 * @todo We need to have a way to wake up the select sleep if
914 * a new iteration request comes in with a flag (read/write) that
915 * we're not currently serving. Otherwise a call that just reads
916 * could block a write call forever (if there are no incoming
920 unix_do_iteration (DBusTransport *transport,
922 int timeout_milliseconds)
924 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
929 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
930 flags & DBUS_ITERATION_DO_READING ? "read" : "",
931 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
932 timeout_milliseconds,
933 unix_transport->read_watch,
934 unix_transport->write_watch,
937 /* the passed in DO_READING/DO_WRITING flags indicate whether to
938 * read/write messages, but regardless of those we may need to block
939 * for reading/writing to do auth. But if we do reading for auth,
940 * we don't want to read any messages yet if not given DO_READING.
943 poll_fd.fd = unix_transport->fd;
946 if (_dbus_transport_get_is_authenticated (transport))
948 /* This is kind of a hack; if we have stuff to write, then try
949 * to avoid the poll. This is probably about a 5% speedup on an
950 * echo client/server.
952 * If both reading and writing were requested, we want to avoid this
953 * since it could have funky effects:
954 * - both ends spinning waiting for the other one to read
955 * data so they can finish writing
956 * - prioritizing all writing ahead of reading
958 if ((flags & DBUS_ITERATION_DO_WRITING) &&
959 !(flags & (DBUS_ITERATION_DO_READING | DBUS_ITERATION_BLOCK)) &&
960 !transport->disconnected &&
961 _dbus_connection_has_messages_to_send_unlocked (transport->connection))
963 do_writing (transport);
965 if (transport->disconnected ||
966 !_dbus_connection_has_messages_to_send_unlocked (transport->connection))
970 /* If we get here, we decided to do the poll() after all */
971 _dbus_assert (unix_transport->read_watch);
972 if (flags & DBUS_ITERATION_DO_READING)
973 poll_fd.events |= _DBUS_POLLIN;
975 _dbus_assert (unix_transport->write_watch);
976 if (flags & DBUS_ITERATION_DO_WRITING)
977 poll_fd.events |= _DBUS_POLLOUT;
981 DBusAuthState auth_state;
983 auth_state = _dbus_auth_do_work (transport->auth);
985 if (transport->receive_credentials_pending ||
986 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
987 poll_fd.events |= _DBUS_POLLIN;
989 if (transport->send_credentials_pending ||
990 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
991 poll_fd.events |= _DBUS_POLLOUT;
996 if (flags & DBUS_ITERATION_BLOCK)
997 poll_timeout = timeout_milliseconds;
1001 /* For blocking selects we drop the connection lock here
1002 * to avoid blocking out connection access during a potentially
1003 * indefinite blocking call. The io path is still protected
1004 * by the io_path_cond condvar, so we won't reenter this.
1006 if (flags & DBUS_ITERATION_BLOCK)
1007 _dbus_connection_unlock (transport->connection);
1010 poll_res = _dbus_poll (&poll_fd, 1, poll_timeout);
1012 if (poll_res < 0 && errno == EINTR)
1015 if (flags & DBUS_ITERATION_BLOCK)
1016 _dbus_connection_lock (transport->connection);
1020 if (poll_fd.revents & _DBUS_POLLERR)
1021 do_io_error (transport);
1024 dbus_bool_t need_read = (poll_fd.revents & _DBUS_POLLIN) > 0;
1025 dbus_bool_t need_write = (poll_fd.revents & _DBUS_POLLOUT) > 0;
1026 dbus_bool_t authentication_completed;
1028 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1029 need_read, need_write);
1030 do_authentication (transport, need_read, need_write,
1031 &authentication_completed);
1033 /* See comment in unix_handle_watch. */
1034 if (authentication_completed)
1037 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1038 do_reading (transport);
1039 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1040 do_writing (transport);
1045 _dbus_verbose ("Error from _dbus_poll(): %s\n",
1046 _dbus_strerror (errno));
1052 /* We need to install the write watch only if we did not
1053 * successfully write everything. Note we need to be careful that we
1054 * don't call check_write_watch *before* do_writing, since it's
1055 * inefficient to add the write watch, and we can avoid it most of
1056 * the time since we can write immediately.
1058 * However, we MUST always call check_write_watch(); DBusConnection code
1059 * relies on the fact that running an iteration will notice that
1060 * messages are pending.
1062 check_write_watch (transport);
1064 _dbus_verbose (" ... leaving do_iteration()\n");
1068 unix_live_messages_changed (DBusTransport *transport)
1070 /* See if we should look for incoming messages again */
1071 check_read_watch (transport);
1076 unix_get_unix_fd (DBusTransport *transport,
1079 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
1081 *fd_p = unix_transport->fd;
1086 static DBusTransportVTable unix_vtable = {
1090 unix_connection_set,
1092 unix_live_messages_changed,
1097 * Creates a new transport for the given file descriptor. The file
1098 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1099 * make it so). This function is shared by various transports that
1100 * boil down to a full duplex file descriptor.
1102 * @param fd the file descriptor.
1103 * @param server #TRUE if this transport is on the server side of a connection
1104 * @param address the transport's address
1105 * @returns the new transport, or #NULL if no memory.
1108 _dbus_transport_new_for_fd (int fd,
1110 const DBusString *address)
1112 DBusTransportUnix *unix_transport;
1114 unix_transport = dbus_new0 (DBusTransportUnix, 1);
1115 if (unix_transport == NULL)
1118 if (!_dbus_string_init (&unix_transport->encoded_outgoing))
1121 if (!_dbus_string_init (&unix_transport->encoded_incoming))
1124 unix_transport->write_watch = _dbus_watch_new (fd,
1125 DBUS_WATCH_WRITABLE,
1128 if (unix_transport->write_watch == NULL)
1131 unix_transport->read_watch = _dbus_watch_new (fd,
1132 DBUS_WATCH_READABLE,
1135 if (unix_transport->read_watch == NULL)
1138 if (!_dbus_transport_init_base (&unix_transport->base,
1143 unix_transport->fd = fd;
1144 unix_transport->message_bytes_written = 0;
1146 /* These values should probably be tunable or something. */
1147 unix_transport->max_bytes_read_per_iteration = 2048;
1148 unix_transport->max_bytes_written_per_iteration = 2048;
1150 return (DBusTransport*) unix_transport;
1153 _dbus_watch_unref (unix_transport->read_watch);
1155 _dbus_watch_unref (unix_transport->write_watch);
1157 _dbus_string_free (&unix_transport->encoded_incoming);
1159 _dbus_string_free (&unix_transport->encoded_outgoing);
1161 dbus_free (unix_transport);
1166 * Creates a new transport for the given Unix domain socket
1167 * path. This creates a client-side of a transport.
1169 * @todo once we add a way to escape paths in a dbus
1170 * address, this function needs to do escaping.
1172 * @param path the path to the domain socket.
1173 * @param abstract #TRUE to use abstract socket namespace
1174 * @param error address where an error can be returned.
1175 * @returns a new transport, or #NULL on failure.
1178 _dbus_transport_new_for_domain_socket (const char *path,
1179 dbus_bool_t abstract,
1183 DBusTransport *transport;
1186 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1188 if (!_dbus_string_init (&address))
1190 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1197 !_dbus_string_append (&address, "unix:abstract=")) ||
1199 !_dbus_string_append (&address, "unix:path=")) ||
1200 !_dbus_string_append (&address, path))
1202 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1206 fd = _dbus_connect_unix_socket (path, abstract, error);
1209 _DBUS_ASSERT_ERROR_IS_SET (error);
1213 _dbus_fd_set_close_on_exec (fd);
1215 _dbus_verbose ("Successfully connected to unix socket %s\n",
1218 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
1219 if (transport == NULL)
1221 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1225 _dbus_string_free (&address);
1230 _dbus_close (fd, NULL);
1232 _dbus_string_free (&address);
1237 * Creates a new transport for the given hostname and port.
1239 * @param host the host to connect to
1240 * @param port the port to connect to
1241 * @param error location to store reason for failure.
1242 * @returns a new transport, or #NULL on failure.
1245 _dbus_transport_new_for_tcp_socket (const char *host,
1250 DBusTransport *transport;
1253 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1255 if (!_dbus_string_init (&address))
1257 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1261 if (!_dbus_string_append (&address, "tcp:host=") ||
1262 !_dbus_string_append (&address, host) ||
1263 !_dbus_string_append (&address, ",port=") ||
1264 !_dbus_string_append_int (&address, port))
1266 _dbus_string_free (&address);
1267 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1271 fd = _dbus_connect_tcp_socket (host, port, error);
1274 _DBUS_ASSERT_ERROR_IS_SET (error);
1275 _dbus_string_free (&address);
1279 _dbus_fd_set_close_on_exec (fd);
1281 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
1284 transport = _dbus_transport_new_for_fd (fd, FALSE, &address);
1285 if (transport == NULL)
1287 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1288 _dbus_close (fd, NULL);
1289 _dbus_string_free (&address);
1293 _dbus_string_free (&address);