Installed-header hygiene (BZ#20366): obsolete BSD u_* types.
[glibc.git] / sysdeps / unix / sysv / linux / tst-setgetname.c
blobf490d8354cec6a5b3747a6617a52e219aa56cee7
1 /* Test pthread_setname_np and pthread_getname_np.
2 Copyright (C) 2013-2016 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 <http://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>
26 #include <kernel-features.h>
28 /* New name of process. */
29 #define NEW_NAME "setname"
31 /* Name of process which is one byte too big
32 e.g. 17 bytes including null-terminator */
33 #define BIG_NAME "....V....X....XV"
35 /* Longest name of a process
36 e.g. 16 bytes including null-terminator. */
37 #define LONGEST_NAME "....V....X....X"
39 /* One less than longest name with unique
40 characters to detect modification. */
41 #define CANARY_NAME "abcdefghijklmn"
43 /* On Linux the maximum length of the name of a task *including* the null
44 terminator. */
45 #define TASK_COMM_LEN 16
47 long
48 gettid (void)
50 return syscall(__NR_gettid);
53 /* On Linux we can read this task's name from /proc. */
54 int
55 get_self_comm (long tid, char *buf, size_t len)
57 int res = 0;
58 #define FMT "/proc/self/task/%lu/comm"
59 char fname[sizeof (FMT) + 8];
60 sprintf (fname, FMT, (unsigned long) tid);
62 int fd = open (fname, O_RDONLY);
63 if (fd == -1)
64 return errno;
66 ssize_t n = read (fd, (void *) buf, len);
67 if (n < 0)
68 res = errno;
69 else
71 if (buf[n - 1] == '\n')
72 buf[n - 1] = '\0';
73 else if (n == len)
74 res = ERANGE;
75 else
76 buf[n] = '\0';
79 close (fd);
80 return res;
83 int
84 do_test (int argc, char **argv)
86 pthread_t self;
87 int res;
88 int ret = 0;
89 char name[TASK_COMM_LEN];
90 char name_check[TASK_COMM_LEN];
92 memset (name, '\0', TASK_COMM_LEN);
93 memset (name_check, '\0', TASK_COMM_LEN);
95 /* Test 1: Get the name of the task via pthread_getname_np and /proc
96 and verify that they both match. */
97 self = pthread_self ();
98 res = pthread_getname_np (self, name, TASK_COMM_LEN);
100 if (res == 0)
102 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
104 #ifndef __ASSUME_PROC_PID_TASK_COMM
105 /* On this first test we look for ENOENT to be returned from
106 get_self_comm to indicate that the kernel is older than
107 2.6.33 and doesn't contain comm within the proc structure.
108 In that case we skip the entire test. */
109 if (res == ENOENT)
111 printf ("SKIP: The kernel does not have /proc/self/task/%%lu/comm.\n");
112 return 0;
114 #endif
116 if (res == 0)
118 if (strncmp (name, name_check, strlen (BIG_NAME)) == 0)
119 printf ("PASS: Test 1 - pthread_getname_np and /proc agree.\n");
120 else
122 printf ("FAIL: Test 1 - pthread_getname_np and /proc differ"
123 " i.e. %s != %s\n", name, name_check);
124 ret++;
127 else
129 printf ("FAIL: Test 1 - unable read task name via proc.\n");
130 ret++;
133 else
135 printf ("FAIL: Test 1 - pthread_getname_np failed with error %d\n", res);
136 ret++;
139 /* Test 2: Test setting the name and then independently verify it
140 was set. */
141 res = pthread_setname_np (self, NEW_NAME);
143 if (res == 0)
145 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
146 if (res == 0)
148 if (strncmp (NEW_NAME, name_check, strlen (BIG_NAME)) == 0)
149 printf ("PASS: Test 2 - Value used in pthread_setname_np and"
150 " /proc agree.\n");
151 else
153 printf ("FAIL: Test 2 - Value used in pthread_setname_np"
154 " and /proc differ i.e. %s != %s\n",
155 NEW_NAME, name_check);
156 ret++;
159 else
161 printf ("FAIL: Test 2 - unable to read task name via proc.\n");
162 ret++;
165 else
167 printf ("FAIL: Test 2 - pthread_setname_np failed with error %d\n", res);
168 ret++;
171 /* Test 3: Test setting a name that is one-byte too big. */
172 res = pthread_getname_np (self, name, TASK_COMM_LEN);
174 if (res == 0)
176 res = pthread_setname_np (self, BIG_NAME);
177 if (res != 0)
179 if (res == ERANGE)
181 printf ("PASS: Test 3 - pthread_setname_np returned ERANGE"
182 " for a process name that was too long.\n");
184 /* Verify the old name didn't change. */
185 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
186 if (res == 0)
188 if (strncmp (name, name_check, strlen (BIG_NAME)) == 0)
189 printf ("PASS: Test 3 - Original name unchanged after"
190 " pthread_setname_np returned ERANGE.\n");
191 else
193 printf ("FAIL: Test 3 - Original name changed after"
194 " pthread_setname_np returned ERANGE"
195 " i.e. %s != %s\n",
196 name, name_check);
197 ret++;
200 else
202 printf ("FAIL: Test 3 - unable to read task name.\n");
203 ret++;
206 else
208 printf ("FAIL: Test 3 - Wrong error returned"
209 " i.e. ERANGE != %d\n", res);
210 ret++;
213 else
215 printf ("FAIL: Test 3 - Too-long name accepted by"
216 " pthread_setname_np.\n");
217 ret++;
220 else
222 printf ("FAIL: Test 3 - Unable to get original name.\n");
223 ret++;
226 /* Test 4: Verify that setting the longest name works. */
227 res = pthread_setname_np (self, LONGEST_NAME);
229 if (res == 0)
231 res = get_self_comm (gettid (), name_check, TASK_COMM_LEN);
232 if (res == 0)
234 if (strncmp (LONGEST_NAME, name_check, strlen (BIG_NAME)) == 0)
235 printf ("PASS: Test 4 - Longest name set via pthread_setname_np"
236 " agrees with /proc.\n");
237 else
239 printf ("FAIL: Test 4 - Value used in pthread_setname_np and /proc"
240 " differ i.e. %s != %s\n", LONGEST_NAME, name_check);
241 ret++;
244 else
246 printf ("FAIL: Test 4 - unable to read task name via proc.\n");
247 ret++;
250 else
252 printf ("FAIL: Test 4 - pthread_setname_np failed with error %d\n", res);
253 ret++;
256 /* Test 5: Verify that getting a long name into a small buffer fails. */
257 strncpy (name, CANARY_NAME, strlen (CANARY_NAME) + 1);
259 /* Claim the buffer length is strlen (LONGEST_NAME). This is one character
260 too small to hold LONGEST_NAME *and* the null terminator. We should get
261 back ERANGE and name should be unmodified. */
262 res = pthread_getname_np (self, name, strlen (LONGEST_NAME));
264 if (res != 0)
266 if (res == ERANGE)
268 if (strncmp (CANARY_NAME, name, strlen (BIG_NAME)) == 0)
270 printf ("PASS: Test 5 - ERANGE and buffer unmodified.\n");
272 else
274 printf ("FAIL: Test 5 - Original buffer modified.\n");
275 ret++;
278 else
280 printf ("FAIL: Test 5 - Did not return ERANGE for small buffer.\n");
281 ret++;
284 else
286 printf ("FAIL: Test 5 - Returned name longer than buffer.\n");
287 ret++;
290 /* Test 6: Lastly make sure we can read back the longest name. */
291 res = pthread_getname_np (self, name, strlen (LONGEST_NAME) + 1);
293 if (res == 0)
295 if (strncmp (LONGEST_NAME, name, strlen (BIG_NAME)) == 0)
297 printf ("PASS: Test 6 - Read back longest name correctly.\n");
299 else
301 printf ("FAIL: Test 6 - Read \"%s\" instead of longest name.\n",
302 name);
303 ret++;
306 else
308 printf ("FAIL: Test 6 - pthread_getname_np failed with error %d\n", res);
309 ret++;
312 return ret;
315 #include <test-skeleton.c>