1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2019 FUJITSU LIMITED. All rights reserved.
4f08c3bdfSopenharmony_ci * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*\
8f08c3bdfSopenharmony_ci * [Description]
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Test PR_GET_NAME and PR_SET_NAME of prctl(2).
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * - Set the name of the calling thread, the name can be up to 16 bytes
13f08c3bdfSopenharmony_ci *   long, including the terminating null byte. If exceeds 16 bytes, the
14f08c3bdfSopenharmony_ci *   string is silently truncated.
15f08c3bdfSopenharmony_ci *
16f08c3bdfSopenharmony_ci * - Return the name of the calling thread, the buffer should allow space
17f08c3bdfSopenharmony_ci *   for up to 16 bytes, the returned string will be null-terminated.
18f08c3bdfSopenharmony_ci *
19f08c3bdfSopenharmony_ci * - Check /proc/self/task/[tid]/comm and /proc/self/comm name whether
20f08c3bdfSopenharmony_ci *   matches the thread name.
21f08c3bdfSopenharmony_ci */
22f08c3bdfSopenharmony_ci
23f08c3bdfSopenharmony_ci#include <sys/prctl.h>
24f08c3bdfSopenharmony_ci#include <string.h>
25f08c3bdfSopenharmony_ci#include <stdio.h>
26f08c3bdfSopenharmony_ci#include "tst_test.h"
27f08c3bdfSopenharmony_ci#include "lapi/syscalls.h"
28f08c3bdfSopenharmony_ci#include "lapi/prctl.h"
29f08c3bdfSopenharmony_ci
30f08c3bdfSopenharmony_cistatic struct tcase {
31f08c3bdfSopenharmony_ci	char setname[20];
32f08c3bdfSopenharmony_ci	char expname[20];
33f08c3bdfSopenharmony_ci} tcases[] = {
34f08c3bdfSopenharmony_ci	{"prctl05_test", "prctl05_test"},
35f08c3bdfSopenharmony_ci	{"prctl05_test_xxxxx", "prctl05_test_xx"}
36f08c3bdfSopenharmony_ci};
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_cistatic void verify_prctl(unsigned int n)
39f08c3bdfSopenharmony_ci{
40f08c3bdfSopenharmony_ci	char buf[20];
41f08c3bdfSopenharmony_ci	char comm_path[40];
42f08c3bdfSopenharmony_ci	pid_t tid;
43f08c3bdfSopenharmony_ci	struct tcase *tc = &tcases[n];
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ci	TEST(prctl(PR_SET_NAME, tc->setname));
46f08c3bdfSopenharmony_ci	if (TST_RET == -1) {
47f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "prctl(PR_SET_NAME) failed");
48f08c3bdfSopenharmony_ci		return;
49f08c3bdfSopenharmony_ci	}
50f08c3bdfSopenharmony_ci	tst_res(TPASS, "prctl(PR_SET_NAME, '%s') succeeded", tc->setname);
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	TEST(prctl(PR_GET_NAME, buf));
53f08c3bdfSopenharmony_ci	if (TST_RET == -1) {
54f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO, "prctl(PR_GET_NAME) failed");
55f08c3bdfSopenharmony_ci		return;
56f08c3bdfSopenharmony_ci	}
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	if (strncmp(tc->expname, buf, sizeof(buf))) {
59f08c3bdfSopenharmony_ci		tst_res(TFAIL,
60f08c3bdfSopenharmony_ci			"prctl(PR_GET_NAME) failed, expected %s, got %s",
61f08c3bdfSopenharmony_ci			tc->expname, buf);
62f08c3bdfSopenharmony_ci		return;
63f08c3bdfSopenharmony_ci	}
64f08c3bdfSopenharmony_ci	tst_res(TPASS, "prctl(PR_GET_NAME) succeeded, thread name is %s", buf);
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci	tid = tst_syscall(__NR_gettid);
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	sprintf(comm_path, "/proc/self/task/%d/comm", tid);
69f08c3bdfSopenharmony_ci	TST_ASSERT_STR(comm_path, tc->expname);
70f08c3bdfSopenharmony_ci	TST_ASSERT_STR("/proc/self/comm", tc->expname);
71f08c3bdfSopenharmony_ci}
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_cistatic struct tst_test test = {
74f08c3bdfSopenharmony_ci	.test = verify_prctl,
75f08c3bdfSopenharmony_ci	.tcnt = ARRAY_SIZE(tcases),
76f08c3bdfSopenharmony_ci};
77