2 * Copyright © 2010-2012 Nokia Corporation
3 * Copyright © 2014 Collabora Ltd.
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation files
7 * (the "Software"), to deal in the Software without restriction,
8 * including without limitation the rights to use, copy, modify, merge,
9 * publish, distribute, sublicense, and/or sell copies of the Software,
10 * and to permit persons to whom the Software is furnished to do so,
11 * subject to the following conditions:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 #include <dbus/dbus.h>
29 #include <dbus/dbus-internals.h>
30 #include <dbus/dbus-sysdeps.h>
38 # include <dbus/dbus-sysdeps-unix.h>
42 # ifdef HAVE_SYS_RESOURCE_H
43 # include <sys/resource.h>
45 # include <sys/stat.h>
46 # include <sys/time.h>
47 # include <sys/types.h>
51 #include "test-utils-glib.h"
53 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
54 #include <dbus/dbus-message-internal.h>
56 typedef struct _DBusInitialFDs DBusInitialFDs;
57 #define _dbus_check_fdleaks_enter() NULL
58 #define _dbus_check_fdleaks_leave(fds) do {} while (0)
61 /* Arbitrary; included here to avoid relying on the default */
62 #define MAX_MESSAGE_UNIX_FDS 20
63 /* This test won't work on Linux unless this is true. */
64 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS <= 253);
66 /* Arbitrary; included here to avoid relying on the default. */
67 #define MAX_INCOMING_UNIX_FDS (MAX_MESSAGE_UNIX_FDS * 4)
69 /* Arbitrary, except that MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES should be
70 * less than the process's file descriptor limit. */
71 #define SOME_MESSAGES 20
72 /* To cover some situations on Linux we want this to be true. */
73 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES > 256);
75 /* Linux won't allow more than 253 fds per sendmsg(). */
76 #define TOO_MANY_FDS 255
77 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS < TOO_MANY_FDS);
79 /* As in test/relay.c, this is a miniature dbus-daemon: we relay messages
80 * from the client on the left to the client on the right.
82 * left socket left dispatch right socket right
83 * client ===========> server --------------> server ===========> client
94 DBusConnection *left_client_conn;
95 DBusConnection *left_server_conn;
97 DBusConnection *right_server_conn;
98 DBusConnection *right_client_conn;
99 /* queue of DBusMessage received by right_client_conn */
103 DBusInitialFDs *initial_fds;
106 static void oom (const gchar *doing) G_GNUC_NORETURN;
109 oom (const gchar *doing)
111 g_error ("out of memory (%s)", doing);
116 assert_no_error (const DBusError *e)
118 if (G_UNLIKELY (dbus_error_is_set (e)))
119 g_error ("expected success but got error: %s: %s", e->name, e->message);
122 static DBusHandlerResult
123 left_server_message_cb (DBusConnection *server_conn,
124 DBusMessage *message,
129 g_assert (server_conn == f->left_server_conn);
130 g_assert (f->right_server_conn != NULL);
132 dbus_connection_send (f->right_server_conn, message, NULL);
134 return DBUS_HANDLER_RESULT_HANDLED;
137 static DBusHandlerResult
138 right_client_message_cb (DBusConnection *client_conn,
139 DBusMessage *message,
144 g_assert (client_conn == f->right_client_conn);
145 g_queue_push_tail (&f->messages, dbus_message_ref (message));
147 return DBUS_HANDLER_RESULT_HANDLED;
151 new_conn_cb (DBusServer *server,
152 DBusConnection *server_conn,
157 dbus_connection_set_max_message_unix_fds (server_conn,
158 MAX_MESSAGE_UNIX_FDS);
159 dbus_connection_set_max_received_unix_fds (server_conn,
160 MAX_INCOMING_UNIX_FDS);
162 if (f->left_server_conn == NULL)
164 f->left_server_conn = dbus_connection_ref (server_conn);
166 if (!dbus_connection_add_filter (server_conn,
167 left_server_message_cb, f, NULL))
168 oom ("adding filter");
172 g_assert (f->right_server_conn == NULL);
173 f->right_server_conn = dbus_connection_ref (server_conn);
176 test_connection_setup (f->ctx, server_conn);
180 test_connect (Fixture *f,
181 gboolean should_support_fds)
188 f->initial_fds = _dbus_check_fdleaks_enter ();
190 g_assert (f->left_server_conn == NULL);
191 g_assert (f->right_server_conn == NULL);
193 address = dbus_server_get_address (f->server);
194 g_assert (address != NULL);
196 f->left_client_conn = dbus_connection_open_private (address, &f->e);
197 assert_no_error (&f->e);
198 g_assert (f->left_client_conn != NULL);
199 test_connection_setup (f->ctx, f->left_client_conn);
201 /* The left client connection is allowed to behave abusively. */
202 dbus_connection_set_max_message_unix_fds (f->left_client_conn, 1000);
203 dbus_connection_set_max_received_unix_fds (f->left_client_conn, 1000000);
205 while (f->left_server_conn == NULL)
208 test_main_context_iterate (f->ctx, TRUE);
211 f->right_client_conn = dbus_connection_open_private (address, &f->e);
212 assert_no_error (&f->e);
213 g_assert (f->right_client_conn != NULL);
214 test_connection_setup (f->ctx, f->right_client_conn);
218 while (f->right_server_conn == NULL)
221 test_main_context_iterate (f->ctx, TRUE);
224 if (!dbus_connection_add_filter (f->right_client_conn,
225 right_client_message_cb, f, NULL))
226 oom ("adding filter");
228 /* The right client connection is allowed to queue all the messages. */
229 dbus_connection_set_max_message_unix_fds (f->right_client_conn, 1000);
230 dbus_connection_set_max_received_unix_fds (f->right_client_conn, 1000000);
232 while (!dbus_connection_get_is_authenticated (f->left_client_conn) ||
233 !dbus_connection_get_is_authenticated (f->right_client_conn) ||
234 !dbus_connection_get_is_authenticated (f->left_server_conn) ||
235 !dbus_connection_get_is_authenticated (f->right_server_conn))
238 test_main_context_iterate (f->ctx, TRUE);
241 if (!should_support_fds)
244 if (!dbus_connection_can_send_type (f->left_client_conn,
246 g_error ("left client connection cannot send Unix fds");
248 if (!dbus_connection_can_send_type (f->left_server_conn,
250 g_error ("left server connection cannot send Unix fds");
252 if (!dbus_connection_can_send_type (f->right_client_conn,
254 g_error ("right client connection cannot send Unix fds");
256 if (!dbus_connection_can_send_type (f->right_server_conn,
258 g_error ("right server connection cannot send Unix fds");
262 setup_common (Fixture *f,
265 f->ctx = test_main_context_get ();
266 dbus_error_init (&f->e);
267 g_queue_init (&f->messages);
269 if ((g_str_has_prefix (address, "tcp:") ||
270 g_str_has_prefix (address, "nonce-tcp:")) &&
271 !test_check_tcp_works ())
277 f->server = dbus_server_listen (address, &f->e);
278 assert_no_error (&f->e);
279 g_assert (f->server != NULL);
281 dbus_server_set_new_connection_function (f->server,
282 new_conn_cb, f, NULL);
283 test_server_setup (f->ctx, f->server);
287 setup_unsupported (Fixture *f,
288 gconstpointer data G_GNUC_UNUSED)
290 setup_common (f, "tcp:host=127.0.0.1");
295 gconstpointer data G_GNUC_UNUSED)
297 #ifdef HAVE_UNIX_FD_PASSING
298 /* We assume that anything with fd-passing supports the unix: transport */
299 setup_common (f, "unix:tmpdir=/tmp");
301 f->fd_before = open ("/dev/null", O_RDONLY);
303 /* this should succeed on any reasonable Unix */
304 if (f->fd_before < 0)
305 g_error ("cannot open /dev/null for reading: %s", g_strerror (errno));
307 _dbus_fd_set_close_on_exec (f->fd_before);
312 test_unsupported (Fixture *f,
318 test_connect (f, FALSE);
320 if (dbus_connection_can_send_type (f->left_client_conn,
322 g_error ("left client connection claims it can send Unix fds");
324 if (dbus_connection_can_send_type (f->left_server_conn,
326 g_error ("left server connection claims it can send Unix fds");
328 if (dbus_connection_can_send_type (f->right_client_conn,
330 g_error ("right client connection claims it can send Unix fds");
332 if (dbus_connection_can_send_type (f->right_server_conn,
334 g_error ("right server connection claims it can send Unix fds");
338 test_relay (Fixture *f,
341 #ifdef HAVE_UNIX_FD_PASSING
342 /* We assume that any platform with working fd-passing is POSIX,
343 * and therefore has open() and fstat() */
344 dbus_uint32_t serial;
345 DBusMessage *outgoing, *incoming;
347 struct stat stat_before;
348 struct stat stat_after;
353 test_connect (f, TRUE);
355 outgoing = dbus_message_new_signal ("/com/example/Hello",
356 "com.example.Hello", "Greeting");
357 g_assert (outgoing != NULL);
359 if (!dbus_message_append_args (outgoing,
360 DBUS_TYPE_UNIX_FD, &f->fd_before,
362 oom ("appending fd");
364 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
365 oom ("sending message");
367 dbus_message_unref (outgoing);
369 while (g_queue_get_length (&f->messages) < 1)
372 test_main_context_iterate (f->ctx, TRUE);
375 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
377 incoming = g_queue_pop_head (&f->messages);
379 g_assert (dbus_message_contains_unix_fds (incoming));
380 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
381 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
382 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
383 "com.example.Hello");
384 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
385 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
386 g_assert_cmpstr (dbus_message_get_signature (incoming), ==,
387 DBUS_TYPE_UNIX_FD_AS_STRING);
388 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
389 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
391 if (dbus_set_error_from_message (&f->e, incoming))
392 g_error ("%s: %s", f->e.name, f->e.message);
393 else if (!dbus_message_get_args (incoming,
395 DBUS_TYPE_UNIX_FD, &fd_after,
397 g_error ("%s: %s", f->e.name, f->e.message);
399 assert_no_error (&f->e);
401 if (fstat (f->fd_before, &stat_before) < 0)
402 g_error ("%s", g_strerror (errno));
404 if (fstat (fd_after, &stat_after) < 0)
405 g_error ("%s", g_strerror (errno));
407 /* this seems like enough to say "it's the same file" */
408 g_assert_cmpint (stat_before.st_dev, ==, stat_after.st_dev);
409 g_assert_cmpint (stat_before.st_ino, ==, stat_after.st_ino);
410 g_assert_cmpint (stat_before.st_rdev, ==, stat_after.st_rdev);
412 dbus_message_unref (incoming);
414 if (close (fd_after) < 0)
415 g_error ("%s", g_strerror (errno));
417 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
418 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
419 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
420 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
422 g_test_skip ("fd-passing not supported on this platform");
427 test_limit (Fixture *f,
430 #ifdef HAVE_UNIX_FD_PASSING
431 dbus_uint32_t serial;
432 DBusMessage *outgoing, *incoming;
438 test_connect (f, TRUE);
440 outgoing = dbus_message_new_signal ("/com/example/Hello",
441 "com.example.Hello", "Greeting");
442 g_assert (outgoing != NULL);
444 for (i = 0; i < MAX_MESSAGE_UNIX_FDS; i++)
446 if (!dbus_message_append_args (outgoing,
447 DBUS_TYPE_UNIX_FD, &f->fd_before,
449 oom ("appending fd");
452 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
453 oom ("sending message");
455 dbus_message_unref (outgoing);
457 while (g_queue_get_length (&f->messages) < 1)
460 test_main_context_iterate (f->ctx, TRUE);
463 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
465 incoming = g_queue_pop_head (&f->messages);
467 g_assert (dbus_message_contains_unix_fds (incoming));
468 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
469 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
470 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
471 "com.example.Hello");
472 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
473 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
474 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
475 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
477 dbus_message_unref (incoming);
479 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
480 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
481 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
482 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
484 g_test_skip ("fd-passing not supported on this platform");
489 test_too_many (Fixture *f,
492 #ifdef HAVE_UNIX_FD_PASSING
493 DBusMessage *outgoing;
499 test_connect (f, TRUE);
501 outgoing = dbus_message_new_signal ("/com/example/Hello",
502 "com.example.Hello", "Greeting");
503 g_assert (outgoing != NULL);
505 for (i = 0; i < MAX_MESSAGE_UNIX_FDS + GPOINTER_TO_UINT (data); i++)
507 if (!dbus_message_append_args (outgoing,
508 DBUS_TYPE_UNIX_FD, &f->fd_before,
510 oom ("appending fd");
513 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
514 oom ("sending message");
516 dbus_message_unref (outgoing);
518 /* The sender is unceremoniously disconnected. */
519 while (dbus_connection_get_is_connected (f->left_client_conn) ||
520 dbus_connection_get_is_connected (f->left_server_conn))
523 test_main_context_iterate (f->ctx, TRUE);
526 /* The message didn't get through without its fds. */
527 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
529 /* The intended victim is unaffected by the left connection's
531 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
532 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
534 g_test_skip ("fd-passing not supported on this platform");
539 test_too_many_split (Fixture *f,
542 #ifdef HAVE_UNIX_FD_PASSING
543 DBusMessage *outgoing;
545 DBusSocket left_client_socket;
549 int fds[TOO_MANY_FDS];
551 #ifdef HAVE_GETRLIMIT
558 /* This test deliberately pushes up against OS limits, so skip it
559 * if we don't have enough fds. 4 times the maximum per message
560 * ought to be enough: that will cover the message, the dup'd fds
561 * we actually send, the copy that we potentially receive, and some
562 * spare capacity for everything else. */
563 #ifdef HAVE_GETRLIMIT
564 if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
566 if (lim.rlim_cur != RLIM_INFINITY &&
567 lim.rlim_cur < 4 * TOO_MANY_FDS)
569 g_test_skip ("not enough RLIMIT_NOFILE");
575 test_connect (f, TRUE);
577 outgoing = dbus_message_new_signal ("/com/example/Hello",
578 "com.example.Hello", "Greeting");
579 g_assert (outgoing != NULL);
581 /* TOO_MANY_FDS fds are far too many: in particular, Linux doesn't allow
582 * sending this many in a single sendmsg(). libdbus never splits
583 * a message between two sendmsg() calls if it can help it, and
584 * in particular it always sends all the fds with the first sendmsg(),
585 * but malicious senders might not be so considerate. */
586 for (i = 0; i < TOO_MANY_FDS; i++)
588 if (!dbus_message_append_args (outgoing,
589 DBUS_TYPE_UNIX_FD, &f->fd_before,
591 oom ("appending fd");
594 /* This probably shouldn't work for messages with fds, but it does,
595 * which is convenient for this sort of trickery. */
596 if (!dbus_message_marshal (outgoing, &payload, &payload_len))
597 oom ("marshalling message");
599 _dbus_string_init_const_len (&buffer, payload, payload_len);
601 for (i = 0; i < TOO_MANY_FDS; i++)
603 fds[i] = dup (f->fd_before);
606 g_error ("could not dup fd: %s", g_strerror (errno));
609 /* This is blatant cheating, and the API documentation specifically
610 * tells you not use this function in this way. Never do this
611 * in application code. */
612 if (!dbus_connection_get_socket (f->left_client_conn,
613 &left_client_socket.fd))
614 g_error ("'unix:' DBusConnection should have had a socket");
616 /* Just to be sure that we're at a message boundary. */
617 dbus_connection_flush (f->left_client_conn);
619 /* We have too many fds for one sendmsg(), so send the first half
620 * (rounding down if odd) with the first byte... */
621 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 0, 1,
622 &fds[0], TOO_MANY_FDS / 2);
625 g_error ("could not send first byte and first batch of fds: %s",
628 /* ... and the second half (rounding up if odd) with the rest of
630 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 1,
631 payload_len - 1, &fds[TOO_MANY_FDS / 2],
632 TOO_MANY_FDS - (TOO_MANY_FDS / 2));
636 g_error ("could not send rest of message and rest of fds: %s",
639 else if (done < payload_len - 1)
641 /* For simplicity, assume the socket buffer is big enough for the
642 * whole message, which should be < 2 KiB. If this fails on some
643 * OS, redo this test code to use a proper loop like the real
645 g_error ("short write in sendmsg(), fix this test: %d/%d",
646 done, payload_len - 1);
651 for (i = 0; i < TOO_MANY_FDS; i++)
654 dbus_message_unref (outgoing);
656 /* The sender is unceremoniously disconnected. */
657 while (dbus_connection_get_is_connected (f->left_client_conn) ||
658 dbus_connection_get_is_connected (f->left_server_conn))
661 test_main_context_iterate (f->ctx, TRUE);
664 /* The message didn't get through without its fds. */
665 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
667 /* The intended victim is unaffected by the left connection's
669 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
670 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
672 g_test_skip ("fd-passing not supported on this platform");
677 test_flood (Fixture *f,
680 #ifdef HAVE_UNIX_FD_PASSING
682 DBusMessage *outgoing[SOME_MESSAGES];
683 dbus_uint32_t serial;
688 test_connect (f, TRUE);
690 for (j = 0; j < SOME_MESSAGES; j++)
692 outgoing[j] = dbus_message_new_signal ("/com/example/Hello",
693 "com.example.Hello", "Greeting");
694 g_assert (outgoing[j] != NULL);
696 for (i = 0; i < GPOINTER_TO_UINT (data); i++)
698 if (!dbus_message_append_args (outgoing[j],
699 DBUS_TYPE_UNIX_FD, &f->fd_before,
701 oom ("appending fd");
705 /* This is in its own loop so we do it as fast as possible */
706 for (j = 0; j < SOME_MESSAGES; j++)
708 if (!dbus_connection_send (f->left_client_conn, outgoing[j], &serial))
709 oom ("sending message");
712 for (j = 0; j < SOME_MESSAGES; j++)
714 dbus_message_unref (outgoing[j]);
717 while (g_queue_get_length (&f->messages) < SOME_MESSAGES)
720 test_main_context_iterate (f->ctx, TRUE);
723 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, SOME_MESSAGES);
725 for (j = 0; j < SOME_MESSAGES; j++)
727 DBusMessage *incoming;
729 incoming = g_queue_pop_head (&f->messages);
731 g_assert (dbus_message_contains_unix_fds (incoming));
732 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
733 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
734 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
735 "com.example.Hello");
736 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
737 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
738 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
740 dbus_message_unref (incoming);
743 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
744 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
745 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
746 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
748 g_test_skip ("fd-passing not supported on this platform");
753 test_odd_limit (Fixture *f,
756 #ifdef HAVE_UNIX_FD_PASSING
757 DBusMessage *outgoing;
763 test_connect (f, TRUE);
764 dbus_connection_set_max_message_unix_fds (f->left_server_conn, 7);
765 dbus_connection_set_max_message_unix_fds (f->right_server_conn, 7);
767 outgoing = dbus_message_new_signal ("/com/example/Hello",
768 "com.example.Hello", "Greeting");
769 g_assert (outgoing != NULL);
771 for (i = 0; i < 7 + GPOINTER_TO_INT (data); i++)
773 if (!dbus_message_append_args (outgoing,
774 DBUS_TYPE_UNIX_FD, &f->fd_before,
776 oom ("appending fd");
779 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
780 oom ("sending message");
782 dbus_message_unref (outgoing);
784 if (GPOINTER_TO_INT (data) > 0)
786 /* The sender is unceremoniously disconnected. */
787 while (dbus_connection_get_is_connected (f->left_client_conn) ||
788 dbus_connection_get_is_connected (f->left_server_conn))
791 test_main_context_iterate (f->ctx, TRUE);
794 /* The message didn't get through without its fds. */
795 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
797 /* The intended victim is unaffected by the left connection's
799 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
800 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
804 DBusMessage *incoming;
806 /* We're at or under the limit. The message gets through intact. */
807 while (g_queue_get_length (&f->messages) < 1)
810 test_main_context_iterate (f->ctx, TRUE);
813 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
815 incoming = g_queue_pop_head (&f->messages);
817 g_assert (dbus_message_contains_unix_fds (incoming));
818 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
819 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
820 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
821 "com.example.Hello");
822 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
823 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
824 g_assert_cmpstr (dbus_message_get_path (incoming), ==,
825 "/com/example/Hello");
827 dbus_message_unref (incoming);
829 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
830 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
831 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
832 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
835 g_test_skip ("fd-passing not supported on this platform");
840 teardown (Fixture *f,
841 gconstpointer data G_GNUC_UNUSED)
843 if (f->left_client_conn != NULL)
845 dbus_connection_close (f->left_client_conn);
846 dbus_connection_unref (f->left_client_conn);
847 f->left_client_conn = NULL;
850 if (f->right_client_conn != NULL)
852 dbus_connection_close (f->right_client_conn);
853 dbus_connection_unref (f->right_client_conn);
854 f->right_client_conn = NULL;
857 if (f->left_server_conn != NULL)
859 dbus_connection_close (f->left_server_conn);
860 dbus_connection_unref (f->left_server_conn);
861 f->left_server_conn = NULL;
864 if (f->right_server_conn != NULL)
866 dbus_connection_close (f->right_server_conn);
867 dbus_connection_unref (f->right_server_conn);
868 f->right_server_conn = NULL;
871 if (f->server != NULL)
873 dbus_server_disconnect (f->server);
874 dbus_server_unref (f->server);
879 test_main_context_unref (f->ctx);
881 #ifdef HAVE_UNIX_FD_PASSING
882 if (f->fd_before >= 0 && close (f->fd_before) < 0)
883 g_error ("%s", g_strerror (errno));
886 if (f->initial_fds != NULL)
887 _dbus_check_fdleaks_leave (f->initial_fds);
894 test_init (&argc, &argv);
896 #ifdef HAVE_GETRLIMIT
900 if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
901 g_error ("Failed to get RLIMIT_NOFILE limit: %s", g_strerror (errno));
903 if (lim.rlim_cur != RLIM_INFINITY &&
904 /* only run if we have a fairly generous margin of error
905 * for stdout, stderr, duplicates, the D-Bus connection, etc. */
906 lim.rlim_cur < 2 * MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES)
908 g_message ("not enough RLIMIT_NOFILE to run this test");
909 /* Autotools exit code for "all skipped" */
915 g_test_add ("/unsupported", Fixture, NULL, setup_unsupported,
916 test_unsupported, teardown);
918 g_test_add ("/relay", Fixture, NULL, setup,
919 test_relay, teardown);
920 g_test_add ("/limit", Fixture, NULL, setup,
921 test_limit, teardown);
923 g_test_add ("/too-many/plus1", Fixture, GUINT_TO_POINTER (1), setup,
924 test_too_many, teardown);
925 g_test_add ("/too-many/plus2", Fixture, GUINT_TO_POINTER (2), setup,
926 test_too_many, teardown);
927 g_test_add ("/too-many/plus17", Fixture, GUINT_TO_POINTER (17), setup,
928 test_too_many, teardown);
930 g_test_add ("/too-many/split", Fixture, NULL, setup,
931 test_too_many_split, teardown);
933 g_test_add ("/flood/1", Fixture, GUINT_TO_POINTER (1),
934 setup, test_flood, teardown);
935 #if MAX_MESSAGE_UNIX_FDS >= 2
936 g_test_add ("/flood/half-limit", Fixture,
937 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS / 2),
938 setup, test_flood, teardown);
940 #if MAX_MESSAGE_UNIX_FDS >= 4
941 g_test_add ("/flood/over-half-limit", Fixture,
942 GUINT_TO_POINTER (3 * MAX_MESSAGE_UNIX_FDS / 4),
943 setup, test_flood, teardown);
945 g_test_add ("/flood/limit", Fixture,
946 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS), setup, test_flood, teardown);
948 g_test_add ("/odd-limit/minus1", Fixture, GINT_TO_POINTER (-1), setup,
949 test_odd_limit, teardown);
950 g_test_add ("/odd-limit/at", Fixture, GINT_TO_POINTER (0), setup,
951 test_odd_limit, teardown);
952 g_test_add ("/odd-limit/plus1", Fixture, GINT_TO_POINTER (+1), setup,
953 test_odd_limit, teardown);
954 g_test_add ("/odd-limit/plus2", Fixture, GINT_TO_POINTER (+2), setup,
955 test_odd_limit, teardown);
957 return g_test_run ();