1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-transport-unix.c UNIX socket subclasses of DBusTransport
4 * Copyright (C) 2002, 2003 Red Hat Inc.
6 * Licensed under the Academic Free License version 1.2
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"
29 #include <sys/types.h>
35 * @defgroup DBusTransportUnix DBusTransport implementations for UNIX
36 * @ingroup DBusInternals
37 * @brief Implementation details of DBusTransport on UNIX
43 * Opaque object representing a Unix file descriptor transport.
45 typedef struct DBusTransportUnix DBusTransportUnix;
48 * Implementation details of DBusTransportUnix. All members are private.
50 struct DBusTransportUnix
52 DBusTransport base; /**< Parent instance */
53 int fd; /**< File descriptor. */
54 DBusWatch *read_watch; /**< Watch for readability. */
55 DBusWatch *write_watch; /**< Watch for writability. */
57 int max_bytes_read_per_iteration; /**< To avoid blocking too long. */
58 int max_bytes_written_per_iteration; /**< To avoid blocking too long. */
60 int message_bytes_written; /**< Number of bytes of current
61 * outgoing message that have
64 DBusString encoded_message; /**< 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_message);
104 _dbus_transport_finalize_base (transport);
106 _dbus_assert (unix_transport->read_watch == NULL);
107 _dbus_assert (unix_transport->write_watch == NULL);
109 dbus_free (transport);
113 check_write_watch (DBusTransport *transport)
115 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
116 dbus_bool_t need_write_watch;
118 if (transport->connection == NULL)
121 _dbus_transport_ref (transport);
123 if (_dbus_transport_get_is_authenticated (transport))
124 need_write_watch = transport->messages_need_sending;
126 need_write_watch = transport->send_credentials_pending ||
127 _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
129 if (transport->disconnected)
130 need_write_watch = FALSE;
132 if (need_write_watch &&
133 unix_transport->write_watch == NULL)
135 unix_transport->write_watch =
136 _dbus_watch_new (unix_transport->fd,
137 DBUS_WATCH_WRITABLE);
139 /* FIXME this is total crack. The proper fix is probably to
140 * allocate the write watch on transport creation, keep it
141 * allocated. But that doesn't solve needing memory to add the
142 * watch. messages_pending is going to have to handle OOM
143 * somehow (probably being part of PreallocatedSend)
145 if (unix_transport->write_watch == NULL)
148 if (!_dbus_connection_add_watch (transport->connection,
149 unix_transport->write_watch))
151 _dbus_watch_invalidate (unix_transport->write_watch);
152 _dbus_watch_unref (unix_transport->write_watch);
153 unix_transport->write_watch = NULL;
156 else if (!need_write_watch &&
157 unix_transport->write_watch != NULL)
159 _dbus_connection_remove_watch (transport->connection,
160 unix_transport->write_watch);
161 _dbus_watch_invalidate (unix_transport->write_watch);
162 _dbus_watch_unref (unix_transport->write_watch);
163 unix_transport->write_watch = NULL;
167 _dbus_verbose ("Write watch is unchanged from %p on fd %d\n",
168 unix_transport->write_watch, unix_transport->fd);
172 _dbus_transport_unref (transport);
176 check_read_watch (DBusTransport *transport)
178 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
179 dbus_bool_t need_read_watch;
181 if (transport->connection == 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;
190 need_read_watch = transport->receive_credentials_pending ||
191 _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
193 _dbus_verbose ("need_read_watch = %d authenticated = %d\n",
194 need_read_watch, _dbus_transport_get_is_authenticated (transport));
196 if (transport->disconnected)
197 need_read_watch = FALSE;
199 if (need_read_watch &&
200 unix_transport->read_watch == NULL)
202 _dbus_verbose ("Adding read watch to unix fd %d\n",
205 unix_transport->read_watch =
206 _dbus_watch_new (unix_transport->fd,
207 DBUS_WATCH_READABLE);
209 /* we can maybe add it some other time, just silently bomb */
210 if (unix_transport->read_watch == NULL)
213 if (!_dbus_connection_add_watch (transport->connection,
214 unix_transport->read_watch))
216 _dbus_watch_invalidate (unix_transport->read_watch);
217 _dbus_watch_unref (unix_transport->read_watch);
218 unix_transport->read_watch = NULL;
221 else if (!need_read_watch &&
222 unix_transport->read_watch != NULL)
224 _dbus_verbose ("Removing read watch from unix fd %d\n",
227 _dbus_connection_remove_watch (transport->connection,
228 unix_transport->read_watch);
229 _dbus_watch_invalidate (unix_transport->read_watch);
230 _dbus_watch_unref (unix_transport->read_watch);
231 unix_transport->read_watch = NULL;
235 _dbus_verbose ("Read watch is unchanged from %p on fd %d\n",
236 unix_transport->read_watch, unix_transport->fd);
240 _dbus_transport_unref (transport);
244 do_io_error (DBusTransport *transport)
246 _dbus_transport_ref (transport);
247 _dbus_transport_disconnect (transport);
248 _dbus_transport_unref (transport);
252 queue_messages (DBusTransport *transport)
254 DBusMessage *message;
256 /* Queue any messages */
257 while ((message = _dbus_message_loader_pop_message (transport->loader)))
259 _dbus_verbose ("queueing received message %p\n", message);
261 _dbus_message_add_size_counter (message, transport->live_messages_size);
262 _dbus_connection_queue_received_message (transport->connection,
264 dbus_message_unref (message);
267 if (_dbus_message_loader_get_is_corrupted (transport->loader))
269 _dbus_verbose ("Corrupted message stream, disconnecting\n");
270 do_io_error (transport);
273 /* check read watch in case we've now exceeded max outstanding messages */
274 check_read_watch (transport);
277 /* return value is whether we successfully read any new data. */
279 read_data_into_auth (DBusTransport *transport)
281 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
285 if (!_dbus_string_init (&buffer, _DBUS_INT_MAX))
287 /* just disconnect if we don't have memory
288 * to do an authentication
290 _dbus_verbose ("No memory for authentication\n");
291 do_io_error (transport);
295 bytes_read = _dbus_read (unix_transport->fd,
296 &buffer, unix_transport->max_bytes_read_per_iteration);
300 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
302 if (_dbus_auth_bytes_received (transport->auth,
305 _dbus_string_free (&buffer);
306 return TRUE; /* We did read some data! woo! */
310 /* just disconnect if we don't have memory to do an
311 * authentication, don't fool with trying to save the buffer
312 * and who knows what.
314 _dbus_verbose ("No memory for authentication\n");
315 do_io_error (transport);
318 else if (bytes_read < 0)
320 /* EINTR already handled for us */
322 if (errno == EAGAIN ||
323 errno == EWOULDBLOCK)
324 ; /* do nothing, just return FALSE below */
327 _dbus_verbose ("Error reading from remote app: %s\n",
328 _dbus_strerror (errno));
329 do_io_error (transport);
332 else if (bytes_read == 0)
334 _dbus_verbose ("Disconnected from remote app\n");
335 do_io_error (transport);
338 _dbus_string_free (&buffer);
342 /* Return value is whether we successfully wrote any bytes */
344 write_data_from_auth (DBusTransport *transport)
346 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
348 const DBusString *buffer;
350 if (!_dbus_auth_get_bytes_to_send (transport->auth,
354 bytes_written = _dbus_write (unix_transport->fd,
356 0, _dbus_string_get_length (buffer));
358 if (bytes_written > 0)
360 _dbus_auth_bytes_sent (transport->auth, bytes_written);
363 else if (bytes_written < 0)
365 /* EINTR already handled for us */
367 if (errno == EAGAIN ||
368 errno == EWOULDBLOCK)
372 _dbus_verbose ("Error writing to remote app: %s\n",
373 _dbus_strerror (errno));
374 do_io_error (transport);
382 recover_unused_bytes (DBusTransport *transport)
385 if (_dbus_auth_needs_decoding (transport->auth))
387 DBusString plaintext;
392 if (!_dbus_string_init (&plaintext, _DBUS_INT_MAX))
395 if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
397 _dbus_string_free (&plaintext);
401 if (!_dbus_auth_get_unused_bytes (transport->auth,
404 _dbus_string_free (&plaintext);
405 _dbus_string_free (&encoded);
409 if (!_dbus_auth_decode_data (transport->auth,
410 &encoded, &plaintext))
412 _dbus_string_free (&plaintext);
413 _dbus_string_free (&encoded);
417 _dbus_message_loader_get_buffer (transport->loader,
420 orig_len = _dbus_string_get_length (buffer);
422 if (!_dbus_string_move (&plaintext, 0, buffer,
425 _dbus_string_free (&plaintext);
426 _dbus_string_free (&encoded);
430 _dbus_verbose (" %d unused bytes sent to message loader\n",
431 _dbus_string_get_length (buffer) -
434 _dbus_message_loader_return_buffer (transport->loader,
436 _dbus_string_get_length (buffer) -
439 _dbus_string_free (&plaintext);
440 _dbus_string_free (&encoded);
447 _dbus_message_loader_get_buffer (transport->loader,
450 orig_len = _dbus_string_get_length (buffer);
452 if (!_dbus_auth_get_unused_bytes (transport->auth,
456 _dbus_verbose (" %d unused bytes sent to message loader\n",
457 _dbus_string_get_length (buffer) -
460 _dbus_message_loader_return_buffer (transport->loader,
462 _dbus_string_get_length (buffer) -
466 queue_messages (transport);
471 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
472 do_io_error (transport);
476 exchange_credentials (DBusTransport *transport,
477 dbus_bool_t do_reading,
478 dbus_bool_t do_writing)
480 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
482 if (do_writing && transport->send_credentials_pending)
484 if (_dbus_send_credentials_unix_socket (unix_transport->fd,
487 transport->send_credentials_pending = FALSE;
491 _dbus_verbose ("Failed to write credentials\n");
492 do_io_error (transport);
496 if (do_reading && transport->receive_credentials_pending)
498 if (_dbus_read_credentials_unix_socket (unix_transport->fd,
499 &transport->credentials,
502 transport->receive_credentials_pending = FALSE;
506 _dbus_verbose ("Failed to read credentials\n");
507 do_io_error (transport);
511 if (!(transport->send_credentials_pending ||
512 transport->receive_credentials_pending))
514 _dbus_auth_set_credentials (transport->auth,
515 &transport->credentials);
520 do_authentication (DBusTransport *transport,
521 dbus_bool_t do_reading,
522 dbus_bool_t do_writing)
524 _dbus_transport_ref (transport);
526 while (!_dbus_transport_get_is_authenticated (transport) &&
527 _dbus_transport_get_is_connected (transport))
529 exchange_credentials (transport, do_reading, do_writing);
531 if (transport->send_credentials_pending ||
532 transport->receive_credentials_pending)
534 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
535 transport->send_credentials_pending,
536 transport->receive_credentials_pending);
540 switch (_dbus_auth_do_work (transport->auth))
542 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
543 _dbus_verbose (" auth state: waiting for input\n");
544 if (!do_reading || !read_data_into_auth (transport))
548 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
549 /* Screw it, just disconnect */
550 _dbus_verbose (" auth state: waiting for memory\n");
551 do_io_error (transport);
554 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
555 _dbus_verbose (" auth state: bytes to send\n");
556 if (!do_writing || !write_data_from_auth (transport))
560 case DBUS_AUTH_STATE_NEED_DISCONNECT:
561 _dbus_verbose (" auth state: need to disconnect\n");
562 do_io_error (transport);
565 case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
566 _dbus_verbose (" auth state: auth with unused bytes\n");
567 recover_unused_bytes (transport);
570 case DBUS_AUTH_STATE_AUTHENTICATED:
571 _dbus_verbose (" auth state: authenticated\n");
577 check_read_watch (transport);
578 check_write_watch (transport);
579 _dbus_transport_unref (transport);
583 do_writing (DBusTransport *transport)
586 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
588 /* No messages without authentication! */
589 if (!_dbus_transport_get_is_authenticated (transport))
592 if (transport->disconnected)
597 while (!transport->disconnected &&
598 _dbus_connection_have_messages_to_send (transport->connection))
601 DBusMessage *message;
602 const DBusString *header;
603 const DBusString *body;
604 int header_len, body_len;
605 int total_bytes_to_write;
607 if (total > unix_transport->max_bytes_written_per_iteration)
609 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
610 total, unix_transport->max_bytes_written_per_iteration);
614 if (unix_transport->write_watch == NULL)
616 _dbus_verbose ("write watch removed, not writing more stuff\n");
620 message = _dbus_connection_get_message_to_send (transport->connection);
621 _dbus_assert (message != NULL);
622 _dbus_message_lock (message);
624 _dbus_verbose ("writing message %p\n", message);
626 _dbus_message_get_network_data (message,
629 header_len = _dbus_string_get_length (header);
630 body_len = _dbus_string_get_length (body);
632 if (_dbus_auth_needs_encoding (transport->auth))
634 if (_dbus_string_get_length (&unix_transport->encoded_message) == 0)
636 if (!_dbus_auth_encode_data (transport->auth,
637 header, &unix_transport->encoded_message))
640 if (!_dbus_auth_encode_data (transport->auth,
641 body, &unix_transport->encoded_message))
643 _dbus_string_set_length (&unix_transport->encoded_message, 0);
648 total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_message);
650 _dbus_verbose ("encoded message is %d bytes\n",
651 total_bytes_to_write);
654 _dbus_write (unix_transport->fd,
655 &unix_transport->encoded_message,
656 unix_transport->message_bytes_written,
657 total_bytes_to_write - unix_transport->message_bytes_written);
661 total_bytes_to_write = header_len + body_len;
663 _dbus_verbose ("message is %d bytes\n",
664 total_bytes_to_write);
666 if (unix_transport->message_bytes_written < header_len)
669 _dbus_write_two (unix_transport->fd,
671 unix_transport->message_bytes_written,
672 header_len - unix_transport->message_bytes_written,
679 _dbus_write (unix_transport->fd,
681 (unix_transport->message_bytes_written - header_len),
683 (unix_transport->message_bytes_written - header_len));
687 if (bytes_written < 0)
689 /* EINTR already handled for us */
691 if (errno == EAGAIN ||
692 errno == EWOULDBLOCK)
696 _dbus_verbose ("Error writing to remote app: %s\n",
697 _dbus_strerror (errno));
698 do_io_error (transport);
704 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
705 total_bytes_to_write);
707 total += bytes_written;
708 unix_transport->message_bytes_written += bytes_written;
710 _dbus_assert (unix_transport->message_bytes_written <=
711 total_bytes_to_write);
713 if (unix_transport->message_bytes_written == total_bytes_to_write)
715 unix_transport->message_bytes_written = 0;
716 _dbus_string_set_length (&unix_transport->encoded_message, 0);
718 _dbus_connection_message_sent (transport->connection,
725 return; /* I think some C compilers require a statement after a label */
729 do_reading (DBusTransport *transport)
731 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
736 /* No messages without authentication! */
737 if (!_dbus_transport_get_is_authenticated (transport))
744 /* See if we've exceeded max messages and need to disable reading */
745 check_read_watch (transport);
746 if (unix_transport->read_watch == NULL)
749 if (total > unix_transport->max_bytes_read_per_iteration)
751 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
752 total, unix_transport->max_bytes_read_per_iteration);
756 if (transport->disconnected)
759 if (_dbus_auth_needs_decoding (transport->auth))
763 if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
764 goto out; /* not enough memory for the moment */
766 bytes_read = _dbus_read (unix_transport->fd,
768 unix_transport->max_bytes_read_per_iteration);
774 _dbus_message_loader_get_buffer (transport->loader,
777 orig_len = _dbus_string_get_length (buffer);
779 if (!_dbus_auth_decode_data (transport->auth,
782 /* FIXME argh, we are really fucked here - nowhere to
783 * put "encoded" while we wait for more memory. Just
784 * screw it for now and disconnect. The failure may be
785 * due to badly-encoded data instead of lack of memory
788 _dbus_verbose ("Disconnected from remote app due to failure decoding data\n");
789 do_io_error (transport);
792 _dbus_message_loader_return_buffer (transport->loader,
794 _dbus_string_get_length (buffer) - orig_len);
797 _dbus_string_free (&encoded);
801 _dbus_message_loader_get_buffer (transport->loader,
804 bytes_read = _dbus_read (unix_transport->fd,
805 buffer, unix_transport->max_bytes_read_per_iteration);
807 _dbus_message_loader_return_buffer (transport->loader,
809 bytes_read < 0 ? 0 : bytes_read);
814 /* EINTR already handled for us */
816 if (errno == EAGAIN ||
817 errno == EWOULDBLOCK)
821 _dbus_verbose ("Error reading from remote app: %s\n",
822 _dbus_strerror (errno));
823 do_io_error (transport);
827 else if (bytes_read == 0)
829 _dbus_verbose ("Disconnected from remote app\n");
830 do_io_error (transport);
835 _dbus_verbose (" read %d bytes\n", bytes_read);
839 queue_messages (transport);
841 /* Try reading more data until we get EAGAIN and return, or
842 * exceed max bytes per iteration. If in blocking mode of
843 * course we'll block instead of returning.
849 return; /* I think some C compilers require a statement after a label */
853 unix_handle_watch (DBusTransport *transport,
857 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
859 _dbus_assert (watch == unix_transport->read_watch ||
860 watch == unix_transport->write_watch);
862 if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
864 _dbus_transport_disconnect (transport);
868 if (watch == unix_transport->read_watch &&
869 (flags & DBUS_WATCH_READABLE))
871 _dbus_verbose ("handling read watch\n");
872 do_authentication (transport, TRUE, FALSE);
873 do_reading (transport);
875 else if (watch == unix_transport->write_watch &&
876 (flags & DBUS_WATCH_WRITABLE))
878 _dbus_verbose ("handling write watch\n");
879 do_authentication (transport, FALSE, TRUE);
880 do_writing (transport);
885 unix_disconnect (DBusTransport *transport)
887 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
889 free_watches (transport);
891 close (unix_transport->fd);
892 unix_transport->fd = -1;
896 unix_connection_set (DBusTransport *transport)
898 check_read_watch (transport);
899 check_write_watch (transport);
903 unix_messages_pending (DBusTransport *transport,
904 int messages_pending)
906 check_write_watch (transport);
909 /* FIXME use _dbus_poll(), not select() */
911 * @todo We need to have a way to wake up the select sleep if
912 * a new iteration request comes in with a flag (read/write) that
913 * we're not currently serving. Otherwise a call that just reads
914 * could block a write call forever (if there are no incoming
918 unix_do_iteration (DBusTransport *transport,
920 int timeout_milliseconds)
922 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
925 dbus_bool_t do_select;
928 _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n",
929 flags & DBUS_ITERATION_DO_READING ? "read" : "",
930 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
931 timeout_milliseconds,
932 unix_transport->read_watch,
933 unix_transport->write_watch);
935 /* "again" has to be up here because on EINTR the fd sets become
942 /* the passed in DO_READING/DO_WRITING flags indicate whether to
943 * read/write messages, but regardless of those we may need to block
944 * for reading/writing to do auth. But if we do reading for auth,
945 * we don't want to read any messages yet if not given DO_READING.
947 * Also, if read_watch == NULL or write_watch == NULL, we don't
948 * want to read/write so don't.
952 FD_ZERO (&write_set);
954 if (_dbus_transport_get_is_authenticated (transport))
956 if (unix_transport->read_watch &&
957 (flags & DBUS_ITERATION_DO_READING))
959 FD_SET (unix_transport->fd, &read_set);
963 if (unix_transport->write_watch &&
964 (flags & DBUS_ITERATION_DO_WRITING))
966 FD_SET (unix_transport->fd, &write_set);
972 DBusAuthState auth_state;
974 auth_state = _dbus_auth_do_work (transport->auth);
976 if (transport->receive_credentials_pending ||
977 auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
979 FD_SET (unix_transport->fd, &read_set);
983 if (transport->send_credentials_pending ||
984 auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
986 FD_SET (unix_transport->fd, &write_set);
994 struct timeval timeout;
995 dbus_bool_t use_timeout;
998 FD_SET (unix_transport->fd, &err_set);
1000 if (flags & DBUS_ITERATION_BLOCK)
1002 if (timeout_milliseconds >= 0)
1004 timeout.tv_sec = timeout_milliseconds / 1000;
1005 timeout.tv_usec = (timeout_milliseconds % 1000) * 1000;
1007 /* Always use timeout if one is passed in. */
1012 use_timeout = FALSE; /* NULL timeout to block forever */
1017 /* 0 timeout to not block */
1019 timeout.tv_usec = 0;
1023 /* For blocking selects we drop the connection lock here
1024 * to avoid blocking out connection access during a potentially
1025 * indefinite blocking call. The io path is still protected
1026 * by the io_path_cond condvar, so we won't reenter this.
1028 if (flags & DBUS_ITERATION_BLOCK)
1029 _dbus_connection_unlock (transport->connection);
1031 select_res = select (unix_transport->fd + 1,
1032 &read_set, &write_set, &err_set,
1033 use_timeout ? &timeout : NULL);
1035 if (flags & DBUS_ITERATION_BLOCK)
1036 _dbus_connection_lock (transport->connection);
1039 if (select_res >= 0)
1041 if (FD_ISSET (unix_transport->fd, &err_set))
1042 do_io_error (transport);
1045 dbus_bool_t need_read = FD_ISSET (unix_transport->fd, &read_set);
1046 dbus_bool_t need_write = FD_ISSET (unix_transport->fd, &write_set);
1048 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
1049 need_read, need_write);
1050 do_authentication (transport, need_read, need_write);
1052 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1053 do_reading (transport);
1054 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1055 do_writing (transport);
1058 else if (errno == EINTR)
1062 _dbus_verbose ("Error from select(): %s\n",
1063 _dbus_strerror (errno));
1069 unix_live_messages_changed (DBusTransport *transport)
1071 /* See if we should look for incoming messages again */
1072 check_read_watch (transport);
1075 static DBusTransportVTable unix_vtable = {
1079 unix_connection_set,
1080 unix_messages_pending,
1082 unix_live_messages_changed
1086 * Creates a new transport for the given file descriptor. The file
1087 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1088 * make it so). This function is shared by various transports that
1089 * boil down to a full duplex file descriptor.
1091 * @param fd the file descriptor.
1092 * @param server #TRUE if this transport is on the server side of a connection
1093 * @returns the new transport, or #NULL if no memory.
1096 _dbus_transport_new_for_fd (int fd,
1099 DBusTransportUnix *unix_transport;
1101 unix_transport = dbus_new0 (DBusTransportUnix, 1);
1102 if (unix_transport == NULL)
1105 if (!_dbus_string_init (&unix_transport->encoded_message,
1108 dbus_free (unix_transport);
1112 if (!_dbus_transport_init_base (&unix_transport->base,
1116 _dbus_string_free (&unix_transport->encoded_message);
1117 dbus_free (unix_transport);
1121 unix_transport->fd = fd;
1122 unix_transport->message_bytes_written = 0;
1124 /* These values should probably be tunable or something. */
1125 unix_transport->max_bytes_read_per_iteration = 2048;
1126 unix_transport->max_bytes_written_per_iteration = 2048;
1128 check_read_watch ((DBusTransport*) unix_transport);
1129 check_write_watch ((DBusTransport*) unix_transport);
1131 return (DBusTransport*) unix_transport;
1135 * Creates a new transport for the given Unix domain socket
1138 * @param path the path to the domain socket.
1139 * @param server #TRUE if this transport is on the server side of a connection
1140 * @param result location to store reason for failure.
1141 * @returns a new transport, or #NULL on failure.
1144 _dbus_transport_new_for_domain_socket (const char *path,
1146 DBusResultCode *result)
1149 DBusTransport *transport;
1151 fd = _dbus_connect_unix_socket (path, result);
1155 _dbus_fd_set_close_on_exec (fd);
1157 _dbus_verbose ("Successfully connected to unix socket %s\n",
1160 transport = _dbus_transport_new_for_fd (fd, server);
1161 if (transport == NULL)
1163 dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1172 * Creates a new transport for the given hostname and port.
1174 * @param host the host to connect to
1175 * @param port the port to connect to
1176 * @param server #TRUE if this transport is on the server side of a connection
1177 * @param result location to store reason for failure.
1178 * @returns a new transport, or #NULL on failure.
1181 _dbus_transport_new_for_tcp_socket (const char *host,
1184 DBusResultCode *result)
1187 DBusTransport *transport;
1189 fd = _dbus_connect_tcp_socket (host, port, result);
1193 _dbus_fd_set_close_on_exec (fd);
1195 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
1198 transport = _dbus_transport_new_for_fd (fd, server);
1199 if (transport == NULL)
1201 dbus_set_result (result, DBUS_RESULT_NO_MEMORY);