Commit e4abc1d1 authored by Simon McVittie's avatar Simon McVittie

Don't report file descriptors as "leaked" if they were already open

This is necessary to run the regression tests under valgrind (if
telling it to output to a dedicated fd), gdb, fakeroot etc.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=35173Reviewed-by: Colin Walters's avatarColin Walters <walters@verbum.org>
parent 614ea05b
......@@ -54,6 +54,8 @@ check_memleaks (const char *name)
}
#endif /* DBUS_BUILD_TESTS */
static DBusInitialFDs *initial_fds = NULL;
static void
test_pre_hook (void)
{
......@@ -62,16 +64,21 @@ test_pre_hook (void)
&& (!bus_selinux_pre_init ()
|| !bus_selinux_full_init ()))
die ("could not init selinux support");
initial_fds = _dbus_check_fdleaks_enter ();
}
static char *progname = "";
static void
test_post_hook (void)
{
if (_dbus_getenv ("DBUS_TEST_SELINUX"))
bus_selinux_shutdown ();
check_memleaks (progname);
_dbus_check_fdleaks();
_dbus_check_fdleaks_leave (initial_fds);
initial_fds = NULL;
}
int
......
......@@ -138,8 +138,9 @@ dbus_bool_t _dbus_message_iter_get_args_valist (DBusMessageIter *iter,
int first_arg_type,
va_list var_args);
void _dbus_check_fdleaks(void);
typedef struct DBusInitialFDs DBusInitialFDs;
DBusInitialFDs *_dbus_check_fdleaks_enter (void);
void _dbus_check_fdleaks_leave (DBusInitialFDs *fds);
/** @} */
......
......@@ -138,12 +138,66 @@ check_memleaks (void)
}
}
void
_dbus_check_fdleaks(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 */
......@@ -173,12 +227,19 @@ _dbus_check_fdleaks(void)
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
}
......@@ -1000,6 +1061,9 @@ _dbus_message_test (const char *test_data_dir)
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",
......@@ -1394,7 +1458,8 @@ _dbus_message_test (const char *test_data_dir)
_dbus_message_loader_unref (loader);
check_memleaks ();
_dbus_check_fdleaks();
_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",
......@@ -1458,16 +1523,23 @@ _dbus_message_test (const char *test_data_dir)
}
check_memleaks ();
_dbus_check_fdleaks();
_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 */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment