tests: support testing fd inheritance over exec

Add facility for testing how (many) file descriptors survive an exec.
This allows implementing O_CLOEXEC tests.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
This commit is contained in:
Pekka Paalanen 2012-04-20 14:22:51 +03:00
parent 7c0aa1a4a3
commit da6b1a8e47
5 changed files with 124 additions and 4 deletions

View file

@ -1,7 +1,4 @@
TESTS = $(check_PROGRAMS)
check_PROGRAMS = \
my_check_programs = \
sanity-test \
array-test \
map-test \
@ -10,6 +7,12 @@ check_PROGRAMS = \
event-loop-test \
client-test
TESTS = $(my_check_programs)
check_PROGRAMS = \
$(my_check_programs) \
exec-fd-leak-checker
test_runner_src = test-runner.c test-runner.h test-helpers.c
sanity_test_SOURCES = sanity-test.c $(test_runner_src)
@ -25,3 +28,8 @@ LDADD = $(top_builddir)/src/libwayland-util.la \
$(top_builddir)/src/libwayland-server.la \
-lrt -ldl $(FFI_LIBS)
exec_fd_leak_checker_SOURCES = \
exec-fd-leak-checker.c \
test-runner.h \
test-helpers.c
exec_fd_leak_checker_LDADD =

View file

@ -0,0 +1,75 @@
/*
* Copyright © 2012 Collabora, Ltd.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include "test-runner.h"
static int
parse_count(const char *str, int *value)
{
char *end;
long v;
errno = 0;
v = strtol(str, &end, 0);
if ((errno == ERANGE && (v == LONG_MAX || v == LONG_MIN)) ||
(errno != 0 && v == 0) ||
(end == str) ||
(*end != '\0')) {
return -1;
}
if (v < 0 || v > INT_MAX) {
return -1;
}
*value = v;
return 0;
}
int main(int argc, char *argv[])
{
int expected;
if (argc != 2)
goto help_out;
if (parse_count(argv[1], &expected) < 0)
goto help_out;
if (count_open_fds() == expected)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
help_out:
fprintf(stderr, "Usage: %s N\n"
"where N is the expected number of open file descriptors.\n"
"This program exits with a failure if the number "
"does not match exactly.\n", argv[0]);
return EXIT_FAILURE;
}

View file

@ -93,3 +93,25 @@ FAIL_TEST(sanity_fd_leak)
/* leak 2 file descriptors */
pipe(fd);
}
FAIL_TEST(sanity_fd_leak_exec)
{
int fd[2];
int nr_fds = count_open_fds();
/* leak 2 file descriptors */
pipe(fd);
exec_fd_leak_check(nr_fds);
}
TEST(sanity_fd_exec)
{
int fd[2];
int nr_fds = count_open_fds();
/* create 2 file descriptors, that should pass over exec */
pipe(fd);
exec_fd_leak_check(nr_fds + 2);
}

View file

@ -23,6 +23,8 @@
#include <assert.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include "test-runner.h"
@ -50,3 +52,13 @@ count_open_fds(void)
return count;
}
void
exec_fd_leak_check(int nr_expected_fds)
{
const char *exe = "./exec-fd-leak-checker";
char number[16] = { 0 };
snprintf(number, sizeof number - 1, "%d", nr_expected_fds);
execl(exe, exe, number, (char *)NULL);
assert(0 && "execing fd leak checker failed");
}

View file

@ -34,4 +34,7 @@ struct test {
int
count_open_fds(void);
void
exec_fd_leak_check(int nr_expected_fds); /* never returns */
#endif