root/tools/testing/selftests/kcmp/kcmp_test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_kcmp
  2. main

   1 // SPDX-License-Identifier: GPL-2.0
   2 #define _GNU_SOURCE
   3 
   4 #include <stdio.h>
   5 #include <stdlib.h>
   6 #include <signal.h>
   7 #include <limits.h>
   8 #include <unistd.h>
   9 #include <errno.h>
  10 #include <string.h>
  11 #include <fcntl.h>
  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 #include <sys/epoll.h>
  20 
  21 #include "../kselftest.h"
  22 
  23 static long sys_kcmp(int pid1, int pid2, int type, unsigned long fd1, unsigned long fd2)
  24 {
  25         return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2);
  26 }
  27 
  28 static const unsigned int duped_num = 64;
  29 
  30 int main(int argc, char **argv)
  31 {
  32         const char kpath[] = "kcmp-test-file";
  33         struct kcmp_epoll_slot epoll_slot;
  34         struct epoll_event ev;
  35         int pid1, pid2;
  36         int pipefd[2];
  37         int fd1, fd2;
  38         int epollfd;
  39         int status;
  40         int fddup;
  41 
  42         fd1 = open(kpath, O_RDWR | O_CREAT | O_TRUNC, 0644);
  43         pid1 = getpid();
  44 
  45         if (fd1 < 0) {
  46                 perror("Can't create file");
  47                 ksft_exit_fail();
  48         }
  49 
  50         if (pipe(pipefd)) {
  51                 perror("Can't create pipe");
  52                 ksft_exit_fail();
  53         }
  54 
  55         epollfd = epoll_create1(0);
  56         if (epollfd < 0) {
  57                 perror("epoll_create1 failed");
  58                 ksft_exit_fail();
  59         }
  60 
  61         memset(&ev, 0xff, sizeof(ev));
  62         ev.events = EPOLLIN | EPOLLOUT;
  63 
  64         if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd[0], &ev)) {
  65                 perror("epoll_ctl failed");
  66                 ksft_exit_fail();
  67         }
  68 
  69         fddup = dup2(pipefd[1], duped_num);
  70         if (fddup < 0) {
  71                 perror("dup2 failed");
  72                 ksft_exit_fail();
  73         }
  74 
  75         if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fddup, &ev)) {
  76                 perror("epoll_ctl failed");
  77                 ksft_exit_fail();
  78         }
  79         close(fddup);
  80 
  81         pid2 = fork();
  82         if (pid2 < 0) {
  83                 perror("fork failed");
  84                 ksft_exit_fail();
  85         }
  86 
  87         if (!pid2) {
  88                 int pid2 = getpid();
  89                 int ret;
  90 
  91                 fd2 = open(kpath, O_RDWR, 0644);
  92                 if (fd2 < 0) {
  93                         perror("Can't open file");
  94                         ksft_exit_fail();
  95                 }
  96 
  97                 /* An example of output and arguments */
  98                 printf("pid1: %6d pid2: %6d FD: %2ld FILES: %2ld VM: %2ld "
  99                        "FS: %2ld SIGHAND: %2ld IO: %2ld SYSVSEM: %2ld "
 100                        "INV: %2ld\n",
 101                        pid1, pid2,
 102                        sys_kcmp(pid1, pid2, KCMP_FILE,          fd1, fd2),
 103                        sys_kcmp(pid1, pid2, KCMP_FILES,         0, 0),
 104                        sys_kcmp(pid1, pid2, KCMP_VM,            0, 0),
 105                        sys_kcmp(pid1, pid2, KCMP_FS,            0, 0),
 106                        sys_kcmp(pid1, pid2, KCMP_SIGHAND,       0, 0),
 107                        sys_kcmp(pid1, pid2, KCMP_IO,            0, 0),
 108                        sys_kcmp(pid1, pid2, KCMP_SYSVSEM,       0, 0),
 109 
 110                         /* This one should fail */
 111                        sys_kcmp(pid1, pid2, KCMP_TYPES + 1,     0, 0));
 112 
 113                 /* This one should return same fd */
 114                 ret = sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd1);
 115                 if (ret) {
 116                         printf("FAIL: 0 expected but %d returned (%s)\n",
 117                                 ret, strerror(errno));
 118                         ksft_inc_fail_cnt();
 119                         ret = -1;
 120                 } else {
 121                         printf("PASS: 0 returned as expected\n");
 122                         ksft_inc_pass_cnt();
 123                 }
 124 
 125                 /* Compare with self */
 126                 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);
 127                 if (ret) {
 128                         printf("FAIL: 0 expected but %d returned (%s)\n",
 129                                 ret, strerror(errno));
 130                         ksft_inc_fail_cnt();
 131                         ret = -1;
 132                 } else {
 133                         printf("PASS: 0 returned as expected\n");
 134                         ksft_inc_pass_cnt();
 135                 }
 136 
 137                 /* Compare epoll target */
 138                 epoll_slot = (struct kcmp_epoll_slot) {
 139                         .efd    = epollfd,
 140                         .tfd    = duped_num,
 141                         .toff   = 0,
 142                 };
 143                 ret = sys_kcmp(pid1, pid1, KCMP_EPOLL_TFD, pipefd[1],
 144                                (unsigned long)(void *)&epoll_slot);
 145                 if (ret) {
 146                         printf("FAIL: 0 expected but %d returned (%s)\n",
 147                                 ret, strerror(errno));
 148                         ksft_inc_fail_cnt();
 149                         ret = -1;
 150                 } else {
 151                         printf("PASS: 0 returned as expected\n");
 152                         ksft_inc_pass_cnt();
 153                 }
 154 
 155                 ksft_print_cnts();
 156 
 157                 if (ret)
 158                         ksft_exit_fail();
 159                 else
 160                         ksft_exit_pass();
 161         }
 162 
 163         waitpid(pid2, &status, P_ALL);
 164 
 165         return ksft_exit_pass();
 166 }

/* [<][>][^][v][top][bottom][index][help] */