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
85 DBusConnection *left_client_conn;
86 DBusConnection *left_server_conn;
88 DBusConnection *right_server_conn;
89 DBusConnection *right_client_conn;
90 /* queue of DBusMessage received by right_client_conn */
96 #ifdef HAVE_UNIX_FD_PASSING
98 static void oom (const gchar *doing) G_GNUC_NORETURN;
101 oom (const gchar *doing)
103 g_error ("out of memory (%s)", doing);
108 assert_no_error (const DBusError *e)
110 if (G_UNLIKELY (dbus_error_is_set (e)))
111 g_error ("expected success but got error: %s: %s", e->name, e->message);
114 static DBusHandlerResult
115 left_server_message_cb (DBusConnection *server_conn,
116 DBusMessage *message,
121 g_assert (server_conn == f->left_server_conn);
122 g_assert (f->right_server_conn != NULL);
124 dbus_connection_send (f->right_server_conn, message, NULL);
126 return DBUS_HANDLER_RESULT_HANDLED;
129 static DBusHandlerResult
130 right_client_message_cb (DBusConnection *client_conn,
131 DBusMessage *message,
136 g_assert (client_conn == f->right_client_conn);
137 g_queue_push_tail (&f->messages, dbus_message_ref (message));
139 return DBUS_HANDLER_RESULT_HANDLED;
143 new_conn_cb (DBusServer *server,
144 DBusConnection *server_conn,
149 dbus_connection_set_max_message_unix_fds (server_conn,
150 MAX_MESSAGE_UNIX_FDS);
151 dbus_connection_set_max_received_unix_fds (server_conn,
152 MAX_INCOMING_UNIX_FDS);
154 if (f->left_server_conn == NULL)
156 f->left_server_conn = dbus_connection_ref (server_conn);
158 if (!dbus_connection_add_filter (server_conn,
159 left_server_message_cb, f, NULL))
160 oom ("adding filter");
164 g_assert (f->right_server_conn == NULL);
165 f->right_server_conn = dbus_connection_ref (server_conn);
168 test_connection_setup (f->ctx, server_conn);
172 test_connect (Fixture *f,
173 gconstpointer data G_GNUC_UNUSED)
177 g_assert (f->left_server_conn == NULL);
178 g_assert (f->right_server_conn == NULL);
180 address = dbus_server_get_address (f->server);
181 g_assert (address != NULL);
183 f->left_client_conn = dbus_connection_open_private (address, &f->e);
184 assert_no_error (&f->e);
185 g_assert (f->left_client_conn != NULL);
186 test_connection_setup (f->ctx, f->left_client_conn);
188 /* The left client connection is allowed to behave abusively. */
189 dbus_connection_set_max_message_unix_fds (f->left_client_conn, 1000);
190 dbus_connection_set_max_received_unix_fds (f->left_client_conn, 1000000);
192 while (f->left_server_conn == NULL)
195 test_main_context_iterate (f->ctx, TRUE);
198 f->right_client_conn = dbus_connection_open_private (address, &f->e);
199 assert_no_error (&f->e);
200 g_assert (f->right_client_conn != NULL);
201 test_connection_setup (f->ctx, f->right_client_conn);
205 while (f->right_server_conn == NULL)
208 test_main_context_iterate (f->ctx, TRUE);
211 if (!dbus_connection_add_filter (f->right_client_conn,
212 right_client_message_cb, f, NULL))
213 oom ("adding filter");
215 /* The right client connection is allowed to queue all the messages. */
216 dbus_connection_set_max_message_unix_fds (f->right_client_conn, 1000);
217 dbus_connection_set_max_received_unix_fds (f->right_client_conn, 1000000);
219 while (!dbus_connection_get_is_authenticated (f->left_client_conn) ||
220 !dbus_connection_get_is_authenticated (f->right_client_conn) ||
221 !dbus_connection_get_is_authenticated (f->left_server_conn) ||
222 !dbus_connection_get_is_authenticated (f->right_server_conn))
225 test_main_context_iterate (f->ctx, TRUE);
228 if (!dbus_connection_can_send_type (f->left_client_conn,
230 g_error ("left client connection cannot send Unix fds");
232 if (!dbus_connection_can_send_type (f->left_server_conn,
234 g_error ("left server connection cannot send Unix fds");
236 if (!dbus_connection_can_send_type (f->right_client_conn,
238 g_error ("right client connection cannot send Unix fds");
240 if (!dbus_connection_can_send_type (f->right_server_conn,
242 g_error ("right server connection cannot send Unix fds");
248 gconstpointer data G_GNUC_UNUSED)
250 #ifdef HAVE_UNIX_FD_PASSING
251 /* We assume that anything with fd-passing supports the unix: transport */
253 f->ctx = test_main_context_get ();
254 dbus_error_init (&f->e);
255 g_queue_init (&f->messages);
257 f->server = dbus_server_listen ("unix:tmpdir=/tmp", &f->e);
258 assert_no_error (&f->e);
259 g_assert (f->server != NULL);
261 dbus_server_set_new_connection_function (f->server,
262 new_conn_cb, f, NULL);
263 test_server_setup (f->ctx, f->server);
265 f->fd_before = open ("/dev/null", O_RDONLY);
267 /* this should succeed on any reasonable Unix */
268 if (f->fd_before < 0)
269 g_error ("cannot open /dev/null for reading: %s", g_strerror (errno));
271 _dbus_fd_set_close_on_exec (f->fd_before);
276 test_relay (Fixture *f,
279 #ifdef HAVE_UNIX_FD_PASSING
280 /* We assume that any platform with working fd-passing is POSIX,
281 * and therefore has open() and fstat() */
282 dbus_uint32_t serial;
283 DBusMessage *outgoing, *incoming;
285 struct stat stat_before;
286 struct stat stat_after;
288 test_connect (f, data);
290 outgoing = dbus_message_new_signal ("/com/example/Hello",
291 "com.example.Hello", "Greeting");
292 g_assert (outgoing != NULL);
294 if (!dbus_message_append_args (outgoing,
295 DBUS_TYPE_UNIX_FD, &f->fd_before,
297 oom ("appending fd");
299 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
300 oom ("sending message");
302 dbus_message_unref (outgoing);
304 while (g_queue_get_length (&f->messages) < 1)
307 test_main_context_iterate (f->ctx, TRUE);
310 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
312 incoming = g_queue_pop_head (&f->messages);
314 g_assert (dbus_message_contains_unix_fds (incoming));
315 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
316 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
317 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
318 "com.example.Hello");
319 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
320 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
321 g_assert_cmpstr (dbus_message_get_signature (incoming), ==,
322 DBUS_TYPE_UNIX_FD_AS_STRING);
323 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
324 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
326 if (!dbus_message_get_args (incoming,
328 DBUS_TYPE_UNIX_FD, &fd_after,
330 g_error ("%s: %s", f->e.name, f->e.message);
332 assert_no_error (&f->e);
334 if (fstat (f->fd_before, &stat_before) < 0)
335 g_error ("%s", g_strerror (errno));
337 if (fstat (fd_after, &stat_after) < 0)
338 g_error ("%s", g_strerror (errno));
340 /* this seems like enough to say "it's the same file" */
341 g_assert_cmpint (stat_before.st_dev, ==, stat_after.st_dev);
342 g_assert_cmpint (stat_before.st_ino, ==, stat_after.st_ino);
343 g_assert_cmpint (stat_before.st_rdev, ==, stat_after.st_rdev);
345 dbus_message_unref (incoming);
347 if (close (fd_after) < 0)
348 g_error ("%s", g_strerror (errno));
350 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
351 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
352 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
353 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
355 g_test_skip ("fd-passing not supported on this platform");
360 test_limit (Fixture *f,
363 #ifdef HAVE_UNIX_FD_PASSING
364 dbus_uint32_t serial;
365 DBusMessage *outgoing, *incoming;
368 test_connect (f, data);
370 outgoing = dbus_message_new_signal ("/com/example/Hello",
371 "com.example.Hello", "Greeting");
372 g_assert (outgoing != NULL);
374 for (i = 0; i < MAX_MESSAGE_UNIX_FDS; i++)
376 if (!dbus_message_append_args (outgoing,
377 DBUS_TYPE_UNIX_FD, &f->fd_before,
379 oom ("appending fd");
382 if (!dbus_connection_send (f->left_client_conn, outgoing, &serial))
383 oom ("sending message");
385 dbus_message_unref (outgoing);
387 while (g_queue_get_length (&f->messages) < 1)
390 test_main_context_iterate (f->ctx, TRUE);
393 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
395 incoming = g_queue_pop_head (&f->messages);
397 g_assert (dbus_message_contains_unix_fds (incoming));
398 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
399 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
400 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
401 "com.example.Hello");
402 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
403 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
404 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
405 g_assert_cmpuint (dbus_message_get_serial (incoming), ==, serial);
407 dbus_message_unref (incoming);
409 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
410 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
411 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
412 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
414 g_test_skip ("fd-passing not supported on this platform");
419 test_too_many (Fixture *f,
422 #ifdef HAVE_UNIX_FD_PASSING
423 DBusMessage *outgoing;
426 test_connect (f, data);
428 outgoing = dbus_message_new_signal ("/com/example/Hello",
429 "com.example.Hello", "Greeting");
430 g_assert (outgoing != NULL);
432 for (i = 0; i < MAX_MESSAGE_UNIX_FDS + GPOINTER_TO_UINT (data); i++)
434 if (!dbus_message_append_args (outgoing,
435 DBUS_TYPE_UNIX_FD, &f->fd_before,
437 oom ("appending fd");
440 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
441 oom ("sending message");
443 dbus_message_unref (outgoing);
445 /* The sender is unceremoniously disconnected. */
446 while (dbus_connection_get_is_connected (f->left_client_conn) ||
447 dbus_connection_get_is_connected (f->left_server_conn))
450 test_main_context_iterate (f->ctx, TRUE);
453 /* The message didn't get through without its fds. */
454 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
456 /* The intended victim is unaffected by the left connection's
458 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
459 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
461 g_test_skip ("fd-passing not supported on this platform");
466 test_too_many_split (Fixture *f,
469 #ifdef HAVE_UNIX_FD_PASSING
470 DBusMessage *outgoing;
472 DBusSocket left_client_socket;
476 int fds[TOO_MANY_FDS];
479 /* This test deliberately pushes up against OS limits, so skip it
480 * if we don't have enough fds. 4 times the maximum per message
481 * ought to be enough: that will cover the message, the dup'd fds
482 * we actually send, the copy that we potentially receive, and some
483 * spare capacity for everything else. */
484 #ifdef HAVE_GETRLIMIT
487 if (getrlimit (RLIMIT_NOFILE, &lim) == 0)
489 if (lim.rlim_cur != RLIM_INFINITY &&
490 lim.rlim_cur < 4 * TOO_MANY_FDS)
492 g_test_skip ("not enough RLIMIT_NOFILE");
498 test_connect (f, data);
500 outgoing = dbus_message_new_signal ("/com/example/Hello",
501 "com.example.Hello", "Greeting");
502 g_assert (outgoing != NULL);
504 /* TOO_MANY_FDS fds are far too many: in particular, Linux doesn't allow
505 * sending this many in a single sendmsg(). libdbus never splits
506 * a message between two sendmsg() calls if it can help it, and
507 * in particular it always sends all the fds with the first sendmsg(),
508 * but malicious senders might not be so considerate. */
509 for (i = 0; i < TOO_MANY_FDS; i++)
511 if (!dbus_message_append_args (outgoing,
512 DBUS_TYPE_UNIX_FD, &f->fd_before,
514 oom ("appending fd");
517 /* This probably shouldn't work for messages with fds, but it does,
518 * which is convenient for this sort of trickery. */
519 if (!dbus_message_marshal (outgoing, &payload, &payload_len))
520 oom ("marshalling message");
522 _dbus_string_init_const_len (&buffer, payload, payload_len);
524 for (i = 0; i < TOO_MANY_FDS; i++)
526 fds[i] = dup (f->fd_before);
529 g_error ("could not dup fd: %s", g_strerror (errno));
532 /* This is blatant cheating, and the API documentation specifically
533 * tells you not use this function in this way. Never do this
534 * in application code. */
535 if (!dbus_connection_get_socket (f->left_client_conn,
536 &left_client_socket.fd))
537 g_error ("'unix:' DBusConnection should have had a socket");
539 /* Just to be sure that we're at a message boundary. */
540 dbus_connection_flush (f->left_client_conn);
542 /* We have too many fds for one sendmsg(), so send the first half
543 * (rounding down if odd) with the first byte... */
544 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 0, 1,
545 &fds[0], TOO_MANY_FDS / 2);
548 g_error ("could not send first byte and first batch of fds: %s",
551 /* ... and the second half (rounding up if odd) with the rest of
553 done = _dbus_write_socket_with_unix_fds (left_client_socket, &buffer, 1,
554 payload_len - 1, &fds[TOO_MANY_FDS / 2],
555 TOO_MANY_FDS - (TOO_MANY_FDS / 2));
559 g_error ("could not send rest of message and rest of fds: %s",
562 else if (done < payload_len - 1)
564 /* For simplicity, assume the socket buffer is big enough for the
565 * whole message, which should be < 2 KiB. If this fails on some
566 * OS, redo this test code to use a proper loop like the real
568 g_error ("short write in sendmsg(), fix this test: %d/%d",
569 done, payload_len - 1);
574 for (i = 0; i < TOO_MANY_FDS; i++)
577 dbus_message_unref (outgoing);
579 /* The sender is unceremoniously disconnected. */
580 while (dbus_connection_get_is_connected (f->left_client_conn) ||
581 dbus_connection_get_is_connected (f->left_server_conn))
584 test_main_context_iterate (f->ctx, TRUE);
587 /* The message didn't get through without its fds. */
588 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
590 /* The intended victim is unaffected by the left connection's
592 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
593 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
595 g_test_skip ("fd-passing not supported on this platform");
600 test_flood (Fixture *f,
603 #ifdef HAVE_UNIX_FD_PASSING
605 DBusMessage *outgoing[SOME_MESSAGES];
606 dbus_uint32_t serial;
608 test_connect (f, data);
610 for (j = 0; j < SOME_MESSAGES; j++)
612 outgoing[j] = dbus_message_new_signal ("/com/example/Hello",
613 "com.example.Hello", "Greeting");
614 g_assert (outgoing[j] != NULL);
616 for (i = 0; i < GPOINTER_TO_UINT (data); i++)
618 if (!dbus_message_append_args (outgoing[j],
619 DBUS_TYPE_UNIX_FD, &f->fd_before,
621 oom ("appending fd");
625 /* This is in its own loop so we do it as fast as possible */
626 for (j = 0; j < SOME_MESSAGES; j++)
628 if (!dbus_connection_send (f->left_client_conn, outgoing[j], &serial))
629 oom ("sending message");
632 for (j = 0; j < SOME_MESSAGES; j++)
634 dbus_message_unref (outgoing[j]);
637 while (g_queue_get_length (&f->messages) < SOME_MESSAGES)
640 test_main_context_iterate (f->ctx, TRUE);
643 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, SOME_MESSAGES);
645 for (j = 0; j < SOME_MESSAGES; j++)
647 DBusMessage *incoming;
649 incoming = g_queue_pop_head (&f->messages);
651 g_assert (dbus_message_contains_unix_fds (incoming));
652 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
653 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
654 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
655 "com.example.Hello");
656 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
657 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
658 g_assert_cmpstr (dbus_message_get_path (incoming), ==, "/com/example/Hello");
660 dbus_message_unref (incoming);
663 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
664 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
665 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
666 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
668 g_test_skip ("fd-passing not supported on this platform");
673 test_odd_limit (Fixture *f,
676 #ifdef HAVE_UNIX_FD_PASSING
677 DBusMessage *outgoing;
680 test_connect (f, data);
681 dbus_connection_set_max_message_unix_fds (f->left_server_conn, 7);
682 dbus_connection_set_max_message_unix_fds (f->right_server_conn, 7);
684 outgoing = dbus_message_new_signal ("/com/example/Hello",
685 "com.example.Hello", "Greeting");
686 g_assert (outgoing != NULL);
688 for (i = 0; i < 7 + GPOINTER_TO_INT (data); i++)
690 if (!dbus_message_append_args (outgoing,
691 DBUS_TYPE_UNIX_FD, &f->fd_before,
693 oom ("appending fd");
696 if (!dbus_connection_send (f->left_client_conn, outgoing, NULL))
697 oom ("sending message");
699 dbus_message_unref (outgoing);
701 if (GPOINTER_TO_INT (data) > 0)
703 /* The sender is unceremoniously disconnected. */
704 while (dbus_connection_get_is_connected (f->left_client_conn) ||
705 dbus_connection_get_is_connected (f->left_server_conn))
708 test_main_context_iterate (f->ctx, TRUE);
711 /* The message didn't get through without its fds. */
712 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 0);
714 /* The intended victim is unaffected by the left connection's
716 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
717 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
721 DBusMessage *incoming;
723 /* We're at or under the limit. The message gets through intact. */
724 while (g_queue_get_length (&f->messages) < 1)
727 test_main_context_iterate (f->ctx, TRUE);
730 g_assert_cmpuint (g_queue_get_length (&f->messages), ==, 1);
732 incoming = g_queue_pop_head (&f->messages);
734 g_assert (dbus_message_contains_unix_fds (incoming));
735 g_assert_cmpstr (dbus_message_get_destination (incoming), ==, NULL);
736 g_assert_cmpstr (dbus_message_get_error_name (incoming), ==, NULL);
737 g_assert_cmpstr (dbus_message_get_interface (incoming), ==,
738 "com.example.Hello");
739 g_assert_cmpstr (dbus_message_get_member (incoming), ==, "Greeting");
740 g_assert_cmpstr (dbus_message_get_sender (incoming), ==, NULL);
741 g_assert_cmpstr (dbus_message_get_path (incoming), ==,
742 "/com/example/Hello");
744 dbus_message_unref (incoming);
746 g_assert (dbus_connection_get_is_connected (f->right_client_conn));
747 g_assert (dbus_connection_get_is_connected (f->right_server_conn));
748 g_assert (dbus_connection_get_is_connected (f->left_client_conn));
749 g_assert (dbus_connection_get_is_connected (f->left_server_conn));
752 g_test_skip ("fd-passing not supported on this platform");
757 teardown (Fixture *f,
758 gconstpointer data G_GNUC_UNUSED)
760 #ifdef HAVE_UNIX_FD_PASSING
761 if (f->left_client_conn != NULL)
763 dbus_connection_close (f->left_client_conn);
764 dbus_connection_unref (f->left_client_conn);
765 f->left_client_conn = NULL;
768 if (f->right_client_conn != NULL)
770 dbus_connection_close (f->right_client_conn);
771 dbus_connection_unref (f->right_client_conn);
772 f->right_client_conn = NULL;
775 if (f->left_server_conn != NULL)
777 dbus_connection_close (f->left_server_conn);
778 dbus_connection_unref (f->left_server_conn);
779 f->left_server_conn = NULL;
782 if (f->right_server_conn != NULL)
784 dbus_connection_close (f->right_server_conn);
785 dbus_connection_unref (f->right_server_conn);
786 f->right_server_conn = NULL;
789 if (f->server != NULL)
791 dbus_server_disconnect (f->server);
792 dbus_server_unref (f->server);
796 test_main_context_unref (f->ctx);
798 if (f->fd_before >= 0 && close (f->fd_before) < 0)
799 g_error ("%s", g_strerror (errno));
807 test_init (&argc, &argv);
809 #ifdef HAVE_GETRLIMIT
813 if (getrlimit (RLIMIT_NOFILE, &lim) < 0)
814 g_error ("Failed to get RLIMIT_NOFILE limit: %s", g_strerror (errno));
816 if (lim.rlim_cur != RLIM_INFINITY &&
817 /* only run if we have a fairly generous margin of error
818 * for stdout, stderr, duplicates, the D-Bus connection, etc. */
819 lim.rlim_cur < 2 * MAX_MESSAGE_UNIX_FDS * SOME_MESSAGES)
821 g_message ("not enough RLIMIT_NOFILE to run this test");
822 /* Autotools exit code for "all skipped" */
828 g_test_add ("/relay", Fixture, NULL, setup,
829 test_relay, teardown);
830 g_test_add ("/limit", Fixture, NULL, setup,
831 test_limit, teardown);
833 g_test_add ("/too-many/plus1", Fixture, GUINT_TO_POINTER (1), setup,
834 test_too_many, teardown);
835 g_test_add ("/too-many/plus2", Fixture, GUINT_TO_POINTER (2), setup,
836 test_too_many, teardown);
837 g_test_add ("/too-many/plus17", Fixture, GUINT_TO_POINTER (17), setup,
838 test_too_many, teardown);
840 g_test_add ("/too-many/split", Fixture, NULL, setup,
841 test_too_many_split, teardown);
843 g_test_add ("/flood/1", Fixture, GUINT_TO_POINTER (1),
844 setup, test_flood, teardown);
845 #if MAX_MESSAGE_UNIX_FDS >= 2
846 g_test_add ("/flood/half-limit", Fixture,
847 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS / 2),
848 setup, test_flood, teardown);
850 #if MAX_MESSAGE_UNIX_FDS >= 4
851 g_test_add ("/flood/over-half-limit", Fixture,
852 GUINT_TO_POINTER (3 * MAX_MESSAGE_UNIX_FDS / 4),
853 setup, test_flood, teardown);
855 g_test_add ("/flood/limit", Fixture,
856 GUINT_TO_POINTER (MAX_MESSAGE_UNIX_FDS), setup, test_flood, teardown);
858 g_test_add ("/odd-limit/minus1", Fixture, GINT_TO_POINTER (-1), setup,
859 test_odd_limit, teardown);
860 g_test_add ("/odd-limit/at", Fixture, GINT_TO_POINTER (0), setup,
861 test_odd_limit, teardown);
862 g_test_add ("/odd-limit/plus1", Fixture, GINT_TO_POINTER (+1), setup,
863 test_odd_limit, teardown);
864 g_test_add ("/odd-limit/plus2", Fixture, GINT_TO_POINTER (+2), setup,
865 test_odd_limit, teardown);
867 return g_test_run ();