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 /* we can maybe add it some other time, just silently bomb */
140 if (unix_transport->write_watch == NULL)
143 if (!_dbus_connection_add_watch (transport->connection,
144 unix_transport->write_watch))
146 _dbus_watch_invalidate (unix_transport->write_watch);
147 _dbus_watch_unref (unix_transport->write_watch);
148 unix_transport->write_watch = NULL;
151 else if (!need_write_watch &&
152 unix_transport->write_watch != NULL)
154 _dbus_connection_remove_watch (transport->connection,
155 unix_transport->write_watch);
156 _dbus_watch_invalidate (unix_transport->write_watch);
157 _dbus_watch_unref (unix_transport->write_watch);
158 unix_transport->write_watch = NULL;
162 _dbus_transport_unref (transport);
166 check_read_watch (DBusTransport *transport)
168 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
169 dbus_bool_t need_read_watch;
171 if (transport->connection == NULL)
174 _dbus_transport_ref (transport);
177 _dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
179 if (transport->disconnected)
180 need_read_watch = FALSE;
182 if (need_read_watch &&
183 unix_transport->read_watch == NULL)
185 _dbus_verbose ("Adding read watch to unix fd %d\n",
188 unix_transport->read_watch =
189 _dbus_watch_new (unix_transport->fd,
190 DBUS_WATCH_READABLE);
192 /* we can maybe add it some other time, just silently bomb */
193 if (unix_transport->read_watch == NULL)
196 if (!_dbus_connection_add_watch (transport->connection,
197 unix_transport->read_watch))
199 _dbus_watch_invalidate (unix_transport->read_watch);
200 _dbus_watch_unref (unix_transport->read_watch);
201 unix_transport->read_watch = NULL;
204 else if (!need_read_watch &&
205 unix_transport->read_watch != NULL)
207 _dbus_verbose ("Removing read watch from unix fd %d\n",
210 _dbus_connection_remove_watch (transport->connection,
211 unix_transport->read_watch);
212 _dbus_watch_invalidate (unix_transport->read_watch);
213 _dbus_watch_unref (unix_transport->read_watch);
214 unix_transport->read_watch = NULL;
218 _dbus_transport_unref (transport);
222 do_io_error (DBusTransport *transport)
224 _dbus_transport_ref (transport);
225 _dbus_transport_disconnect (transport);
226 _dbus_transport_unref (transport);
230 queue_messages (DBusTransport *transport)
232 DBusMessage *message;
234 /* Queue any messages */
235 while ((message = _dbus_message_loader_pop_message (transport->loader)))
237 _dbus_verbose ("queueing received message %p\n", message);
239 _dbus_message_add_size_counter (message, transport->live_messages_size);
240 _dbus_connection_queue_received_message (transport->connection,
242 dbus_message_unref (message);
245 if (_dbus_message_loader_get_is_corrupted (transport->loader))
247 _dbus_verbose ("Corrupted message stream, disconnecting\n");
248 do_io_error (transport);
251 /* check read watch in case we've now exceeded max outstanding messages */
252 check_read_watch (transport);
255 /* return value is whether we successfully read any new data. */
257 read_data_into_auth (DBusTransport *transport)
259 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
263 if (!_dbus_string_init (&buffer, _DBUS_INT_MAX))
265 /* just disconnect if we don't have memory
266 * to do an authentication
268 _dbus_verbose ("No memory for authentication\n");
269 do_io_error (transport);
273 bytes_read = _dbus_read (unix_transport->fd,
274 &buffer, unix_transport->max_bytes_read_per_iteration);
278 _dbus_verbose (" read %d bytes in auth phase\n", bytes_read);
280 if (_dbus_auth_bytes_received (transport->auth,
283 _dbus_string_free (&buffer);
284 return TRUE; /* We did read some data! woo! */
288 /* just disconnect if we don't have memory to do an
289 * authentication, don't fool with trying to save the buffer
290 * and who knows what.
292 _dbus_verbose ("No memory for authentication\n");
293 do_io_error (transport);
296 else if (bytes_read < 0)
298 /* EINTR already handled for us */
300 if (errno == EAGAIN ||
301 errno == EWOULDBLOCK)
302 ; /* do nothing, just return FALSE below */
305 _dbus_verbose ("Error reading from remote app: %s\n",
306 _dbus_strerror (errno));
307 do_io_error (transport);
310 else if (bytes_read == 0)
312 _dbus_verbose ("Disconnected from remote app\n");
313 do_io_error (transport);
316 _dbus_string_free (&buffer);
320 /* Return value is whether we successfully wrote any bytes */
322 write_data_from_auth (DBusTransport *transport)
324 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
326 const DBusString *buffer;
328 if (!_dbus_auth_get_bytes_to_send (transport->auth,
332 bytes_written = _dbus_write (unix_transport->fd,
334 0, _dbus_string_get_length (buffer));
336 if (bytes_written > 0)
338 _dbus_auth_bytes_sent (transport->auth, bytes_written);
341 else if (bytes_written < 0)
343 /* EINTR already handled for us */
345 if (errno == EAGAIN ||
346 errno == EWOULDBLOCK)
350 _dbus_verbose ("Error writing to remote app: %s\n",
351 _dbus_strerror (errno));
352 do_io_error (transport);
360 recover_unused_bytes (DBusTransport *transport)
363 if (_dbus_auth_needs_decoding (transport->auth))
365 DBusString plaintext;
370 if (!_dbus_string_init (&plaintext, _DBUS_INT_MAX))
373 if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
375 _dbus_string_free (&plaintext);
379 if (!_dbus_auth_get_unused_bytes (transport->auth,
382 _dbus_string_free (&plaintext);
383 _dbus_string_free (&encoded);
387 if (!_dbus_auth_decode_data (transport->auth,
388 &encoded, &plaintext))
390 _dbus_string_free (&plaintext);
391 _dbus_string_free (&encoded);
395 _dbus_message_loader_get_buffer (transport->loader,
398 orig_len = _dbus_string_get_length (buffer);
400 if (!_dbus_string_move (&plaintext, 0, buffer,
403 _dbus_string_free (&plaintext);
404 _dbus_string_free (&encoded);
408 _dbus_verbose (" %d unused bytes sent to message loader\n",
409 _dbus_string_get_length (buffer) -
412 _dbus_message_loader_return_buffer (transport->loader,
414 _dbus_string_get_length (buffer) -
417 _dbus_string_free (&plaintext);
418 _dbus_string_free (&encoded);
425 _dbus_message_loader_get_buffer (transport->loader,
428 orig_len = _dbus_string_get_length (buffer);
430 if (!_dbus_auth_get_unused_bytes (transport->auth,
434 _dbus_verbose (" %d unused bytes sent to message loader\n",
435 _dbus_string_get_length (buffer) -
438 _dbus_message_loader_return_buffer (transport->loader,
440 _dbus_string_get_length (buffer) -
444 queue_messages (transport);
449 _dbus_verbose ("Not enough memory to transfer unused bytes from auth conversation\n");
450 do_io_error (transport);
454 exchange_credentials (DBusTransport *transport,
455 dbus_bool_t do_reading,
456 dbus_bool_t do_writing)
458 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
460 if (do_writing && transport->send_credentials_pending)
462 if (_dbus_send_credentials_unix_socket (unix_transport->fd,
465 transport->send_credentials_pending = FALSE;
469 _dbus_verbose ("Failed to write credentials\n");
470 do_io_error (transport);
474 if (do_reading && transport->receive_credentials_pending)
476 if (_dbus_read_credentials_unix_socket (unix_transport->fd,
477 &transport->credentials,
480 transport->receive_credentials_pending = FALSE;
484 _dbus_verbose ("Failed to read credentials\n");
485 do_io_error (transport);
489 if (!(transport->send_credentials_pending ||
490 transport->receive_credentials_pending))
492 _dbus_auth_set_credentials (transport->auth,
493 &transport->credentials);
498 do_authentication (DBusTransport *transport,
499 dbus_bool_t do_reading,
500 dbus_bool_t do_writing)
502 _dbus_transport_ref (transport);
504 while (!_dbus_transport_get_is_authenticated (transport) &&
505 _dbus_transport_get_is_connected (transport))
507 exchange_credentials (transport, do_reading, do_writing);
509 if (transport->send_credentials_pending ||
510 transport->receive_credentials_pending)
512 _dbus_verbose ("send_credentials_pending = %d receive_credentials_pending = %d\n",
513 transport->send_credentials_pending,
514 transport->receive_credentials_pending);
518 switch (_dbus_auth_do_work (transport->auth))
520 case DBUS_AUTH_STATE_WAITING_FOR_INPUT:
521 _dbus_verbose (" auth state: waiting for input\n");
522 if (!do_reading || !read_data_into_auth (transport))
526 case DBUS_AUTH_STATE_WAITING_FOR_MEMORY:
527 /* Screw it, just disconnect */
528 _dbus_verbose (" auth state: waiting for memory\n");
529 do_io_error (transport);
532 case DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND:
533 _dbus_verbose (" auth state: bytes to send\n");
534 if (!do_writing || !write_data_from_auth (transport))
538 case DBUS_AUTH_STATE_NEED_DISCONNECT:
539 _dbus_verbose (" auth state: need to disconnect\n");
540 do_io_error (transport);
543 case DBUS_AUTH_STATE_AUTHENTICATED_WITH_UNUSED_BYTES:
544 _dbus_verbose (" auth state: auth with unused bytes\n");
545 recover_unused_bytes (transport);
548 case DBUS_AUTH_STATE_AUTHENTICATED:
549 _dbus_verbose (" auth state: authenticated\n");
555 check_write_watch (transport);
556 _dbus_transport_unref (transport);
560 do_writing (DBusTransport *transport)
563 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
565 /* No messages without authentication! */
566 if (!_dbus_transport_get_is_authenticated (transport))
569 if (transport->disconnected)
574 while (!transport->disconnected &&
575 _dbus_connection_have_messages_to_send (transport->connection))
578 DBusMessage *message;
579 const DBusString *header;
580 const DBusString *body;
581 int header_len, body_len;
582 int total_bytes_to_write;
584 if (total > unix_transport->max_bytes_written_per_iteration)
586 _dbus_verbose ("%d bytes exceeds %d bytes written per iteration, returning\n",
587 total, unix_transport->max_bytes_written_per_iteration);
591 if (unix_transport->write_watch == NULL)
593 _dbus_verbose ("write watch removed, not writing more stuff\n");
597 message = _dbus_connection_get_message_to_send (transport->connection);
598 _dbus_assert (message != NULL);
599 _dbus_message_lock (message);
601 _dbus_verbose ("writing message %p\n", message);
603 _dbus_message_get_network_data (message,
606 header_len = _dbus_string_get_length (header);
607 body_len = _dbus_string_get_length (body);
609 if (_dbus_auth_needs_encoding (transport->auth))
611 if (_dbus_string_get_length (&unix_transport->encoded_message) == 0)
613 if (!_dbus_auth_encode_data (transport->auth,
614 header, &unix_transport->encoded_message))
617 if (!_dbus_auth_encode_data (transport->auth,
618 body, &unix_transport->encoded_message))
620 _dbus_string_set_length (&unix_transport->encoded_message, 0);
625 total_bytes_to_write = _dbus_string_get_length (&unix_transport->encoded_message);
627 _dbus_verbose ("encoded message is %d bytes\n",
628 total_bytes_to_write);
631 _dbus_write (unix_transport->fd,
632 &unix_transport->encoded_message,
633 unix_transport->message_bytes_written,
634 total_bytes_to_write - unix_transport->message_bytes_written);
638 total_bytes_to_write = header_len + body_len;
640 _dbus_verbose ("message is %d bytes\n",
641 total_bytes_to_write);
643 if (unix_transport->message_bytes_written < header_len)
646 _dbus_write_two (unix_transport->fd,
648 unix_transport->message_bytes_written,
649 header_len - unix_transport->message_bytes_written,
656 _dbus_write (unix_transport->fd,
658 (unix_transport->message_bytes_written - header_len),
660 (unix_transport->message_bytes_written - header_len));
664 if (bytes_written < 0)
666 /* EINTR already handled for us */
668 if (errno == EAGAIN ||
669 errno == EWOULDBLOCK)
673 _dbus_verbose ("Error writing to remote app: %s\n",
674 _dbus_strerror (errno));
675 do_io_error (transport);
681 _dbus_verbose (" wrote %d bytes of %d\n", bytes_written,
682 total_bytes_to_write);
684 total += bytes_written;
685 unix_transport->message_bytes_written += bytes_written;
687 _dbus_assert (unix_transport->message_bytes_written <=
688 total_bytes_to_write);
690 if (unix_transport->message_bytes_written == total_bytes_to_write)
692 unix_transport->message_bytes_written = 0;
693 _dbus_string_set_length (&unix_transport->encoded_message, 0);
695 _dbus_connection_message_sent (transport->connection,
702 return; /* I think some C compilers require a statement after a label */
706 do_reading (DBusTransport *transport)
708 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
713 /* No messages without authentication! */
714 if (!_dbus_transport_get_is_authenticated (transport))
721 /* See if we've exceeded max messages and need to disable reading */
722 check_read_watch (transport);
723 if (unix_transport->read_watch == NULL)
726 if (total > unix_transport->max_bytes_read_per_iteration)
728 _dbus_verbose ("%d bytes exceeds %d bytes read per iteration, returning\n",
729 total, unix_transport->max_bytes_read_per_iteration);
733 if (transport->disconnected)
736 if (_dbus_auth_needs_decoding (transport->auth))
740 if (!_dbus_string_init (&encoded, _DBUS_INT_MAX))
741 goto out; /* not enough memory for the moment */
743 bytes_read = _dbus_read (unix_transport->fd,
745 unix_transport->max_bytes_read_per_iteration);
751 _dbus_message_loader_get_buffer (transport->loader,
754 orig_len = _dbus_string_get_length (buffer);
756 if (!_dbus_auth_decode_data (transport->auth,
759 /* FIXME argh, we are really fucked here - nowhere to
760 * put "encoded" while we wait for more memory. Just
761 * screw it for now and disconnect. The failure may be
762 * due to badly-encoded data instead of lack of memory
765 _dbus_verbose ("Disconnected from remote app due to failure decoding data\n");
766 do_io_error (transport);
769 _dbus_message_loader_return_buffer (transport->loader,
771 _dbus_string_get_length (buffer) - orig_len);
774 _dbus_string_free (&encoded);
778 _dbus_message_loader_get_buffer (transport->loader,
781 bytes_read = _dbus_read (unix_transport->fd,
782 buffer, unix_transport->max_bytes_read_per_iteration);
784 _dbus_message_loader_return_buffer (transport->loader,
786 bytes_read < 0 ? 0 : bytes_read);
791 /* EINTR already handled for us */
793 if (errno == EAGAIN ||
794 errno == EWOULDBLOCK)
798 _dbus_verbose ("Error reading from remote app: %s\n",
799 _dbus_strerror (errno));
800 do_io_error (transport);
804 else if (bytes_read == 0)
806 _dbus_verbose ("Disconnected from remote app\n");
807 do_io_error (transport);
812 _dbus_verbose (" read %d bytes\n", bytes_read);
816 queue_messages (transport);
818 /* Try reading more data until we get EAGAIN and return, or
819 * exceed max bytes per iteration. If in blocking mode of
820 * course we'll block instead of returning.
826 return; /* I think some C compilers require a statement after a label */
830 unix_handle_watch (DBusTransport *transport,
834 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
836 _dbus_assert (watch == unix_transport->read_watch ||
837 watch == unix_transport->write_watch);
839 if (flags & (DBUS_WATCH_HANGUP | DBUS_WATCH_ERROR))
841 _dbus_transport_disconnect (transport);
845 if (watch == unix_transport->read_watch &&
846 (flags & DBUS_WATCH_READABLE))
848 _dbus_verbose ("handling read watch\n");
849 do_authentication (transport, TRUE, FALSE);
850 do_reading (transport);
852 else if (watch == unix_transport->write_watch &&
853 (flags & DBUS_WATCH_WRITABLE))
855 _dbus_verbose ("handling write watch\n");
856 do_authentication (transport, FALSE, TRUE);
857 do_writing (transport);
862 unix_disconnect (DBusTransport *transport)
864 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
866 free_watches (transport);
868 close (unix_transport->fd);
869 unix_transport->fd = -1;
873 unix_connection_set (DBusTransport *transport)
875 check_read_watch (transport);
876 check_write_watch (transport);
880 unix_messages_pending (DBusTransport *transport,
881 int messages_pending)
883 check_write_watch (transport);
886 /* FIXME use _dbus_poll(), not select() */
888 unix_do_iteration (DBusTransport *transport,
890 int timeout_milliseconds)
892 DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
895 dbus_bool_t do_select;
897 _dbus_verbose (" iteration flags = %s%s timeout = %d\n",
898 flags & DBUS_ITERATION_DO_READING ? "read" : "",
899 flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
900 timeout_milliseconds);
902 /* "again" has to be up here because on EINTR the fd sets become
909 /* the passed in DO_READING/DO_WRITING flags indicate whether to
910 * read/write messages, but regardless of those we may need to block
911 * for reading/writing to do auth. But if we do reading for auth,
912 * we don't want to read any messages yet if not given DO_READING.
914 * Also, if read_watch == NULL or write_watch == NULL, we don't
915 * want to read/write so don't.
919 FD_ZERO (&write_set);
921 if (_dbus_transport_get_is_authenticated (transport))
923 if (unix_transport->read_watch &&
924 (flags & DBUS_ITERATION_DO_READING))
926 FD_SET (unix_transport->fd, &read_set);
930 if (unix_transport->write_watch &&
931 (flags & DBUS_ITERATION_DO_WRITING))
933 FD_SET (unix_transport->fd, &write_set);
939 DBusAuthState auth_state;
941 auth_state = _dbus_auth_do_work (transport->auth);
943 if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT)
945 FD_SET (unix_transport->fd, &read_set);
949 if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
951 FD_SET (unix_transport->fd, &write_set);
959 struct timeval timeout;
960 dbus_bool_t use_timeout;
963 FD_SET (unix_transport->fd, &err_set);
965 if (flags & DBUS_ITERATION_BLOCK)
967 if (timeout_milliseconds >= 0)
969 timeout.tv_sec = timeout_milliseconds / 1000;
970 timeout.tv_usec = (timeout_milliseconds % 1000) * 1000;
972 /* Always use timeout if one is passed in. */
977 use_timeout = FALSE; /* NULL timeout to block forever */
982 /* 0 timeout to not block */
988 if (select (unix_transport->fd + 1, &read_set, &write_set, &err_set,
989 use_timeout ? &timeout : NULL) >= 0)
991 if (FD_ISSET (unix_transport->fd, &err_set))
992 do_io_error (transport);
995 dbus_bool_t need_read = FD_ISSET (unix_transport->fd, &read_set);
996 dbus_bool_t need_write = FD_ISSET (unix_transport->fd, &write_set);
998 _dbus_verbose ("in iteration, need_read=%d need_write=%d\n",
999 need_read, need_write);
1000 do_authentication (transport, need_read, need_write);
1002 if (need_read && (flags & DBUS_ITERATION_DO_READING))
1003 do_reading (transport);
1004 if (need_write && (flags & DBUS_ITERATION_DO_WRITING))
1005 do_writing (transport);
1008 else if (errno == EINTR)
1012 _dbus_verbose ("Error from select(): %s\n",
1013 _dbus_strerror (errno));
1019 unix_live_messages_changed (DBusTransport *transport)
1021 /* See if we should look for incoming messages again */
1022 check_read_watch (transport);
1025 static DBusTransportVTable unix_vtable = {
1029 unix_connection_set,
1030 unix_messages_pending,
1032 unix_live_messages_changed
1036 * Creates a new transport for the given file descriptor. The file
1037 * descriptor must be nonblocking (use _dbus_set_fd_nonblocking() to
1038 * make it so). This function is shared by various transports that
1039 * boil down to a full duplex file descriptor.
1041 * @param fd the file descriptor.
1042 * @param server #TRUE if this transport is on the server side of a connection
1043 * @returns the new transport, or #NULL if no memory.
1046 _dbus_transport_new_for_fd (int fd,
1049 DBusTransportUnix *unix_transport;
1051 unix_transport = dbus_new0 (DBusTransportUnix, 1);
1052 if (unix_transport == NULL)
1055 if (!_dbus_string_init (&unix_transport->encoded_message,
1058 dbus_free (unix_transport);
1062 if (!_dbus_transport_init_base (&unix_transport->base,
1066 _dbus_string_free (&unix_transport->encoded_message);
1067 dbus_free (unix_transport);
1071 unix_transport->fd = fd;
1072 unix_transport->message_bytes_written = 0;
1074 /* These values should probably be tunable or something. */
1075 unix_transport->max_bytes_read_per_iteration = 2048;
1076 unix_transport->max_bytes_written_per_iteration = 2048;
1078 check_read_watch ((DBusTransport*) unix_transport);
1079 check_write_watch ((DBusTransport*) unix_transport);
1081 return (DBusTransport*) unix_transport;
1085 * Creates a new transport for the given Unix domain socket
1088 * @param path the path to the domain socket.
1089 * @param server #TRUE if this transport is on the server side of a connection
1090 * @param result location to store reason for failure.
1091 * @returns a new transport, or #NULL on failure.
1094 _dbus_transport_new_for_domain_socket (const char *path,
1096 DBusResultCode *result)
1099 DBusTransport *transport;
1101 fd = _dbus_connect_unix_socket (path, result);
1105 _dbus_fd_set_close_on_exec (fd);
1107 _dbus_verbose ("Successfully connected to unix socket %s\n",
1110 transport = _dbus_transport_new_for_fd (fd, server);
1111 if (transport == NULL)
1113 dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1122 * Creates a new transport for the given hostname and port.
1124 * @param host the host to connect to
1125 * @param port the port to connect to
1126 * @param server #TRUE if this transport is on the server side of a connection
1127 * @param result location to store reason for failure.
1128 * @returns a new transport, or #NULL on failure.
1131 _dbus_transport_new_for_tcp_socket (const char *host,
1134 DBusResultCode *result)
1137 DBusTransport *transport;
1139 fd = _dbus_connect_tcp_socket (host, port, result);
1143 _dbus_fd_set_close_on_exec (fd);
1145 _dbus_verbose ("Successfully connected to tcp socket %s:%d\n",
1148 transport = _dbus_transport_new_for_fd (fd, server);
1149 if (transport == NULL)
1151 dbus_set_result (result, DBUS_RESULT_NO_MEMORY);