brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · d7a8e32 Raw
169 lines · c
1// SPDX-License-Identifier: GPL-2.02#define _GNU_SOURCE3 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 23static 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 28static const unsigned int duped_num = 64;29 30int 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		ksft_print_header();92		ksft_set_plan(3);93 94		fd2 = open(kpath, O_RDWR);95		if (fd2 < 0) {96			perror("Can't open file");97			ksft_exit_fail();98		}99 100		/* An example of output and arguments */101		printf("pid1: %6d pid2: %6d FD: %2ld FILES: %2ld VM: %2ld "102		       "FS: %2ld SIGHAND: %2ld IO: %2ld SYSVSEM: %2ld "103		       "INV: %2ld\n",104		       pid1, pid2,105		       sys_kcmp(pid1, pid2, KCMP_FILE,		fd1, fd2),106		       sys_kcmp(pid1, pid2, KCMP_FILES,		0, 0),107		       sys_kcmp(pid1, pid2, KCMP_VM,		0, 0),108		       sys_kcmp(pid1, pid2, KCMP_FS,		0, 0),109		       sys_kcmp(pid1, pid2, KCMP_SIGHAND,	0, 0),110		       sys_kcmp(pid1, pid2, KCMP_IO,		0, 0),111		       sys_kcmp(pid1, pid2, KCMP_SYSVSEM,	0, 0),112 113			/* This one should fail */114		       sys_kcmp(pid1, pid2, KCMP_TYPES + 1,	0, 0));115 116		/* This one should return same fd */117		ret = sys_kcmp(pid1, pid2, KCMP_FILE, fd1, fd1);118		if (ret) {119			printf("FAIL: 0 expected but %d returned (%s)\n",120				ret, strerror(errno));121			ksft_inc_fail_cnt();122			ret = -1;123		} else {124			printf("PASS: 0 returned as expected\n");125			ksft_inc_pass_cnt();126		}127 128		/* Compare with self */129		ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);130		if (ret) {131			printf("FAIL: 0 expected but %d returned (%s)\n",132				ret, strerror(errno));133			ksft_inc_fail_cnt();134			ret = -1;135		} else {136			printf("PASS: 0 returned as expected\n");137			ksft_inc_pass_cnt();138		}139 140		/* Compare epoll target */141		epoll_slot = (struct kcmp_epoll_slot) {142			.efd	= epollfd,143			.tfd	= duped_num,144			.toff	= 0,145		};146		ret = sys_kcmp(pid1, pid1, KCMP_EPOLL_TFD, pipefd[1],147			       (unsigned long)(void *)&epoll_slot);148		if (ret) {149			printf("FAIL: 0 expected but %d returned (%s)\n",150				ret, strerror(errno));151			ksft_inc_fail_cnt();152			ret = -1;153		} else {154			printf("PASS: 0 returned as expected\n");155			ksft_inc_pass_cnt();156		}157 158 159		if (ret)160			ksft_exit_fail();161		else162			ksft_exit_pass();163	}164 165	waitpid(pid2, &status, P_ALL);166 167	return 0;168}169