blob: b164272644e66b9d52098f90f73fc6e588c44af0 [file] [log] [blame]
John Levonab618542018-10-08 15:34:11 +01001/*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12/*
13 * Copyright 2018 Joyent, Inc.
14 */
15
16/*
17 * Some basic pthread name API tests.
18 */
19
20#include <sys/stat.h>
21#include <pthread.h>
22#include <limits.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <thread.h>
27#include <fcntl.h>
28#include <stdio.h>
29#include <errno.h>
30#include <err.h>
31
32
33/*ARGSUSED*/
34static void *
35thr(void *unused)
36{
37 (void) sleep(100);
38 return (NULL);
39}
40
41/*ARGSUSED*/
42int
43main(int argc, char *argv[])
44{
45 char name[PTHREAD_MAX_NAMELEN_NP];
46 pthread_attr_t attr;
47 char path[PATH_MAX];
48 pthread_t tid;
49 ssize_t n;
50 int test;
51 int rc;
52 int fd;
53
54 /* Default thread name is empty string. */
55 test = 1;
56
57 rc = pthread_getname_np(pthread_self(), name, sizeof (name));
58
59 if (rc != 0 || strcmp(name, "") != 0)
60 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
61
62 /* Can set name. */
63 test = 2;
64
65 (void) strlcpy(name, "main", sizeof (name));
66 rc = pthread_setname_np(pthread_self(), name);
67
68 if (rc != 0)
69 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
70
71 rc = pthread_getname_np(pthread_self(), name, sizeof (name));
72
73 if (rc != 0 || strcmp(name, "main") != 0)
74 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
75
76 /* ERANGE check. */
77 test = 3;
78
79 rc = pthread_getname_np(pthread_self(), name, 2);
80
81 if (rc != ERANGE)
82 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
83
84 /* EINVAL check. */
85 test = 4;
86
87 rc = pthread_getname_np(pthread_self(), NULL, sizeof (name));
88
89 if (rc != EINVAL)
90 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
91
92 /* can clear thread name. */
93 test = 5;
94
95 rc = pthread_setname_np(pthread_self(), NULL);
96
97 if (rc != 0)
98 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
99
100 rc = pthread_getname_np(pthread_self(), name, sizeof (name));
101
102 if (rc != 0 || strcmp(name, "") != 0)
103 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
104
105 /* non-existent thread check. */
106 test = 6;
107
108 rc = pthread_getname_np(808, name, sizeof (name));
109
110 if (rc != ESRCH)
111 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
112
113 rc = pthread_setname_np(808, "state");
114
115 if (rc != ESRCH)
116 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
117
118 /* too long a name. */
119 test = 7;
120
121 rc = pthread_setname_np(pthread_self(),
122 "12345678901234567890123456789012");
123
124 if (rc != ERANGE)
125 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
126
127 /* can name another thread. */
128 test = 8;
129
130 rc = pthread_create(&tid, NULL, thr, NULL);
131
132 if (rc != 0)
133 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
134
135 rc = pthread_setname_np(tid, "otherthread");
136
137 if (rc != 0)
138 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
139
140 /* attr tests. */
141 test = 9;
142
143 (void) pthread_attr_init(&attr);
144
145 rc = pthread_attr_setname_np(&attr,
146 "12345678901234567890123456789012");
147
148 if (rc != ERANGE)
149 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
150
151 rc = pthread_attr_setname_np(&attr, "thread2");
152
153 if (rc != 0)
154 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
155
156 rc = pthread_attr_getname_np(&attr, NULL, sizeof (name));
157
158 if (rc != EINVAL)
159 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
160
161 rc = pthread_attr_getname_np(&attr, name, 2);
162
163 if (rc != ERANGE)
164 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
165
166 /* does the attr actually apply? */
167 test = 10;
168
169 rc = pthread_create(&tid, &attr, thr, NULL);
170
171 if (rc != 0)
172 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
173
174 rc = pthread_getname_np(tid, name, sizeof (name));
175
176 if (rc != 0 || strcmp(name, "thread2") != 0)
177 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
178
179 /* proc read tests */
180 test = 11;
181
182 (void) snprintf(path, sizeof (path),
183 "/proc/self/lwp/%d/lwpname", (int)tid);
184
185 fd = open(path, O_RDWR);
186
187 if (fd == -1)
188 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
189
190 n = read(fd, name, sizeof (name));
191
192 if (n != sizeof (name) || strcmp(name, "thread2") != 0)
193 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
194
195 if (lseek(fd, 0, SEEK_SET) != 0)
196 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
197
198 n = read(fd, name, PTHREAD_MAX_NAMELEN_NP * 2);
199
200 if (n != sizeof (name) || strcmp(name, "thread2") != 0)
201 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
202
203 if (lseek(fd, 0, SEEK_SET) != 0)
204 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
205
206 n = read(fd, name, 4);
207
208 if (n != 4 || strncmp(name, "thre", 4) != 0)
209 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
210
211 /* proc write tests */
212 test = 12;
213
214 if (lseek(fd, 0, SEEK_SET) != 0)
215 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
216
217 n = write(fd, "1234567890123456789012345678901",
218 PTHREAD_MAX_NAMELEN_NP);
219
220 if (n != PTHREAD_MAX_NAMELEN_NP)
221 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
222
223 if (lseek(fd, 0, SEEK_SET) != 0)
224 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
225
226 n = write(fd, "foo", sizeof ("foo"));
227
228 if (n != sizeof ("foo"))
229 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
230
231 if (lseek(fd, 0, SEEK_SET) != 0)
232 errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
233
234 n = read(fd, name, sizeof (name));
235
236 if (n != sizeof (name) || strcmp(name, "foo") != 0)
237 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
238
239 (void) close(fd);
240
241 /* thr_* API. */
242 test = 13;
243
244 rc = thr_setname(thr_self(), "main");
245
246 if (rc != 0)
247 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
248
249 rc = thr_getname(thr_self(), name, sizeof (name));
250
251 if (rc != 0 || strcmp(name, "main") != 0)
252 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
253
254 /* badness */
255 test = 14;
256
257 rc = thr_setname(thr_self(), "\033]0;messeduptitle\a");
258
259 if (rc != EINVAL)
260 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
261
262 rc = thr_setname(thr_self(), "ab\177\177\n");
263
264 if (rc != EINVAL)
265 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
266
267 rc = pthread_attr_setname_np(&attr, "\033]0;messeduptitle\a");
268
269 if (rc != EINVAL)
270 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
271
272 rc = pthread_attr_setname_np(&attr, "ab\177\177\n");
273
274 if (rc != EINVAL)
275 errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
276
277 return (EXIT_SUCCESS);
278}