1/*
2 * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19 /* Description:
20 *   Verify that:
21 *		1) kcmp fails with bad pid
22 *		2) kcmp fails with invalid flag
23 *		3) kcmp fails with invalid flag
24 *		4) kcmp fails with invalid flag
25 *		5) kcmp fails with invalid flag
26 *		6) kcmp fails with invalid fd
27 */
28
29#define _GNU_SOURCE
30
31#include "tst_test.h"
32#include "lapi/fcntl.h"
33#include "kcmp.h"
34
35#define TEST_FILE "test_file"
36#define TEST_FILE2 "test_file2"
37
38static int fd1;
39static int fd2;
40static int fd_fake;
41static int pid1;
42static int pid_unused;
43static int fd_fake = -1;
44
45#include <sys/types.h>
46#include <sys/wait.h>
47#include <limits.h>
48
49static struct test_case {
50	int *pid1;
51	int *pid2;
52	int type;
53	int *fd1;
54	int *fd2;
55	int exp_errno;
56} test_cases[] = {
57	{&pid1, &pid_unused, KCMP_FILE, &fd1, &fd2, ESRCH},
58	{&pid1, &pid1, KCMP_TYPES + 1, &fd1, &fd2, EINVAL},
59	{&pid1, &pid1, -1, &fd1, &fd2, EINVAL},
60	{&pid1, &pid1, INT_MIN, &fd1, &fd2, EINVAL},
61	{&pid1, &pid1, INT_MAX, &fd1, &fd2, EINVAL},
62	{&pid1, &pid1, KCMP_FILE, &fd1, &fd_fake, EBADF}
63};
64
65static void setup(void)
66{
67	pid1 = getpid();
68	pid_unused = tst_get_unused_pid();
69
70	fd1 = SAFE_OPEN(TEST_FILE, O_CREAT | O_RDWR | O_TRUNC);
71	fd2 = SAFE_OPEN(TEST_FILE2, O_CREAT | O_RDWR | O_TRUNC);
72}
73
74static void cleanup(void)
75{
76	if (fd1 > 0)
77		SAFE_CLOSE(fd1);
78
79	if (fd2 > 0)
80		SAFE_CLOSE(fd2);
81}
82
83static void verify_kcmp(unsigned int n)
84{
85	struct test_case *test = &test_cases[n];
86
87	TEST(kcmp(*(test->pid1), *(test->pid2), test->type,
88		  *(test->fd1), *(test->fd2)));
89
90	if (TEST_RETURN != -1) {
91		tst_res(TFAIL, "kcmp() succeeded unexpectedly");
92		return;
93	}
94
95	if (test->exp_errno == TEST_ERRNO) {
96		tst_res(TPASS | TTERRNO, "kcmp() returned the expected value");
97		return;
98	}
99
100	tst_res(TFAIL | TTERRNO,
101		"kcmp() got unexpected return value: expected: %d - %s",
102			test->exp_errno, tst_strerrno(test->exp_errno));
103}
104
105static struct tst_test test = {
106	.tcnt = ARRAY_SIZE(test_cases),
107	.setup = setup,
108	.cleanup = cleanup,
109	.test = verify_kcmp,
110	.min_kver = "3.5.0",
111	.needs_tmpdir = 1
112};
113