1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2015 Cedric Hnyda <chnyda@suse.com> 4 */ 5 6 /* Description: 7 * Verify that: 8 * 1) kcmp returns 0 with two process and two fd refering to the 9 * same open file 10 * 2) kcmp doesn't return 0 with two process and two fd not 11 * refering to the same open file 12 */ 13 14#define _GNU_SOURCE 15 16#include "tst_test.h" 17#include "lapi/fcntl.h" 18#include "lapi/kcmp.h" 19 20#define TEST_FILE "test_file" 21#define TEST_FILE2 "test_file2" 22 23static int fd1; 24static int fd2; 25static int fd3; 26static int pid1; 27static int pid2; 28 29static struct test_case { 30 int *pid1; 31 int *pid2; 32 int type; 33 int *fd1; 34 int *fd2; 35 int exp_different; 36} test_cases[] = { 37 {&pid1, &pid1, KCMP_FILE, &fd1, &fd1, 0}, 38 {&pid2, &pid2, KCMP_FILE, &fd1, &fd2, 0}, 39 {&pid1, &pid2, KCMP_FILE, &fd1, &fd1, 0}, 40 {&pid1, &pid2, KCMP_FILE, &fd1, &fd2, 0}, 41 {&pid1, &pid2, KCMP_FILE, &fd1, &fd3, 1}, 42}; 43 44static void setup(void) 45{ 46 fd1 = SAFE_OPEN(TEST_FILE, O_CREAT | O_RDWR | O_TRUNC, 0666); 47} 48 49static void cleanup(void) 50{ 51 if (fd1 > 0) 52 SAFE_CLOSE(fd1); 53} 54 55static void do_child(const struct test_case *test) 56{ 57 pid2 = getpid(); 58 59 fd3 = SAFE_OPEN(TEST_FILE2, O_CREAT | O_RDWR, 0666); 60 61 fd2 = dup(fd1); 62 if (fd2 == -1) { 63 tst_res(TFAIL | TERRNO, "dup() failed unexpectedly"); 64 SAFE_CLOSE(fd3); 65 return; 66 } 67 68 TEST(kcmp(*(test->pid1), *(test->pid2), test->type, 69 *(test->fd1), *(test->fd2))); 70 71 SAFE_CLOSE(fd2); 72 SAFE_CLOSE(fd3); 73 74 if (TST_RET == -1) { 75 tst_res(TFAIL | TTERRNO, "kcmp() failed unexpectedly"); 76 return; 77 } 78 79 if ((test->exp_different && TST_RET == 0) 80 || (test->exp_different == 0 && TST_RET)) { 81 tst_res(TFAIL, "kcmp() returned %lu instead of %d", 82 TST_RET, test->exp_different); 83 return; 84 } 85 86 tst_res(TPASS, "kcmp() returned the expected value"); 87} 88 89static void verify_kcmp(unsigned int n) 90{ 91 struct test_case *tc = &test_cases[n]; 92 93 pid1 = getpid(); 94 95 pid2 = SAFE_FORK(); 96 if (!pid2) 97 do_child(tc); 98} 99 100static struct tst_test test = { 101 .tcnt = ARRAY_SIZE(test_cases), 102 .setup = setup, 103 .cleanup = cleanup, 104 .forks_child = 1, 105 .test = verify_kcmp, 106 .needs_tmpdir = 1, 107}; 108