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