1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2016 Xiao Yang <yangx.jy@cn.fujitsu.com>
4f08c3bdfSopenharmony_ci */
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci /*
7f08c3bdfSopenharmony_ci * Testname: kcmp03.c
8f08c3bdfSopenharmony_ci *
9f08c3bdfSopenharmony_ci * Description:
10f08c3bdfSopenharmony_ci * 1) kcmp() returns 0 if the processes share the same file system information.
11f08c3bdfSopenharmony_ci * 2) kcmp() returns 0 if the processes share I/O context.
12f08c3bdfSopenharmony_ci * 3) kcmp() returns 0 if the processes share the same list of System V
13f08c3bdfSopenharmony_ci *    semaphore undo operations.
14f08c3bdfSopenharmony_ci * 4) kcmp() returns 0 if the processes share the same address space.
15f08c3bdfSopenharmony_ci */
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_ci#define _GNU_SOURCE
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci#include <errno.h>
20f08c3bdfSopenharmony_ci#include <stdlib.h>
21f08c3bdfSopenharmony_ci#include <sys/wait.h>
22f08c3bdfSopenharmony_ci#include "tst_test.h"
23f08c3bdfSopenharmony_ci#include "lapi/kcmp.h"
24f08c3bdfSopenharmony_ci#include "lapi/sched.h"
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_ci#define STACK_SIZE	(1024*1024)
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_cistatic int pid1;
29f08c3bdfSopenharmony_cistatic int pid2;
30f08c3bdfSopenharmony_cistatic void *stack;
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_cistatic struct tcase {
33f08c3bdfSopenharmony_ci	int clone_type;
34f08c3bdfSopenharmony_ci	int kcmp_type;
35f08c3bdfSopenharmony_ci} tcases[] = {
36f08c3bdfSopenharmony_ci	{CLONE_VM, KCMP_VM},
37f08c3bdfSopenharmony_ci	{CLONE_FS, KCMP_FS},
38f08c3bdfSopenharmony_ci	{CLONE_IO, KCMP_IO},
39f08c3bdfSopenharmony_ci	{CLONE_SYSVSEM, KCMP_SYSVSEM}
40f08c3bdfSopenharmony_ci};
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_cistatic void setup(void)
43f08c3bdfSopenharmony_ci{
44f08c3bdfSopenharmony_ci	stack = SAFE_MALLOC(STACK_SIZE);
45f08c3bdfSopenharmony_ci}
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic void cleanup(void)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	free(stack);
50f08c3bdfSopenharmony_ci}
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_cistatic int do_child(void *arg)
53f08c3bdfSopenharmony_ci{
54f08c3bdfSopenharmony_ci	pid2 = getpid();
55f08c3bdfSopenharmony_ci
56f08c3bdfSopenharmony_ci	TEST(kcmp(pid1, pid2, *(int *)arg, 0, 0));
57f08c3bdfSopenharmony_ci	if (TST_RET == -1) {
58f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "kcmp() failed unexpectedly");
59f08c3bdfSopenharmony_ci		return 0;
60f08c3bdfSopenharmony_ci	}
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci	if (TST_RET == 0)
63f08c3bdfSopenharmony_ci		tst_res(TPASS, "kcmp() returned the expected value");
64f08c3bdfSopenharmony_ci	else
65f08c3bdfSopenharmony_ci		tst_res(TFAIL, "kcmp() returned the unexpected value");
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_ci	return 0;
68f08c3bdfSopenharmony_ci}
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_cistatic void verify_kcmp(unsigned int n)
71f08c3bdfSopenharmony_ci{
72f08c3bdfSopenharmony_ci	int res;
73f08c3bdfSopenharmony_ci
74f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[n];
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_ci	pid1 = getpid();
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_ci	res = ltp_clone(tc->clone_type | SIGCHLD, do_child, &tc->kcmp_type,
79f08c3bdfSopenharmony_ci			STACK_SIZE, stack);
80f08c3bdfSopenharmony_ci	if (res == -1)
81f08c3bdfSopenharmony_ci		tst_res(TFAIL | TERRNO, "clone() Failed");
82f08c3bdfSopenharmony_ci}
83f08c3bdfSopenharmony_ci
84f08c3bdfSopenharmony_cistatic struct tst_test test = {
85f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tcases),
86f08c3bdfSopenharmony_ci	.setup = setup,
87f08c3bdfSopenharmony_ci	.cleanup = cleanup,
88f08c3bdfSopenharmony_ci	.forks_child = 1,
89f08c3bdfSopenharmony_ci	.test = verify_kcmp,
90f08c3bdfSopenharmony_ci};
91