x86: Move CET infrastructure to x86_64
[glibc.git] / nptl / tst-setgetname.c
blobf80528669645e857260880ca0b1dfc808f37843b
1 /* Test pthread_setname_np and pthread_getname_np.
2 Copyright (C) 2013-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, see <https://www.gnu.org/licenses/>. */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <pthread.h>
21 #include <string.h>
22 #include <sys/syscall.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <errno.h>
27 /* New name of process. */
28 #define NEW_NAME "setname"
30 /* Name of process which is one byte too big
31 e.g. 17 bytes including null-terminator */
32 #define BIG_NAME "....V....X....XV"
34 /* Longest name of a process
35 e.g. 16 bytes including null-terminator. */
36 #define LONGEST_NAME "....V....X....X"
38 /* One less than longest name with unique
39 characters to detect modification. */
40 #define CANARY_NAME "abcdefghijklmn"
42 /* On Linux the maximum length of the name of a task *including* the null
43 terminator. */
44 #define TASK_COMM_LEN 16
46 /* On Linux we can read this task's name from /proc. */
47 int
48 get_self_comm (long tid, char *buf, size_t len)
50 int res = 0;
51 #define FMT "/proc/self/task/%lu/comm"
52 char fname[sizeof (FMT) + 32];
53 sprintf (fname, FMT, (unsigned long) tid);
55 int fd = open (fname, O_RDONLY);
56 if (fd == -1)
57 return errno;
59 ssize_t n = read (fd, (void *) buf, len);
60 if (n < 0)
61 res = errno;
62 else
64 if (buf[n - 1] == '\n')
65 buf[n - 1] = '\0';
66 else if (n == len)
67 res = ERANGE;
68 else
69 buf[n] = '\0';
72 close (fd);
73 return res;
76 int
77 do_test (int argc, char **argv)
79 pthread_t self;
80 int res;
81 int ret = 0;
82 char name[TASK_COMM_LEN];
83 char name_check[TASK_COMM_LEN];
85 memset (name, '\0', TASK_COMM_LEN);
86 memset (name_check, '\0', TASK_COMM_LEN);
88 /* Test 1: Get the name of the task via pthread_getname_np and /proc
89 and verify that they both match. */
90 self = pthread_self ();
91 res = pthread_getname_np (self, name, TASK_COMM_LEN);
93 if (res == 0)
95 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
97 if (res == 0)
99 if (strncmp (name, name_check, strlen (BIG_NAME)) == 0)
100 printf ("PASS: Test 1 - pthread_getname_np and /proc agree.\n");
101 else
103 printf ("FAIL: Test 1 - pthread_getname_np and /proc differ"
104 " i.e. %s != %s\n", name, name_check);
105 ret++;
108 else
110 printf ("FAIL: Test 1 - unable read task name via proc.\n");
111 ret++;
114 else
116 printf ("FAIL: Test 1 - pthread_getname_np failed with error %d\n", res);
117 ret++;
120 /* Test 2: Test setting the name and then independently verify it
121 was set. */
122 res = pthread_setname_np (self, NEW_NAME);
124 if (res == 0)
126 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
127 if (res == 0)
129 if (strncmp (NEW_NAME, name_check, strlen (BIG_NAME)) == 0)
130 printf ("PASS: Test 2 - Value used in pthread_setname_np and"
131 " /proc agree.\n");
132 else
134 printf ("FAIL: Test 2 - Value used in pthread_setname_np"
135 " and /proc differ i.e. %s != %s\n",
136 NEW_NAME, name_check);
137 ret++;
140 else
142 printf ("FAIL: Test 2 - unable to read task name via proc.\n");
143 ret++;
146 else
148 printf ("FAIL: Test 2 - pthread_setname_np failed with error %d\n", res);
149 ret++;
152 /* Test 3: Test setting a name that is one-byte too big. */
153 res = pthread_getname_np (self, name, TASK_COMM_LEN);
155 if (res == 0)
157 res = pthread_setname_np (self, BIG_NAME);
158 if (res != 0)
160 if (res == ERANGE)
162 printf ("PASS: Test 3 - pthread_setname_np returned ERANGE"
163 " for a process name that was too long.\n");
165 /* Verify the old name didn't change. */
166 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
167 if (res == 0)
169 if (strncmp (name, name_check, strlen (BIG_NAME)) == 0)
170 printf ("PASS: Test 3 - Original name unchanged after"
171 " pthread_setname_np returned ERANGE.\n");
172 else
174 printf ("FAIL: Test 3 - Original name changed after"
175 " pthread_setname_np returned ERANGE"
176 " i.e. %s != %s\n",
177 name, name_check);
178 ret++;
181 else
183 printf ("FAIL: Test 3 - unable to read task name.\n");
184 ret++;
187 else
189 printf ("FAIL: Test 3 - Wrong error returned"
190 " i.e. ERANGE != %d\n", res);
191 ret++;
194 else
196 printf ("FAIL: Test 3 - Too-long name accepted by"
197 " pthread_setname_np.\n");
198 ret++;
201 else
203 printf ("FAIL: Test 3 - Unable to get original name.\n");
204 ret++;
207 /* Test 4: Verify that setting the longest name works. */
208 res = pthread_setname_np (self, LONGEST_NAME);
210 if (res == 0)
212 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
213 if (res == 0)
215 if (strncmp (LONGEST_NAME, name_check, strlen (BIG_NAME)) == 0)
216 printf ("PASS: Test 4 - Longest name set via pthread_setname_np"
217 " agrees with /proc.\n");
218 else
220 printf ("FAIL: Test 4 - Value used in pthread_setname_np and /proc"
221 " differ i.e. %s != %s\n", LONGEST_NAME, name_check);
222 ret++;
225 else
227 printf ("FAIL: Test 4 - unable to read task name via proc.\n");
228 ret++;
231 else
233 printf ("FAIL: Test 4 - pthread_setname_np failed with error %d\n", res);
234 ret++;
237 /* Test 5: Verify that getting a long name into a small buffer fails. */
238 strncpy (name, CANARY_NAME, strlen (CANARY_NAME) + 1);
240 /* Claim the buffer length is strlen (LONGEST_NAME). This is one character
241 too small to hold LONGEST_NAME *and* the null terminator. We should get
242 back ERANGE and name should be unmodified. */
243 res = pthread_getname_np (self, name, strlen (LONGEST_NAME));
245 if (res != 0)
247 if (res == ERANGE)
249 if (strncmp (CANARY_NAME, name, strlen (BIG_NAME)) == 0)
251 printf ("PASS: Test 5 - ERANGE and buffer unmodified.\n");
253 else
255 printf ("FAIL: Test 5 - Original buffer modified.\n");
256 ret++;
259 else
261 printf ("FAIL: Test 5 - Did not return ERANGE for small buffer.\n");
262 ret++;
265 else
267 printf ("FAIL: Test 5 - Returned name longer than buffer.\n");
268 ret++;
271 /* Test 6: Lastly make sure we can read back the longest name. */
272 res = pthread_getname_np (self, name, strlen (LONGEST_NAME) + 1);
274 if (res == 0)
276 if (strncmp (LONGEST_NAME, name, strlen (BIG_NAME)) == 0)
278 printf ("PASS: Test 6 - Read back longest name correctly.\n");
280 else
282 printf ("FAIL: Test 6 - Read \"%s\" instead of longest name.\n",
283 name);
284 ret++;
287 else
289 printf ("FAIL: Test 6 - pthread_getname_np failed with error %d\n", res);
290 ret++;
293 return ret;
296 #include <test-skeleton.c>