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 
38 static int fd1;
39 static int fd2;
40 static int fd_fake;
41 static int pid1;
42 static int pid_unused;
43 static int fd_fake = -1;
44 
45 #include <sys/types.h>
46 #include <sys/wait.h>
47 #include <limits.h>
48 
49 static 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 
setup(void)65 static 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 
cleanup(void)74 static void cleanup(void)
75 {
76 	if (fd1 > 0)
77 		SAFE_CLOSE(fd1);
78 
79 	if (fd2 > 0)
80 		SAFE_CLOSE(fd2);
81 }
82 
verify_kcmp(unsigned int n)83 static 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 
105 static 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