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 /* Arbitrary; included here to avoid relying on the default */
54 #define MAX_MESSAGE_UNIX_FDS 20
55 /* This test won't work on Linux unless this is true. */
56 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS <= 253);
58 /* Arbitrary; included here to avoid relying on the default. */
59 #define MAX_INCOMING_UNIX_FDS (MAX_MESSAGE_UNIX_FDS * 4)
61 /* Arbitrary, except that MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES should be
62 * less than the process's file descriptor limit. */
63 #define SOME_MESSAGES 20
64 /* To cover some situations on Linux we want this to be true. */
65 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES > 256);
67 /* Linux won't allow more than 253 fds per sendmsg(). */
68 #define TOO_MANY_FDS 255
69 _DBUS_STATIC_ASSERT (MAX_MESSAGE_UNIX_FDS < TOO_MANY_FDS);
71 /* As in test/relay.c, this is a miniature dbus-daemon: we relay messages
72 * from the client on the left to the client on the right.
74 * left socket left dispatch right socket right
75 * client ===========> server --------------> server ===========> client
86 DBusConnection *left_client_conn;
87 DBusConnection *left_server_conn;
89 DBusConnection *right_server_conn;
90 DBusConnection *right_client_conn;
91 /* queue of DBusMessage received by right_client_conn */
97 static void oom (const gchar *doing) G_GNUC_NORETURN;
100 oom (const gchar *doing)
102 g_error ("out of memory (%s)", doing);
107 assert_no_error (const DBusError *e)
109 if (G_UNLIKELY (dbus_error_is_set (e)))
110 g_error ("expected success but got error: %s: %s", e->name, e->message);
113 static DBusHandlerResult
114 left_server_message_cb (DBusConnection *server_conn,
115 DBusMessage *message,
120 g_assert (server_conn == f->left_server_conn);
121 g_assert (f->right_server_conn != NULL);
123 dbus_connection_send (f->right_server_conn, message, NULL);
125 return DBUS_HANDLER_RESULT_HANDLED;
128 static DBusHandlerResult
129 right_client_message_cb (DBusConnection *client_conn,
130 DBusMessage *message,
135 g_assert (client_conn == f->right_client_conn);
136 g_queue_push_tail (&f->messages, dbus_message_ref (message));
138 return DBUS_HANDLER_RESULT_HANDLED;
142 new_conn_cb (DBusServer *server,
143 DBusConnection *server_conn,
148 dbus_connection_set_max_message_unix_fds (server_conn,
149 MAX_MESSAGE_UNIX_FDS);
150 dbus_connection_set_max_received_unix_fds (server_conn,
151 MAX_INCOMING_UNIX_FDS);
153 if (f->left_server_conn == NULL)
155 f->left_server_conn = dbus_connection_ref (server_conn);
157 if (!dbus_connection_add_filter (server_conn,
158 left_server_message_cb, f, NULL))
159 oom ("adding filter");
163 g_assert (f->right_server_conn == NULL);
164 f->right_server_conn = dbus_connection_ref (server_conn);
167 test_connection_setup (f->ctx, server_conn);
171 test_connect (Fixture *f,
172 gboolean should_support_fds)
179 g_assert (f->left_server_conn == NULL);
180 g_assert (f->right_server_conn == NULL);
182 address = dbus_server_get_address (f->server);
183 g_assert (address != NULL);
185 f->left_client_conn = dbus_connection_open_private (address, &f->e);
186 assert_no_error (&f->e);
187 g_assert (f->left_client_conn != NULL);
188 test_connection_setup (f->ctx, f->left_client_conn);
190 /* The left client connection is allowed to behave abusively. */
191 dbus_connection_set_max_message_unix_fds (f->left_client_conn, 1000);
192 dbus_connection_set_max_received_unix_fds (f->left_client_conn, 1000000);
194 while (f->left_server_conn == NULL)
197 test_main_context_iterate (f->ctx, TRUE);
200 f->right_client_conn = dbus_connection_open_private (address, &f->e);
201 assert_no_error (&f->e);
202 g_assert (f->right_client_conn != NULL);
203 test_connection_setup (f->ctx, f->right_client_conn);
207 while (f->right_server_conn == NULL)
210 test_main_context_iterate (f->ctx, TRUE);
213 if (!dbus_connection_add_filter (f->right_client_conn,
214 right_client_message_cb, f, NULL))
215 oom ("adding filter");
217 /* The right client connection is allowed to queue all the messages. */
218 dbus_connection_set_max_message_unix_fds (f->right_client_conn, 1000);
219 dbus_connection_set_max_received_unix_fds (f->right_client_conn, 1000000);
221 while (!dbus_connection_get_is_authenticated (f->left_client_conn) ||
222 !dbus_connection_get_is_authenticated (f->right_client_conn) ||
223 !dbus_connection_get_is_authenticated (f->left_server_conn) ||
224 !dbus_connection_get_is_authenticated (f->right_server_conn))
227 test_main_context_iterate (f->ctx, TRUE);
230 if (!should_support_fds)
233 if (!dbus_connection_can_send_type (f->left_client_conn,
235 g_error ("left client connection cannot send Unix fds");
237 if (!dbus_connection_can_send_type (f->left_server_conn,
239 g_error ("left server connection cannot send Unix fds");
241 if (!dbus_connection_can_send_type (f->right_client_conn,
243 g_error ("right client connection cannot send Unix fds");
245 if (!dbus_connection_can_send_type (f->right_server_conn,
247 g_error ("right server connection cannot send Unix fds");
251 setup_common (Fixture *f,
254 f->ctx = test_main_context_get ();
255 dbus_error_init (&f->e);
256 g_queue_init (&f->messages);
258 if ((g_str_has_prefix (address, "tcp:") ||
259 g_str_has_prefix (address, "nonce-tcp:")) &&
260 !test_check_tcp_works ())
266 f->server = dbus_server_listen (address, &f->e);
267 assert_no_error (&f->e);
268 g_assert (f->server != NULL);
270 dbus_server_set_new_connection_function (f->server,
271 new_conn_cb, f, NULL);
272 test_server_setup (f->ctx, f->server);
276 setup_unsupported (Fixture *f,
277 gconstpointer data G_GNUC_UNUSED)
279 setup_common (f, "tcp:host=127.0.0.1");
284 gconstpointer data G_GNUC_UNUSED)
286 #ifdef HAVE_UNIX_FD_PASSING
287 /* We assume that anything with fd-passing supports the unix: transport */
288 setup_common (f, "unix:tmpdir=/tmp");
290 f->fd_before = open ("/dev/null", O_RDONLY);
292 /* this should succeed on any reasonable Unix */
293 if (f->fd_before < 0)
294 g_error ("cannot open /dev/null for reading: %s", g_strerror (errno));
296 _dbus_fd_set_close_on_exec (f->fd_before);
301 test_unsupported (Fixture *f,
307 test_connect (f, FALSE);
309 if (dbus_connection_can_send_type (f->left_client_conn,
311 g_error ("left client connection claims it can send Unix fds");
313 if (dbus_connection_can_send_type (f->left_server_conn,
315 g_error ("left server connection claims it can send Unix fds");
317 if (dbus_connection_can_send_type (f->right_client_conn,
319 g_error ("right client connection claims it can send Unix fds");
321 if (dbus_connection_can_send_type (f->right_server_conn,
323 g_error ("right server connection claims it can send Unix fds");
327 test_relay (Fixture *f,
330 #ifdef HAVE_UNIX_FD_PASSING
331 /* We assume that any platform with working fd-passing is POSIX,
332 * and therefore has open() and fstat() */
333 dbus_uint32_t serial;
334 DBusMessage *outgoing, *incoming;
336 struct stat stat_before;
337 struct stat stat_after;
342 test_connect (f, TRUE);
344 outgoing = dbus_message_new_signal ("/com/example/Hello",
345 "com.example.Hello", "Greeting");
346 g_assert (outgoing != NULL);
348 if (!dbus_message_append_args (outgoing,
349 DBUS_TYPE_UNIX_FD, &f->fd_before,
351 oom ("appending fd");
353 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
354 oom ("sending message");
356 dbus_message_unref (outgoing);
358 while (g_queue_get_length (&f->messages) < 1)
361 test_main_context_iterate (f->ctx, TRUE);
364 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
366 incoming = g_queue_pop_head (&f->messages);
368 g_assert (dbus_message_contains_unix_fds (incoming));
369 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
370 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
371 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
372 "com.example.Hello");
373 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
374 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
375 g_assert_cmpstr (dbus_message_get_signature (incoming), ==,
376 DBUS_TYPE_UNIX_FD_AS_STRING);
377 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
378 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
380 if (dbus_set_error_from_message (&f->e, incoming))
381 g_error ("%s: %s", f->e.name, f->e.message);
382 else if (!dbus_message_get_args (incoming,
384 DBUS_TYPE_UNIX_FD, &fd_after,
386 g_error ("%s: %s", f->e.name, f->e.message);
388 assert_no_error (&f->e);
390 if (fstat (f->fd_before, &stat_before) < 0)
391 g_error ("%s", g_strerror (errno));
393 if (fstat (fd_after, &stat_after) < 0)
394 g_error ("%s", g_strerror (errno));
396 /* this seems like enough to say "it's the same file" */
397 g_assert_cmpint (stat_before.st_dev, ==, stat_after.st_dev);
398 g_assert_cmpint (stat_before.st_ino, ==, stat_after.st_ino);
399 g_assert_cmpint (stat_before.st_rdev, ==, stat_after.st_rdev);
401 dbus_message_unref (incoming);
403 if (close (fd_after) < 0)
404 g_error ("%s", g_strerror (errno));
406 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
407 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
408 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
409 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
411 g_test_skip ("fd-passing not supported on this platform");
416 test_limit (Fixture *f,
419 #ifdef HAVE_UNIX_FD_PASSING
420 dbus_uint32_t serial;
421 DBusMessage *outgoing, *incoming;
427 test_connect (f, TRUE);
429 outgoing = dbus_message_new_signal ("/com/example/Hello",
430 "com.example.Hello", "Greeting");
431 g_assert (outgoing != NULL);
433 for (i = 0; i < MAX_MESSAGE_UNIX_FDS; i++)
435 if (!dbus_message_append_args (outgoing,
436 DBUS_TYPE_UNIX_FD, &f->fd_before,
438 oom ("appending fd");
441 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
442 oom ("sending message");
444 dbus_message_unref (outgoing);
446 while (g_queue_get_length (&f->messages) < 1)
449 test_main_context_iterate (f->ctx, TRUE);
452 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
454 incoming = g_queue_pop_head (&f->messages);
456 g_assert (dbus_message_contains_unix_fds (incoming));
457 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
458 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
459 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
460 "com.example.Hello");
461 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
462 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
463 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
464 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
466 dbus_message_unref (incoming);
468 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
469 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
470 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
471 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
473 g_test_skip ("fd-passing not supported on this platform");
478 test_too_many (Fixture *f,
481 #ifdef HAVE_UNIX_FD_PASSING
482 DBusMessage *outgoing;
488 test_connect (f, TRUE);
490 outgoing = dbus_message_new_signal ("/com/example/Hello",
491 "com.example.Hello", "Greeting");
492 g_assert (outgoing != NULL);
494 for (i = 0; i < MAX_MESSAGE_UNIX_FDS + GPOINTER_TO_UINT (data); i++)
496 if (!dbus_message_append_args (outgoing,
497 DBUS_TYPE_UNIX_FD, &f->fd_before,
499 oom ("appending fd");
502 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
503 oom ("sending message");
505 dbus_message_unref (outgoing);
507 /* The sender is unceremoniously disconnected. */
508 while (dbus_connection_get_is_connected (f->left_client_conn) ||
509 dbus_connection_get_is_connected (f->left_server_conn))
512 test_main_context_iterate (f->ctx, TRUE);
515 /* The message didn't get through without its fds. */
516 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
518 /* The intended victim is unaffected by the left connection's
520 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
521 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
523 g_test_skip ("fd-passing not supported on this platform");
528 test_too_many_split (Fixture *f,
531 #ifdef HAVE_UNIX_FD_PASSING
532 DBusMessage *outgoing;
534 DBusSocket left_client_socket;
538 int fds[TOO_MANY_FDS];
540 #ifdef HAVE_GETRLIMIT
547 /* This test deliberately pushes up against OS limits, so skip it
548 * if we don't have enough fds. 4 times the maximum per message
549 * ought to be enough: that will cover the message, the dup'd fds
550 * we actually send, the copy that we potentially receive, and some
551 * spare capacity for everything else. */
552 #ifdef HAVE_GETRLIMIT
553 if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
555 if (lim.rlim_cur != RLIM_INFINITY &&
556 lim.rlim_cur < 4 * TOO_MANY_FDS)
558 g_test_skip ("not enough RLIMIT_NOFILE");
564 test_connect (f, TRUE);
566 outgoing = dbus_message_new_signal ("/com/example/Hello",
567 "com.example.Hello", "Greeting");
568 g_assert (outgoing != NULL);
570 /* TOO_MANY_FDS fds are far too many: in particular, Linux doesn't allow
571 * sending this many in a single sendmsg(). libdbus never splits
572 * a message between two sendmsg() calls if it can help it, and
573 * in particular it always sends all the fds with the first sendmsg(),
574 * but malicious senders might not be so considerate. */
575 for (i = 0; i < TOO_MANY_FDS; i++)
577 if (!dbus_message_append_args (outgoing,
578 DBUS_TYPE_UNIX_FD, &f->fd_before,
580 oom ("appending fd");
583 /* This probably shouldn't work for messages with fds, but it does,
584 * which is convenient for this sort of trickery. */
585 if (!dbus_message_marshal (outgoing, &payload, &payload_len))
586 oom ("marshalling message");
588 _dbus_string_init_const_len (&buffer, payload, payload_len);
590 for (i = 0; i < TOO_MANY_FDS; i++)
592 fds[i] = dup (f->fd_before);
595 g_error ("could not dup fd: %s", g_strerror (errno));
598 /* This is blatant cheating, and the API documentation specifically
599 * tells you not use this function in this way. Never do this
600 * in application code. */
601 if (!dbus_connection_get_socket (f->left_client_conn,
602 &left_client_socket.fd))
603 g_error ("'unix:' DBusConnection should have had a socket");
605 /* Just to be sure that we're at a message boundary. */
606 dbus_connection_flush (f->left_client_conn);
608 /* We have too many fds for one sendmsg(), so send the first half
609 * (rounding down if odd) with the first byte... */
610 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 0, 1,
611 &fds[0], TOO_MANY_FDS / 2);
614 g_error ("could not send first byte and first batch of fds: %s",
617 /* ... and the second half (rounding up if odd) with the rest of
619 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 1,
620 payload_len - 1, &fds[TOO_MANY_FDS / 2],
621 TOO_MANY_FDS - (TOO_MANY_FDS / 2));
625 g_error ("could not send rest of message and rest of fds: %s",
628 else if (done < payload_len - 1)
630 /* For simplicity, assume the socket buffer is big enough for the
631 * whole message, which should be < 2 KiB. If this fails on some
632 * OS, redo this test code to use a proper loop like the real
634 g_error ("short write in sendmsg(), fix this test: %d/%d",
635 done, payload_len - 1);
640 for (i = 0; i < TOO_MANY_FDS; i++)
643 dbus_message_unref (outgoing);
645 /* The sender is unceremoniously disconnected. */
646 while (dbus_connection_get_is_connected (f->left_client_conn) ||
647 dbus_connection_get_is_connected (f->left_server_conn))
650 test_main_context_iterate (f->ctx, TRUE);
653 /* The message didn't get through without its fds. */
654 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
656 /* The intended victim is unaffected by the left connection's
658 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
659 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
661 g_test_skip ("fd-passing not supported on this platform");
666 test_flood (Fixture *f,
669 #ifdef HAVE_UNIX_FD_PASSING
671 DBusMessage *outgoing[SOME_MESSAGES];
672 dbus_uint32_t serial;
677 test_connect (f, TRUE);
679 for (j = 0; j < SOME_MESSAGES; j++)
681 outgoing[j] = dbus_message_new_signal ("/com/example/Hello",
682 "com.example.Hello", "Greeting");
683 g_assert (outgoing[j] != NULL);
685 for (i = 0; i < GPOINTER_TO_UINT (data); i++)
687 if (!dbus_message_append_args (outgoing[j],
688 DBUS_TYPE_UNIX_FD, &f->fd_before,
690 oom ("appending fd");
694 /* This is in its own loop so we do it as fast as possible */
695 for (j = 0; j < SOME_MESSAGES; j++)
697 if (!dbus_connection_send (f->left_client_conn, outgoing[j], &serial))
698 oom ("sending message");
701 for (j = 0; j < SOME_MESSAGES; j++)
703 dbus_message_unref (outgoing[j]);
706 while (g_queue_get_length (&f->messages) < SOME_MESSAGES)
709 test_main_context_iterate (f->ctx, TRUE);
712 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, SOME_MESSAGES);
714 for (j = 0; j < SOME_MESSAGES; j++)
716 DBusMessage *incoming;
718 incoming = g_queue_pop_head (&f->messages);
720 g_assert (dbus_message_contains_unix_fds (incoming));
721 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
722 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
723 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
724 "com.example.Hello");
725 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
726 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
727 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
729 dbus_message_unref (incoming);
732 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
733 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
734 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
735 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
737 g_test_skip ("fd-passing not supported on this platform");
742 test_odd_limit (Fixture *f,
745 #ifdef HAVE_UNIX_FD_PASSING
746 DBusMessage *outgoing;
752 test_connect (f, TRUE);
753 dbus_connection_set_max_message_unix_fds (f->left_server_conn, 7);
754 dbus_connection_set_max_message_unix_fds (f->right_server_conn, 7);
756 outgoing = dbus_message_new_signal ("/com/example/Hello",
757 "com.example.Hello", "Greeting");
758 g_assert (outgoing != NULL);
760 for (i = 0; i < 7 + GPOINTER_TO_INT (data); i++)
762 if (!dbus_message_append_args (outgoing,
763 DBUS_TYPE_UNIX_FD, &f->fd_before,
765 oom ("appending fd");
768 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
769 oom ("sending message");
771 dbus_message_unref (outgoing);
773 if (GPOINTER_TO_INT (data) > 0)
775 /* The sender is unceremoniously disconnected. */
776 while (dbus_connection_get_is_connected (f->left_client_conn) ||
777 dbus_connection_get_is_connected (f->left_server_conn))
780 test_main_context_iterate (f->ctx, TRUE);
783 /* The message didn't get through without its fds. */
784 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
786 /* The intended victim is unaffected by the left connection's
788 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
789 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
793 DBusMessage *incoming;
795 /* We're at or under the limit. The message gets through intact. */
796 while (g_queue_get_length (&f->messages) < 1)
799 test_main_context_iterate (f->ctx, TRUE);
802 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
804 incoming = g_queue_pop_head (&f->messages);
806 g_assert (dbus_message_contains_unix_fds (incoming));
807 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
808 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
809 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
810 "com.example.Hello");
811 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
812 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
813 g_assert_cmpstr (dbus_message_get_path (incoming), ==,
814 "/com/example/Hello");
816 dbus_message_unref (incoming);
818 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
819 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
820 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
821 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
824 g_test_skip ("fd-passing not supported on this platform");
829 teardown (Fixture *f,
830 gconstpointer data G_GNUC_UNUSED)
832 if (f->left_client_conn != NULL)
834 dbus_connection_close (f->left_client_conn);
835 dbus_connection_unref (f->left_client_conn);
836 f->left_client_conn = NULL;
839 if (f->right_client_conn != NULL)
841 dbus_connection_close (f->right_client_conn);
842 dbus_connection_unref (f->right_client_conn);
843 f->right_client_conn = NULL;
846 if (f->left_server_conn != NULL)
848 dbus_connection_close (f->left_server_conn);
849 dbus_connection_unref (f->left_server_conn);
850 f->left_server_conn = NULL;
853 if (f->right_server_conn != NULL)
855 dbus_connection_close (f->right_server_conn);
856 dbus_connection_unref (f->right_server_conn);
857 f->right_server_conn = NULL;
860 if (f->server != NULL)
862 dbus_server_disconnect (f->server);
863 dbus_server_unref (f->server);
868 test_main_context_unref (f->ctx);
870 #ifdef HAVE_UNIX_FD_PASSING
871 if (f->fd_before >= 0 && close (f->fd_before) < 0)
872 g_error ("%s", g_strerror (errno));
880 test_init (&argc, &argv);
882 #ifdef HAVE_GETRLIMIT
886 if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
887 g_error ("Failed to get RLIMIT_NOFILE limit: %s", g_strerror (errno));
889 if (lim.rlim_cur != RLIM_INFINITY &&
890 /* only run if we have a fairly generous margin of error
891 * for stdout, stderr, duplicates, the D-Bus connection, etc. */
892 lim.rlim_cur < 2 * MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES)
894 g_message ("not enough RLIMIT_NOFILE to run this test");
895 /* Autotools exit code for "all skipped" */
901 g_test_add ("/unsupported", Fixture, NULL, setup_unsupported,
902 test_unsupported, teardown);
904 g_test_add ("/relay", Fixture, NULL, setup,
905 test_relay, teardown);
906 g_test_add ("/limit", Fixture, NULL, setup,
907 test_limit, teardown);
909 g_test_add ("/too-many/plus1", Fixture, GUINT_TO_POINTER (1), setup,
910 test_too_many, teardown);
911 g_test_add ("/too-many/plus2", Fixture, GUINT_TO_POINTER (2), setup,
912 test_too_many, teardown);
913 g_test_add ("/too-many/plus17", Fixture, GUINT_TO_POINTER (17), setup,
914 test_too_many, teardown);
916 g_test_add ("/too-many/split", Fixture, NULL, setup,
917 test_too_many_split, teardown);
919 g_test_add ("/flood/1", Fixture, GUINT_TO_POINTER (1),
920 setup, test_flood, teardown);
921 #if MAX_MESSAGE_UNIX_FDS >= 2
922 g_test_add ("/flood/half-limit", Fixture,
923 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS / 2),
924 setup, test_flood, teardown);
926 #if MAX_MESSAGE_UNIX_FDS >= 4
927 g_test_add ("/flood/over-half-limit", Fixture,
928 GUINT_TO_POINTER (3 * MAX_MESSAGE_UNIX_FDS / 4),
929 setup, test_flood, teardown);
931 g_test_add ("/flood/limit", Fixture,
932 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS), setup, test_flood, teardown);
934 g_test_add ("/odd-limit/minus1", Fixture, GINT_TO_POINTER (-1), setup,
935 test_odd_limit, teardown);
936 g_test_add ("/odd-limit/at", Fixture, GINT_TO_POINTER (0), setup,
937 test_odd_limit, teardown);
938 g_test_add ("/odd-limit/plus1", Fixture, GINT_TO_POINTER (+1), setup,
939 test_odd_limit, teardown);
940 g_test_add ("/odd-limit/plus2", Fixture, GINT_TO_POINTER (+2), setup,
941 test_odd_limit, teardown);
943 return g_test_run ();