diff options
Diffstat (limited to 'tools/testing/selftests/kcmp/kcmp_test.c')
-rw-r--r-- | tools/testing/selftests/kcmp/kcmp_test.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c new file mode 100644 index 000000000000..358cc6bfa35d --- /dev/null +++ b/tools/testing/selftests/kcmp/kcmp_test.c | |||
@@ -0,0 +1,94 @@ | |||
1 | #define _GNU_SOURCE | ||
2 | |||
3 | #include <stdio.h> | ||
4 | #include <stdlib.h> | ||
5 | #include <signal.h> | ||
6 | #include <limits.h> | ||
7 | #include <unistd.h> | ||
8 | #include <errno.h> | ||
9 | #include <string.h> | ||
10 | #include <fcntl.h> | ||
11 | |||
12 | #include <linux/unistd.h> | ||
13 | #include <linux/kcmp.h> | ||
14 | |||
15 | #include <sys/syscall.h> | ||
16 | #include <sys/types.h> | ||
17 | #include <sys/stat.h> | ||
18 | #include <sys/wait.h> | ||
19 | |||
20 | static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2) | ||
21 | { | ||
22 | return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2); | ||
23 | } | ||
24 | |||
25 | int main(int argc, char **argv) | ||
26 | { | ||
27 | const char kpath[] = "kcmp-test-file"; | ||
28 | int pid1, pid2; | ||
29 | int fd1, fd2; | ||
30 | int status; | ||
31 | |||
32 | fd1 = open(kpath, O_RDWR | O_CREAT | O_TRUNC, 0644); | ||
33 | pid1 = getpid(); | ||
34 | |||
35 | if (fd1 < 0) { | ||
36 | perror("Can't create file"); | ||
37 | exit(1); | ||
38 | } | ||
39 | |||
40 | pid2 = fork(); | ||
41 | if (pid2 < 0) { | ||
42 | perror("fork failed"); | ||
43 | exit(1); | ||
44 | } | ||
45 | |||
46 | if (!pid2) { | ||
47 | int pid2 = getpid(); | ||
48 | int ret; | ||
49 | |||
50 | fd2 = open(kpath, O_RDWR, 0644); | ||
51 | if (fd2 < 0) { | ||
52 | perror("Can't open file"); | ||
53 | exit(1); | ||
54 | } | ||
55 | |||
56 | /* An example of output and arguments */ | ||
57 | printf("pid1: %6d pid2: %6d FD: %2ld FILES: %2ld VM: %2ld " | ||
58 | "FS: %2ld SIGHAND: %2ld IO: %2ld SYSVSEM: %2ld " | ||
59 | "INV: %2ld\n", | ||
60 | pid1, pid2, | ||
61 | sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd2), | ||
62 | sys_kcmp(pid1, pid2, KCMP_FILES, 0, 0), | ||
63 | sys_kcmp(pid1, pid2, KCMP_VM, 0, 0), | ||
64 | sys_kcmp(pid1, pid2, KCMP_FS, 0, 0), | ||
65 | sys_kcmp(pid1, pid2, KCMP_SIGHAND, 0, 0), | ||
66 | sys_kcmp(pid1, pid2, KCMP_IO, 0, 0), | ||
67 | sys_kcmp(pid1, pid2, KCMP_SYSVSEM, 0, 0), | ||
68 | |||
69 | /* This one should fail */ | ||
70 | sys_kcmp(pid1, pid2, KCMP_TYPES + 1, 0, 0)); | ||
71 | |||
72 | /* This one should return same fd */ | ||
73 | ret = sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd1); | ||
74 | if (ret) { | ||
75 | printf("FAIL: 0 expected but %d returned\n", ret); | ||
76 | ret = -1; | ||
77 | } else | ||
78 | printf("PASS: 0 returned as expected\n"); | ||
79 | |||
80 | /* Compare with self */ | ||
81 | ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0); | ||
82 | if (ret) { | ||
83 | printf("FAIL: 0 expected but %li returned\n", ret); | ||
84 | ret = -1; | ||
85 | } else | ||
86 | printf("PASS: 0 returned as expected\n"); | ||
87 | |||
88 | exit(ret); | ||
89 | } | ||
90 | |||
91 | waitpid(pid2, &status, P_ALL); | ||
92 | |||
93 | return 0; | ||
94 | } | ||