Tests: unchecked pthread_join return value
[lttng-tools.git] / tests / regression / kernel / select_poll_epoll.c
1 #include <stdio.h>
2 #include <poll.h>
3 #include <signal.h>
4 #include <unistd.h>
5 #include <sys/syscall.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stddef.h>
12 #include <sys/select.h>
13 #include <sys/epoll.h>
14 #include <popt.h>
15 #include <sys/time.h>
16 #include <sys/resource.h>
17 #include <limits.h>
18 #include <pthread.h>
19 #include <sys/mman.h>
20 #include <time.h>
21
22 #define BUF_SIZE 256
23 #define NB_FD 1
24 #define MAX_FDS 2047
25 #define NR_ITER 1000 /* for stress-tests */
26
27 #define MIN_NR_FDS 5 /* the minimum number of open FDs required for the test to run */
28 #define BIG_SELECT_FD 1022
29
30 #define MSEC_PER_USEC 1000
31 #define MSEC_PER_NSEC (MSEC_PER_USEC * 1000)
32
33 static int timeout; /* seconds, -1 to disable */
34 volatile static int stop_thread;
35 static int wait_fd;
36
37 struct ppoll_thread_data {
38 struct pollfd *ufds;
39 int value;
40 };
41
42 void test_select_big(void)
43 {
44 fd_set rfds, wfds, exfds;
45 struct timeval tv;
46 int ret;
47 int fd2;
48 char buf[BUF_SIZE];
49
50 FD_ZERO(&rfds);
51 FD_ZERO(&wfds);
52 FD_ZERO(&exfds);
53
54 fd2 = dup2(wait_fd, BIG_SELECT_FD);
55 if (fd2 < 0) {
56 perror("dup2");
57 goto end;
58 }
59 FD_SET(fd2, &rfds);
60
61 tv.tv_sec = 0;
62 tv.tv_usec = timeout * MSEC_PER_USEC;
63
64 if (timeout > 0) {
65 ret = select(fd2 + 1, &rfds, &wfds, &exfds, &tv);
66 } else {
67 ret = select(fd2 + 1, &rfds, &wfds, &exfds, NULL);
68 }
69
70 if (ret == -1) {
71 perror("select()");
72 } else if (ret) {
73 printf("# [select] data available\n");
74 ret = read(wait_fd, buf, BUF_SIZE);
75 if (ret < 0) {
76 perror("[select] read");
77 }
78 } else {
79 printf("# [select] timeout\n");
80 }
81
82 ret = close(BIG_SELECT_FD);
83 if (ret) {
84 perror("close");
85 }
86
87 end:
88 return;
89 }
90
91 void test_pselect(void)
92 {
93 fd_set rfds;
94 struct timespec tv;
95 int ret;
96 char buf[BUF_SIZE];
97
98 FD_ZERO(&rfds);
99 FD_SET(wait_fd, &rfds);
100
101 tv.tv_sec = 0;
102 tv.tv_nsec = timeout * MSEC_PER_NSEC;
103
104 if (timeout > 0) {
105 ret = pselect(1, &rfds, NULL, NULL, &tv, NULL);
106 } else {
107 ret = pselect(1, &rfds, NULL, NULL, NULL, NULL);
108 }
109
110 if (ret == -1) {
111 perror("pselect()");
112 } else if (ret) {
113 printf("# [pselect] data available\n");
114 ret = read(wait_fd, buf, BUF_SIZE);
115 if (ret < 0) {
116 perror("[pselect] read");
117 }
118 } else {
119 printf("# [pselect] timeout\n");
120 }
121
122 }
123
124 void test_select(void)
125 {
126 fd_set rfds;
127 struct timeval tv;
128 int ret;
129 char buf[BUF_SIZE];
130
131 FD_ZERO(&rfds);
132 FD_SET(wait_fd, &rfds);
133
134 tv.tv_sec = 0;
135 tv.tv_usec = timeout * MSEC_PER_USEC;
136
137 if (timeout > 0) {
138 ret = select(1, &rfds, NULL, NULL, &tv);
139 } else {
140 ret = select(1, &rfds, NULL, NULL, NULL);
141 }
142
143 if (ret == -1) {
144 perror("select()");
145 } else if (ret) {
146 printf("# [select] data available\n");
147 ret = read(wait_fd, buf, BUF_SIZE);
148 if (ret < 0) {
149 perror("[select] read");
150 }
151 } else {
152 printf("# [select] timeout\n");
153 }
154
155 }
156
157 void test_poll(void)
158 {
159 struct pollfd ufds[NB_FD];
160 char buf[BUF_SIZE];
161 int ret;
162
163 ufds[0].fd = wait_fd;
164 ufds[0].events = POLLIN|POLLPRI;
165
166 ret = poll(ufds, 1, timeout);
167
168 if (ret < 0) {
169 perror("poll");
170 } else if (ret > 0) {
171 printf("# [poll] data available\n");
172 ret = read(wait_fd, buf, BUF_SIZE);
173 if (ret < 0) {
174 perror("[poll] read");
175 }
176 } else {
177 printf("# [poll] timeout\n");
178 }
179 }
180
181 void test_ppoll(void)
182 {
183 struct pollfd ufds[NB_FD];
184 char buf[BUF_SIZE];
185 int ret;
186 struct timespec ts;
187
188 ufds[0].fd = wait_fd;
189 ufds[0].events = POLLIN|POLLPRI;
190
191 if (timeout > 0) {
192 ts.tv_sec = 0;
193 ts.tv_nsec = timeout * MSEC_PER_NSEC;
194 ret = ppoll(ufds, 1, &ts, NULL);
195 } else {
196 ret = ppoll(ufds, 1, NULL, NULL);
197 }
198
199
200 if (ret < 0) {
201 perror("ppoll");
202 } else if (ret > 0) {
203 printf("# [ppoll] data available\n");
204 ret = read(wait_fd, buf, BUF_SIZE);
205 if (ret < 0) {
206 perror("[ppoll] read");
207 }
208 } else {
209 printf("# [ppoll] timeout\n");
210 }
211 }
212
213 void test_ppoll_big(void)
214 {
215 struct pollfd ufds[MAX_FDS];
216 char buf[BUF_SIZE];
217 int ret, i, fds[MAX_FDS];
218
219 for (i = 0; i < MAX_FDS; i++) {
220 fds[i] = dup(wait_fd);
221 if (fds[i] < 0) {
222 perror("dup");
223 }
224 ufds[i].fd = fds[i];
225 ufds[i].events = POLLIN|POLLPRI;
226 }
227
228 ret = ppoll(ufds, MAX_FDS, NULL, NULL);
229
230 if (ret < 0) {
231 perror("ppoll");
232 } else if (ret > 0) {
233 printf("# [ppoll] data available\n");
234 ret = read(wait_fd, buf, BUF_SIZE);
235 if (ret < 0) {
236 perror("[ppoll] read");
237 }
238 } else {
239 printf("# [ppoll] timeout\n");
240 }
241
242 for (i = 0; i < MAX_FDS; i++) {
243 ret = close(fds[i]);
244 if (ret != 0) {
245 perror("close");
246 }
247 }
248
249 return;
250 }
251
252 void test_epoll(void)
253 {
254 int ret, epollfd;
255 char buf[BUF_SIZE];
256 struct epoll_event epoll_event;
257
258 epollfd = epoll_create(NB_FD);
259 if (epollfd < 0) {
260 perror("[epoll] create");
261 goto end;
262 }
263
264 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
265 epoll_event.data.fd = wait_fd;
266 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
267 if (ret < 0) {
268 perror("[epoll] add");
269 goto end;
270 }
271
272 if (timeout > 0) {
273 ret = epoll_wait(epollfd, &epoll_event, 1, timeout);
274 } else {
275 ret = epoll_wait(epollfd, &epoll_event, 1, -1);
276 }
277
278 if (ret == 1) {
279 printf("# [epoll] data available\n");
280 ret = read(wait_fd, buf, BUF_SIZE);
281 if (ret < 0) {
282 perror("[epoll] read");
283 }
284 } else if (ret == 0) {
285 printf("# [epoll] timeout\n");
286 } else {
287 perror("epoll_wait");
288 }
289
290 end:
291 return;
292 }
293
294 void test_pepoll(void)
295 {
296 int ret, epollfd;
297 char buf[BUF_SIZE];
298 struct epoll_event epoll_event;
299
300 epollfd = epoll_create(NB_FD);
301 if (epollfd < 0) {
302 perror("[eppoll] create");
303 goto end;
304 }
305
306 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
307 epoll_event.data.fd = wait_fd;
308 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
309 if (ret < 0) {
310 perror("[eppoll] add");
311 goto end;
312 }
313
314 if (timeout > 0) {
315 ret = epoll_pwait(epollfd, &epoll_event, 1, timeout, NULL);
316 } else {
317 ret = epoll_pwait(epollfd, &epoll_event, 1, -1, NULL);
318 }
319
320 if (ret == 1) {
321 printf("# [eppoll] data available\n");
322 ret = read(wait_fd, buf, BUF_SIZE);
323 if (ret < 0) {
324 perror("[eppoll] read");
325 }
326 } else if (ret == 0) {
327 printf("# [eppoll] timeout\n");
328 } else {
329 perror("epoll_pwait");
330 }
331
332 end:
333 return;
334 }
335
336 void run_working_cases(void)
337 {
338 int ret;
339 int pipe_fds[2];
340
341 if (timeout > 0) {
342 /*
343 * We need an input pipe for some cases and stdin might
344 * have random data, so we create a dummy pipe for this
345 * test to make sure we are running under clean conditions.
346 */
347 ret = pipe(pipe_fds);
348 if (ret != 0) {
349 perror("pipe");
350 goto end;
351 }
352 wait_fd = pipe_fds[0];
353 }
354 test_select();
355 test_pselect();
356 test_select_big();
357 test_poll();
358 test_ppoll();
359 test_epoll();
360 test_pepoll();
361
362 if (timeout > 0) {
363 ret = close(pipe_fds[0]);
364 if (ret) {
365 perror("close");
366 }
367 ret = close(pipe_fds[1]);
368 if (ret) {
369 perror("close");
370 }
371 }
372
373 end:
374 return;
375 }
376
377 /*
378 * Ask for 100 FDs in a buffer for allocated for only 1 FD, should
379 * segfault (eventually with a "*** stack smashing detected ***" message).
380 * The event should contain an array of 100 FDs filled with garbage.
381 */
382 void ppoll_fds_buffer_overflow(void)
383 {
384 struct pollfd ufds[NB_FD];
385 char buf[BUF_SIZE];
386 int ret;
387
388 ufds[0].fd = wait_fd;
389 ufds[0].events = POLLIN|POLLPRI;
390
391 ret = syscall(SYS_ppoll, ufds, 100, NULL, NULL);
392
393 if (ret < 0) {
394 perror("ppoll");
395 } else if (ret > 0) {
396 printf("# [ppoll] data available\n");
397 ret = read(wait_fd, buf, BUF_SIZE);
398 if (ret < 0) {
399 perror("[ppoll] read");
400 }
401 } else {
402 printf("# [ppoll] timeout\n");
403 }
404
405 return;
406 }
407
408 /*
409 * Ask for ULONG_MAX FDs in a buffer for allocated for only 1 FD, should
410 * cleanly fail with a "Invalid argument".
411 * The event should contain an empty array of FDs and overflow = 1.
412 */
413 void ppoll_fds_ulong_max(void)
414 {
415 struct pollfd ufds[NB_FD];
416 char buf[BUF_SIZE];
417 int ret;
418
419 ufds[0].fd = wait_fd;
420 ufds[0].events = POLLIN|POLLPRI;
421
422 ret = syscall(SYS_ppoll, ufds, ULONG_MAX, NULL, NULL);
423
424 if (ret < 0) {
425 perror("# ppoll");
426 } else if (ret > 0) {
427 printf("# [ppoll] data available\n");
428 ret = read(wait_fd, buf, BUF_SIZE);
429 if (ret < 0) {
430 perror("[ppoll] read");
431 }
432 } else {
433 printf("# [ppoll] timeout\n");
434 }
435
436 return;
437 }
438
439 /*
440 * Select is limited to 1024 FDs, should output a pselect event
441 * with 0 FDs.
442 */
443 void pselect_fd_too_big(void)
444 {
445 fd_set rfds;
446 int ret;
447 int fd2;
448 char buf[BUF_SIZE];
449
450 /*
451 * Test if nfds > 1024.
452 * Make sure ulimit is set correctly (ulimit -n 2048).
453 */
454 fd2 = dup2(wait_fd, 2047);
455 if (fd2 != 2047) {
456 perror("dup2");
457 return;
458 }
459 FD_ZERO(&rfds);
460 FD_SET(fd2, &rfds);
461
462 ret = syscall(SYS_pselect6, fd2 + 1, &rfds, NULL, NULL, NULL, NULL);
463
464 if (ret == -1) {
465 perror("# pselect()");
466 } else if (ret) {
467 printf("# [pselect] data available\n");
468 ret = read(wait_fd, buf, BUF_SIZE);
469 if (ret < 0) {
470 perror("[pselect] read");
471 }
472 } else {
473 printf("# [pselect] timeout\n");
474 }
475
476 }
477
478 /*
479 * Invalid pointer as writefds, should output a ppoll event
480 * with 0 FDs.
481 */
482 void pselect_invalid_pointer(void)
483 {
484 fd_set rfds;
485 int ret;
486 char buf[BUF_SIZE];
487 void *invalid = (void *) 0x42;
488
489 FD_ZERO(&rfds);
490 FD_SET(wait_fd, &rfds);
491
492 ret = syscall(SYS_pselect6, 1, &rfds, (fd_set *) invalid, NULL, NULL,
493 NULL);
494
495 if (ret == -1) {
496 perror("# pselect()");
497 } else if (ret) {
498 printf("# [pselect] data available\n");
499 ret = read(wait_fd, buf, BUF_SIZE);
500 if (ret < 0) {
501 perror("[pselect] read");
502 }
503 } else {
504 printf("# [pselect] timeout\n");
505 }
506
507 }
508
509 /*
510 * Pass an invalid pointer to epoll_pwait, should fail with
511 * "Bad address", the event returns 0 FDs.
512 */
513 void epoll_pwait_invalid_pointer(void)
514 {
515 int ret, epollfd;
516 char buf[BUF_SIZE];
517 struct epoll_event epoll_event;
518 void *invalid = (void *) 0x42;
519
520 epollfd = epoll_create(NB_FD);
521 if (epollfd < 0) {
522 perror("[eppoll] create");
523 goto end;
524 }
525
526 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
527 epoll_event.data.fd = wait_fd;
528 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
529 if (ret < 0) {
530 perror("[eppoll] add");
531 goto end;
532 }
533
534 ret = syscall(SYS_epoll_pwait, epollfd,
535 (struct epoll_event *) invalid, 1, -1, NULL);
536
537 if (ret == 1) {
538 printf("# [eppoll] data available\n");
539 ret = read(wait_fd, buf, BUF_SIZE);
540 if (ret < 0) {
541 perror("[eppoll] read");
542 }
543 } else if (ret == 0) {
544 printf("# [eppoll] timeout\n");
545 } else {
546 perror("# epoll_pwait");
547 }
548
549 end:
550 return;
551 }
552
553 /*
554 * Set maxevents to INT_MAX, should output "Invalid argument"
555 * The event should return an empty array.
556 */
557 void epoll_pwait_int_max(void)
558 {
559 int ret, epollfd;
560 char buf[BUF_SIZE];
561 struct epoll_event epoll_event;
562
563 epollfd = epoll_create(NB_FD);
564 if (epollfd < 0) {
565 perror("[eppoll] create");
566 goto end;
567 }
568
569 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
570 epoll_event.data.fd = wait_fd;
571 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
572 if (ret < 0) {
573 perror("[eppoll] add");
574 goto end;
575 }
576
577 ret = syscall(SYS_epoll_pwait, epollfd, &epoll_event, INT_MAX, -1,
578 NULL);
579
580 if (ret == 1) {
581 printf("# [eppoll] data available\n");
582 ret = read(wait_fd, buf, BUF_SIZE);
583 if (ret < 0) {
584 perror("[eppoll] read");
585 }
586 } else if (ret == 0) {
587 printf("# [eppoll] timeout\n");
588 } else {
589 perror("# epoll_pwait");
590 }
591
592 end:
593 return;
594 }
595
596 void *ppoll_writer(void *arg)
597 {
598 struct ppoll_thread_data *data = (struct ppoll_thread_data *) arg;
599
600 while (!stop_thread) {
601 memset(data->ufds, data->value,
602 MAX_FDS * sizeof(struct pollfd));
603 usleep(100);
604 }
605
606 return NULL;
607 }
608
609 void do_ppoll(int *fds, struct pollfd *ufds)
610 {
611 int i, ret;
612 struct timespec ts;
613 char buf[BUF_SIZE];
614
615 ts.tv_sec = 0;
616 ts.tv_nsec = 1 * MSEC_PER_NSEC;
617
618 for (i = 0; i < MAX_FDS; i++) {
619 ufds[i].fd = fds[i];
620 ufds[i].events = POLLIN|POLLPRI;
621 }
622
623 ret = ppoll(ufds, MAX_FDS, &ts, NULL);
624
625 if (ret < 0) {
626 perror("ppoll");
627 } else if (ret > 0) {
628 printf("# [ppoll] data available\n");
629 ret = read(wait_fd, buf, BUF_SIZE);
630 if (ret < 0) {
631 perror("[ppoll] read");
632 }
633 } else {
634 printf("# [ppoll] timeout\n");
635 }
636 }
637
638 void stress_ppoll(int *fds, int value)
639 {
640 pthread_t writer;
641 int iter, ret;
642 struct ppoll_thread_data thread_data;
643 struct pollfd ufds[MAX_FDS];
644
645 thread_data.ufds = ufds;
646 thread_data.value = value;
647
648 stop_thread = 0;
649 ret = pthread_create(&writer, NULL, &ppoll_writer, (void *) &thread_data);
650 if (ret != 0) {
651 fprintf(stderr, "[error] pthread_create\n");
652 goto end;
653 }
654 for (iter = 0; iter < NR_ITER; iter++) {
655 do_ppoll(fds, ufds);
656 }
657 stop_thread = 1;
658 ret = pthread_join(writer, NULL);
659 if (ret) {
660 fprintf(stderr, "[error] pthread_join\n");
661 goto end;
662 }
663 end:
664 return;
665 }
666
667 /*
668 * 3 rounds of NR_ITER iterations with concurrent updates of the pollfd
669 * structure:
670 * - memset to 0
671 * - memset to 1
672 * - memset to INT_MAX
673 * Waits for input, but also set a timeout in case the input FD is overwritten
674 * before entering in the syscall. We use MAX_FDS FDs (dup of stdin), so the
675 * resulting trace is big (20MB).
676 *
677 * ppoll should work as expected and the trace should be readable at the end.
678 */
679 void ppoll_concurrent_write(void)
680 {
681 int i, ret, fds[MAX_FDS];
682
683 for (i = 0; i < MAX_FDS; i++) {
684 fds[i] = dup(wait_fd);
685 if (fds[i] < 0) {
686 perror("dup");
687 }
688 }
689
690 stress_ppoll(fds, 0);
691 stress_ppoll(fds, 1);
692 stress_ppoll(fds, INT_MAX);
693
694 for (i = 0; i < MAX_FDS; i++) {
695 ret = close(fds[i]);
696 if (ret != 0) {
697 perror("close");
698 }
699 }
700
701 return;
702 }
703
704 void *epoll_pwait_writer(void *addr)
705 {
706 srand(time(NULL));
707
708 while (!stop_thread) {
709 usleep(rand() % 30);
710 munmap(addr, MAX_FDS * sizeof(struct epoll_event));
711 }
712
713 return NULL;
714 }
715
716 /*
717 * epoll_pwait on MAX_FDS fds while a concurrent thread munmaps the
718 * buffer allocated for the returned data. This should randomly segfault.
719 * The trace should be readable and no kernel OOPS should occur.
720 */
721 void epoll_pwait_concurrent_munmap(void)
722 {
723 int ret, epollfd, i, fds[MAX_FDS];
724 char buf[BUF_SIZE];
725 struct epoll_event *epoll_event;
726 void *addr = NULL;
727 pthread_t writer;
728
729
730 epollfd = epoll_create(MAX_FDS);
731 if (epollfd < 0) {
732 perror("[eppoll] create");
733 goto end;
734 }
735
736 epoll_event = mmap(addr, MAX_FDS * sizeof(struct epoll_event),
737 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
738 -1, 0);
739 if (epoll_event == MAP_FAILED) {
740 perror("mmap");
741 goto end;
742 }
743
744 for (i = 0; i < MAX_FDS; i++) {
745 fds[i] = dup(wait_fd);
746 if (fds[i] < 0) {
747 perror("dup");
748 }
749 epoll_event[i].events = EPOLLIN | EPOLLPRI | EPOLLET;
750 epoll_event[i].data.fd = fds[i];
751 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], epoll_event);
752 if (ret < 0) {
753 perror("[eppoll] add");
754 goto end_unmap;
755 }
756 }
757 stop_thread = 0;
758 ret = pthread_create(&writer, NULL, &epoll_pwait_writer,
759 (void *) epoll_event);
760 if (ret != 0) {
761 fprintf(stderr, "[error] pthread_create\n");
762 goto end;
763 }
764
765 ret = epoll_pwait(epollfd, epoll_event, 1, 1, NULL);
766
767 if (ret == 1) {
768 printf("# [eppoll] data available\n");
769 ret = read(wait_fd, buf, BUF_SIZE);
770 if (ret < 0) {
771 perror("[eppoll] read");
772 }
773 } else if (ret == 0) {
774 printf("# [eppoll] timeout\n");
775 } else {
776 perror("# epoll_pwait");
777 }
778
779 stop_thread = 1;
780 ret = pthread_join(writer, NULL);
781 if (ret) {
782 fprintf(stderr, "[error] pthread_join\n");
783 goto end_unmap;
784 }
785 end_unmap:
786 for (i = 0; i < MAX_FDS; i++) {
787 ret = close(fds[i]);
788 if (ret != 0) {
789 perror("close");
790 }
791 }
792
793 ret = munmap(addr, MAX_FDS * sizeof(struct epoll_event));
794 if (ret != 0) {
795 perror("munmap");
796 }
797
798 end:
799 return;
800 }
801
802 void usage(poptContext optCon, int exitcode, char *error, char *addl)
803 {
804 poptPrintUsage(optCon, stderr, 0);
805 if (error) {
806 fprintf(stderr, "%s: %s\n", error, addl);
807 }
808 exit(exitcode);
809 }
810
811 void print_list(void)
812 {
813 fprintf(stderr, "Test list (-t X):\n");
814 fprintf(stderr, "\t1: Working cases for select, pselect6, poll, ppoll "
815 "and epoll, waiting for input\n");
816 fprintf(stderr, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
817 "ppoll and epoll\n");
818 fprintf(stderr, "\t3: pselect with a FD > 1023\n");
819 fprintf(stderr, "\t4: ppoll with %d FDs\n", MAX_FDS);
820 fprintf(stderr, "\t5: ppoll buffer overflow, should segfault, waits "
821 "for input\n");
822 fprintf(stderr, "\t6: pselect with invalid pointer, waits for "
823 "input\n");
824 fprintf(stderr, "\t7: ppoll with ulong_max fds, waits for input\n");
825 fprintf(stderr, "\t8: epoll_pwait with invalid pointer, waits for "
826 "input\n");
827 fprintf(stderr, "\t9: epoll_pwait with maxevents set to INT_MAX, "
828 "waits for input\n");
829 fprintf(stderr, "\t10: ppoll with concurrent updates of the structure "
830 "from user-space, stress test (3000 iterations), "
831 "waits for input + timeout 1ms\n");
832 fprintf(stderr, "\t11: epoll_pwait with concurrent munmap of the buffer "
833 "from user-space, should randomly segfault, run "
834 "multiple times, waits for input + timeout 1ms\n");
835 }
836
837 int main(int argc, const char **argv)
838 {
839 int c, ret, test = -1;
840 poptContext optCon;
841 struct rlimit open_lim;
842
843 struct poptOption optionsTable[] = {
844 { "test", 't', POPT_ARG_INT, &test, 0,
845 "Test to run", NULL },
846 { "list", 'l', 0, 0, 'l',
847 "List of tests (-t X)", NULL },
848 POPT_AUTOHELP
849 { NULL, 0, 0, NULL, 0 }
850 };
851
852 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
853
854 if (argc < 2) {
855 poptPrintUsage(optCon, stderr, 0);
856 ret = -1;
857 goto end;
858 }
859
860 ret = 0;
861
862 while ((c = poptGetNextOpt(optCon)) >= 0) {
863 switch(c) {
864 case 'l':
865 print_list();
866 goto end;
867 }
868 }
869
870 open_lim.rlim_cur = MAX_FDS + MIN_NR_FDS;
871 open_lim.rlim_max = MAX_FDS + MIN_NR_FDS;
872
873 ret = setrlimit(RLIMIT_NOFILE, &open_lim);
874 if (ret < 0) {
875 perror("setrlimit");
876 goto end;
877 }
878
879 /*
880 * Some tests might segfault, but we need the getpid() to be output
881 * for the validation, disabling the buffering on stdout works.
882 */
883 setbuf(stdout, NULL);
884 printf("%d\n", getpid());
885
886 wait_fd = STDIN_FILENO;
887
888 switch(test) {
889 case 1:
890 timeout = -1;
891 run_working_cases();
892 break;
893 case 2:
894 timeout = 1;
895 run_working_cases();
896 break;
897 case 3:
898 pselect_fd_too_big();
899 break;
900 case 4:
901 test_ppoll_big();
902 break;
903 case 5:
904 ppoll_fds_buffer_overflow();
905 break;
906 case 6:
907 pselect_invalid_pointer();
908 break;
909 case 7:
910 ppoll_fds_ulong_max();
911 break;
912 case 8:
913 epoll_pwait_invalid_pointer();
914 break;
915 case 9:
916 epoll_pwait_int_max();
917 break;
918 case 10:
919 ppoll_concurrent_write();
920 break;
921 case 11:
922 epoll_pwait_concurrent_munmap();
923 break;
924 default:
925 poptPrintUsage(optCon, stderr, 0);
926 ret = -1;
927 break;
928 }
929
930 end:
931 poptFreeContext(optCon);
932 return ret;
933 }
This page took 0.049499 seconds and 6 git commands to generate.