X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-message-util.c;h=a5ce510644f898a3738d223cfada6c434a3a0641;hb=383f596c4aee2561c90abca3ce9d1f52407a3eec;hp=3d5a00f534a17f9bfa916c32f4c94076754d6e9b;hpb=bf2183345fbd19632e81b107593ca4e944d798de;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 3d5a00f..a5ce510 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -18,22 +18,34 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ +#include #include "dbus-internals.h" #include "dbus-test.h" #include "dbus-message-private.h" #include "dbus-marshal-recursive.h" #include "dbus-string.h" +#ifdef HAVE_UNIX_FD_PASSING +#include "dbus-sysdeps-unix.h" +#endif + +#ifdef __linux__ +/* Necessary for the Linux-specific fd leak checking code only */ +#include +#include +#include +#include +#endif /** * @addtogroup DBusMessage * @{ */ -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS /** * Reads arguments from a message iterator given a variable argument * list. Only arguments of basic type and arrays of fixed-length @@ -64,11 +76,11 @@ dbus_message_iter_get_args (DBusMessageIter *iter, return retval; } -#endif /* DBUS_BUILD_TESTS */ +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */ /** @} */ -#ifdef DBUS_BUILD_TESTS +#ifdef DBUS_ENABLE_EMBEDDED_TESTS #include "dbus-test.h" #include "dbus-message-factory.h" #include @@ -126,6 +138,111 @@ check_memleaks (void) } } +#ifdef __linux__ +struct DBusInitialFDs { + fd_set set; +}; +#endif + +DBusInitialFDs * +_dbus_check_fdleaks_enter (void) +{ +#ifdef __linux__ + DIR *d; + DBusInitialFDs *fds; + + /* this is plain malloc so it won't interfere with leak checking */ + fds = malloc (sizeof (DBusInitialFDs)); + _dbus_assert (fds != NULL); + + /* This works on Linux only */ + + if ((d = opendir ("/proc/self/fd"))) + { + struct dirent *de; + + while ((de = readdir(d))) + { + long l; + char *e = NULL; + int fd; + + if (de->d_name[0] == '.') + continue; + + errno = 0; + l = strtol (de->d_name, &e, 10); + _dbus_assert (errno == 0 && e && !*e); + + fd = (int) l; + + if (fd < 3) + continue; + + if (fd == dirfd (d)) + continue; + + FD_SET (fd, &fds->set); + } + + closedir (d); + } + + return fds; +#else + return NULL; +#endif +} + +void +_dbus_check_fdleaks_leave (DBusInitialFDs *fds) +{ +#ifdef __linux__ + DIR *d; + + /* This works on Linux only */ + + if ((d = opendir ("/proc/self/fd"))) + { + struct dirent *de; + + while ((de = readdir(d))) + { + long l; + char *e = NULL; + int fd; + + if (de->d_name[0] == '.') + continue; + + errno = 0; + l = strtol (de->d_name, &e, 10); + _dbus_assert (errno == 0 && e && !*e); + + fd = (int) l; + + if (fd < 3) + continue; + + if (fd == dirfd (d)) + continue; + + if (FD_ISSET (fd, &fds->set)) + continue; + + _dbus_warn ("file descriptor %i leaked in %s.\n", fd, __FILE__); + _dbus_assert_not_reached ("fdleaks"); + } + + closedir (d); + } + + free (fds); +#else + _dbus_assert (fds == NULL); +#endif +} + static dbus_bool_t check_have_valid_message (DBusMessageLoader *loader) { @@ -502,8 +619,8 @@ process_test_subdir (const DBusString *test_base_dir, { if (_dbus_string_ends_with_c_str (&filename, ".message")) { - _dbus_warn ("Could not load %s, message builder language no longer supported\n", - _dbus_string_get_const_data (&filename)); + printf ("SKIP: Could not load %s, message builder language no longer supported\n", + _dbus_string_get_const_data (&filename)); } _dbus_verbose ("Skipping non-.message file %s\n", @@ -895,7 +1012,7 @@ verify_test_message (DBusMessage *message) dbus_bool_t _dbus_message_test (const char *test_data_dir) { - DBusMessage *message; + DBusMessage *message, *message_without_unix_fds; DBusMessageLoader *loader; int i; const char *data; @@ -940,6 +1057,13 @@ _dbus_message_test (const char *test_data_dir) unsigned char v2_BYTE; dbus_bool_t v_BOOLEAN; DBusMessageIter iter, array_iter, struct_iter; +#ifdef HAVE_UNIX_FD_PASSING + int v_UNIX_FD; +#endif + char **decomposed; + DBusInitialFDs *initial_fds; + + initial_fds = _dbus_check_fdleaks_enter (); message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", "/org/freedesktop/TestPath", @@ -1035,6 +1159,34 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (strcmp (dbus_message_get_member (message), "Bar") == 0); + /* Path decomposing */ + dbus_message_set_path (message, NULL); + dbus_message_get_path_decomposed (message, &decomposed); + _dbus_assert (decomposed == NULL); + dbus_free_string_array (decomposed); + + dbus_message_set_path (message, "/"); + dbus_message_get_path_decomposed (message, &decomposed); + _dbus_assert (decomposed != NULL); + _dbus_assert (decomposed[0] == NULL); + dbus_free_string_array (decomposed); + + dbus_message_set_path (message, "/a/b"); + dbus_message_get_path_decomposed (message, &decomposed); + _dbus_assert (decomposed != NULL); + _dbus_assert (strcmp (decomposed[0], "a") == 0); + _dbus_assert (strcmp (decomposed[1], "b") == 0); + _dbus_assert (decomposed[2] == NULL); + dbus_free_string_array (decomposed); + + dbus_message_set_path (message, "/spam/eggs"); + dbus_message_get_path_decomposed (message, &decomposed); + _dbus_assert (decomposed != NULL); + _dbus_assert (strcmp (decomposed[0], "spam") == 0); + _dbus_assert (strcmp (decomposed[1], "eggs") == 0); + _dbus_assert (decomposed[2] == NULL); + dbus_free_string_array (decomposed); + dbus_message_unref (message); /* Test the vararg functions */ @@ -1058,6 +1210,9 @@ _dbus_message_test (const char *test_data_dir) v_BOOLEAN = TRUE; v_BYTE = 42; v2_BYTE = 24; +#ifdef HAVE_UNIX_FD_PASSING + v_UNIX_FD = 1; +#endif dbus_message_append_args (message, DBUS_TYPE_INT16, &v_INT16, @@ -1091,6 +1246,7 @@ _dbus_message_test (const char *test_data_dir) _DBUS_N_ELEMENTS (our_boolean_array), DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, _DBUS_N_ELEMENTS (our_string_array), + DBUS_TYPE_INVALID); i = 0; @@ -1125,7 +1281,16 @@ _dbus_message_test (const char *test_data_dir) sig[i++] = DBUS_TYPE_BOOLEAN; sig[i++] = DBUS_TYPE_ARRAY; sig[i++] = DBUS_TYPE_STRING; - sig[i++] = DBUS_TYPE_INVALID; + + message_without_unix_fds = dbus_message_copy(message); + _dbus_assert(message_without_unix_fds); +#ifdef HAVE_UNIX_FD_PASSING + dbus_message_append_args (message, + DBUS_TYPE_UNIX_FD, &v_UNIX_FD, + DBUS_TYPE_INVALID); + sig[i++] = DBUS_TYPE_UNIX_FD; +#endif + sig[i++] = DBUS_TYPE_INVALID; _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); @@ -1202,6 +1367,20 @@ _dbus_message_test (const char *test_data_dir) _dbus_message_loader_return_buffer (loader, buffer, 1); } +#ifdef HAVE_UNIX_FD_PASSING + { + int *unix_fds; + unsigned n_unix_fds; + /* Write unix fd */ + _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); + _dbus_assert(n_unix_fds > 0); + _dbus_assert(message->n_unix_fds == 1); + unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); + _dbus_assert(unix_fds[0] >= 0); + _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); + } +#endif + dbus_message_unref (message); /* Now pop back the message */ @@ -1218,7 +1397,14 @@ _dbus_message_test (const char *test_data_dir) if (dbus_message_get_reply_serial (message) != 5678) _dbus_assert_not_reached ("reply serial fields differ"); - verify_test_message (message); + dbus_message_unref (message); + + /* ovveride the serial, since it was reset by dbus_message_copy() */ + dbus_message_set_serial(message_without_unix_fds, 8901); + + dbus_message_lock (message_without_unix_fds); + + verify_test_message (message_without_unix_fds); { /* Marshal and demarshal the message. */ @@ -1229,7 +1415,7 @@ _dbus_message_test (const char *test_data_dir) int len = 0; char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; - if (!dbus_message_marshal (message, &marshalled, &len)) + if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) _dbus_assert_not_reached ("failed to marshal message"); _dbus_assert (len != 0); @@ -1268,10 +1454,12 @@ _dbus_message_test (const char *test_data_dir) _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); } - dbus_message_unref (message); + dbus_message_unref (message_without_unix_fds); _dbus_message_loader_unref (loader); check_memleaks (); + _dbus_check_fdleaks_leave (initial_fds); + initial_fds = _dbus_check_fdleaks_enter (); /* Check that we can abandon a container */ message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", @@ -1296,8 +1484,8 @@ _dbus_message_test (const char *test_data_dir) /* uh-oh, error, try and unwind */ - _dbus_assert (dbus_message_iter_close_container (&array_iter, &struct_iter)); - _dbus_assert (dbus_message_iter_close_container (&array_iter, &iter)); + dbus_message_iter_abandon_container (&array_iter, &struct_iter); + dbus_message_iter_abandon_container (&array_iter, &iter); dbus_message_unref (message); @@ -1333,17 +1521,25 @@ _dbus_message_test (const char *test_data_dir) print_validities_seen (FALSE); print_validities_seen (TRUE); } - + check_memleaks (); - + _dbus_check_fdleaks_leave (initial_fds); + /* Now load every message in test_data_dir if we have one */ if (test_data_dir == NULL) return TRUE; - return dbus_internal_do_not_use_foreach_message_file (test_data_dir, + initial_fds = _dbus_check_fdleaks_enter (); + + if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir, (DBusForeachMessageFileFunc) dbus_internal_do_not_use_try_message_file, - NULL); + NULL)) + _dbus_assert_not_reached ("foreach_message_file test failed"); + + _dbus_check_fdleaks_leave (initial_fds); + + return TRUE; } -#endif /* DBUS_BUILD_TESTS */ +#endif /* DBUS_ENABLE_EMBEDDED_TESTS */