1 /* Test pthread_setname_np and pthread_getname_np.
2 Copyright (C) 2013-2017 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/>. */
22 #include <sys/syscall.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
44 #define TASK_COMM_LEN 16
49 return syscall(__NR_gettid
);
52 /* On Linux we can read this task's name from /proc. */
54 get_self_comm (long tid
, char *buf
, size_t len
)
57 #define FMT "/proc/self/task/%lu/comm"
58 char fname
[sizeof (FMT
) + 32];
59 sprintf (fname
, FMT
, (unsigned long) tid
);
61 int fd
= open (fname
, O_RDONLY
);
65 ssize_t n
= read (fd
, (void *) buf
, len
);
70 if (buf
[n
- 1] == '\n')
83 do_test (int argc
, char **argv
)
88 char name
[TASK_COMM_LEN
];
89 char name_check
[TASK_COMM_LEN
];
91 memset (name
, '\0', TASK_COMM_LEN
);
92 memset (name_check
, '\0', TASK_COMM_LEN
);
94 /* Test 1: Get the name of the task via pthread_getname_np and /proc
95 and verify that they both match. */
96 self
= pthread_self ();
97 res
= pthread_getname_np (self
, name
, TASK_COMM_LEN
);
101 res
= get_self_comm (gettid (), name_check
, TASK_COMM_LEN
);
105 if (strncmp (name
, name_check
, strlen (BIG_NAME
)) == 0)
106 printf ("PASS: Test 1 - pthread_getname_np and /proc agree.\n");
109 printf ("FAIL: Test 1 - pthread_getname_np and /proc differ"
110 " i.e. %s != %s\n", name
, name_check
);
116 printf ("FAIL: Test 1 - unable read task name via proc.\n");
122 printf ("FAIL: Test 1 - pthread_getname_np failed with error %d\n", res
);
126 /* Test 2: Test setting the name and then independently verify it
128 res
= pthread_setname_np (self
, NEW_NAME
);
132 res
= get_self_comm (gettid (), name_check
, TASK_COMM_LEN
);
135 if (strncmp (NEW_NAME
, name_check
, strlen (BIG_NAME
)) == 0)
136 printf ("PASS: Test 2 - Value used in pthread_setname_np and"
140 printf ("FAIL: Test 2 - Value used in pthread_setname_np"
141 " and /proc differ i.e. %s != %s\n",
142 NEW_NAME
, name_check
);
148 printf ("FAIL: Test 2 - unable to read task name via proc.\n");
154 printf ("FAIL: Test 2 - pthread_setname_np failed with error %d\n", res
);
158 /* Test 3: Test setting a name that is one-byte too big. */
159 res
= pthread_getname_np (self
, name
, TASK_COMM_LEN
);
163 res
= pthread_setname_np (self
, BIG_NAME
);
168 printf ("PASS: Test 3 - pthread_setname_np returned ERANGE"
169 " for a process name that was too long.\n");
171 /* Verify the old name didn't change. */
172 res
= get_self_comm (gettid (), name_check
, TASK_COMM_LEN
);
175 if (strncmp (name
, name_check
, strlen (BIG_NAME
)) == 0)
176 printf ("PASS: Test 3 - Original name unchanged after"
177 " pthread_setname_np returned ERANGE.\n");
180 printf ("FAIL: Test 3 - Original name changed after"
181 " pthread_setname_np returned ERANGE"
189 printf ("FAIL: Test 3 - unable to read task name.\n");
195 printf ("FAIL: Test 3 - Wrong error returned"
196 " i.e. ERANGE != %d\n", res
);
202 printf ("FAIL: Test 3 - Too-long name accepted by"
203 " pthread_setname_np.\n");
209 printf ("FAIL: Test 3 - Unable to get original name.\n");
213 /* Test 4: Verify that setting the longest name works. */
214 res
= pthread_setname_np (self
, LONGEST_NAME
);
218 res
= get_self_comm (gettid (), name_check
, TASK_COMM_LEN
);
221 if (strncmp (LONGEST_NAME
, name_check
, strlen (BIG_NAME
)) == 0)
222 printf ("PASS: Test 4 - Longest name set via pthread_setname_np"
223 " agrees with /proc.\n");
226 printf ("FAIL: Test 4 - Value used in pthread_setname_np and /proc"
227 " differ i.e. %s != %s\n", LONGEST_NAME
, name_check
);
233 printf ("FAIL: Test 4 - unable to read task name via proc.\n");
239 printf ("FAIL: Test 4 - pthread_setname_np failed with error %d\n", res
);
243 /* Test 5: Verify that getting a long name into a small buffer fails. */
244 strncpy (name
, CANARY_NAME
, strlen (CANARY_NAME
) + 1);
246 /* Claim the buffer length is strlen (LONGEST_NAME). This is one character
247 too small to hold LONGEST_NAME *and* the null terminator. We should get
248 back ERANGE and name should be unmodified. */
249 res
= pthread_getname_np (self
, name
, strlen (LONGEST_NAME
));
255 if (strncmp (CANARY_NAME
, name
, strlen (BIG_NAME
)) == 0)
257 printf ("PASS: Test 5 - ERANGE and buffer unmodified.\n");
261 printf ("FAIL: Test 5 - Original buffer modified.\n");
267 printf ("FAIL: Test 5 - Did not return ERANGE for small buffer.\n");
273 printf ("FAIL: Test 5 - Returned name longer than buffer.\n");
277 /* Test 6: Lastly make sure we can read back the longest name. */
278 res
= pthread_getname_np (self
, name
, strlen (LONGEST_NAME
) + 1);
282 if (strncmp (LONGEST_NAME
, name
, strlen (BIG_NAME
)) == 0)
284 printf ("PASS: Test 6 - Read back longest name correctly.\n");
288 printf ("FAIL: Test 6 - Read \"%s\" instead of longest name.\n",
295 printf ("FAIL: Test 6 - pthread_getname_np failed with error %d\n", res
);
302 #include <test-skeleton.c>