Port: Add OSX support to socket compat
[lttng-tools.git] / tests / regression / kernel / select_poll_epoll.c
... / ...
CommitLineData
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
33static int timeout; /* seconds, -1 to disable */
34volatile static int stop_thread;
35static int wait_fd;
36
37struct ppoll_thread_data {
38 struct pollfd *ufds;
39 int value;
40};
41
42void 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
87end:
88 return;
89}
90
91void 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
124void 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
157void 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
181void 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
213void 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
252void 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
290end:
291 return;
292}
293
294void 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
332end:
333 return;
334}
335
336void 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
373end:
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 */
382void 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 */
413void 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 */
443void pselect_fd_too_big(void)
444{
445 long rfds[2048 / (sizeof(long) * CHAR_BIT)] = { 0 };
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
460 FD_SET(fd2, (fd_set *) &rfds);
461 ret = syscall(SYS_pselect6, fd2 + 1, &rfds, NULL, NULL, NULL, NULL);
462
463 if (ret == -1) {
464 perror("# pselect()");
465 } else if (ret) {
466 printf("# [pselect] data available\n");
467 ret = read(wait_fd, buf, BUF_SIZE);
468 if (ret < 0) {
469 perror("[pselect] read");
470 }
471 } else {
472 printf("# [pselect] timeout\n");
473 }
474
475}
476
477/*
478 * Invalid pointer as writefds, should output a ppoll event
479 * with 0 FDs.
480 */
481void pselect_invalid_pointer(void)
482{
483 fd_set rfds;
484 int ret;
485 char buf[BUF_SIZE];
486 void *invalid = (void *) 0x42;
487
488 FD_ZERO(&rfds);
489 FD_SET(wait_fd, &rfds);
490
491 ret = syscall(SYS_pselect6, 1, &rfds, (fd_set *) invalid, NULL, NULL,
492 NULL);
493
494 if (ret == -1) {
495 perror("# pselect()");
496 } else if (ret) {
497 printf("# [pselect] data available\n");
498 ret = read(wait_fd, buf, BUF_SIZE);
499 if (ret < 0) {
500 perror("[pselect] read");
501 }
502 } else {
503 printf("# [pselect] timeout\n");
504 }
505
506}
507
508/*
509 * Pass an invalid pointer to epoll_pwait, should fail with
510 * "Bad address", the event returns 0 FDs.
511 */
512void epoll_pwait_invalid_pointer(void)
513{
514 int ret, epollfd;
515 char buf[BUF_SIZE];
516 struct epoll_event epoll_event;
517 void *invalid = (void *) 0x42;
518
519 epollfd = epoll_create(NB_FD);
520 if (epollfd < 0) {
521 perror("[eppoll] create");
522 goto end;
523 }
524
525 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
526 epoll_event.data.fd = wait_fd;
527 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
528 if (ret < 0) {
529 perror("[eppoll] add");
530 goto end;
531 }
532
533 ret = syscall(SYS_epoll_pwait, epollfd,
534 (struct epoll_event *) invalid, 1, -1, NULL);
535
536 if (ret == 1) {
537 printf("# [eppoll] data available\n");
538 ret = read(wait_fd, buf, BUF_SIZE);
539 if (ret < 0) {
540 perror("[eppoll] read");
541 }
542 } else if (ret == 0) {
543 printf("# [eppoll] timeout\n");
544 } else {
545 perror("# epoll_pwait");
546 }
547
548end:
549 return;
550}
551
552/*
553 * Set maxevents to INT_MAX, should output "Invalid argument"
554 * The event should return an empty array.
555 */
556void epoll_pwait_int_max(void)
557{
558 int ret, epollfd;
559 char buf[BUF_SIZE];
560 struct epoll_event epoll_event;
561
562 epollfd = epoll_create(NB_FD);
563 if (epollfd < 0) {
564 perror("[eppoll] create");
565 goto end;
566 }
567
568 epoll_event.events = EPOLLIN | EPOLLPRI | EPOLLET;
569 epoll_event.data.fd = wait_fd;
570 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, wait_fd, &epoll_event);
571 if (ret < 0) {
572 perror("[eppoll] add");
573 goto end;
574 }
575
576 ret = syscall(SYS_epoll_pwait, epollfd, &epoll_event, INT_MAX, -1,
577 NULL);
578
579 if (ret == 1) {
580 printf("# [eppoll] data available\n");
581 ret = read(wait_fd, buf, BUF_SIZE);
582 if (ret < 0) {
583 perror("[eppoll] read");
584 }
585 } else if (ret == 0) {
586 printf("# [eppoll] timeout\n");
587 } else {
588 perror("# epoll_pwait");
589 }
590
591end:
592 return;
593}
594
595void *ppoll_writer(void *arg)
596{
597 struct ppoll_thread_data *data = (struct ppoll_thread_data *) arg;
598
599 while (!stop_thread) {
600 memset(data->ufds, data->value,
601 MAX_FDS * sizeof(struct pollfd));
602 usleep(100);
603 }
604
605 return NULL;
606}
607
608void do_ppoll(int *fds, struct pollfd *ufds)
609{
610 int i, ret;
611 struct timespec ts;
612 char buf[BUF_SIZE];
613
614 ts.tv_sec = 0;
615 ts.tv_nsec = 1 * MSEC_PER_NSEC;
616
617 for (i = 0; i < MAX_FDS; i++) {
618 ufds[i].fd = fds[i];
619 ufds[i].events = POLLIN|POLLPRI;
620 }
621
622 ret = ppoll(ufds, MAX_FDS, &ts, NULL);
623
624 if (ret < 0) {
625 perror("ppoll");
626 } else if (ret > 0) {
627 printf("# [ppoll] data available\n");
628 ret = read(wait_fd, buf, BUF_SIZE);
629 if (ret < 0) {
630 perror("[ppoll] read");
631 }
632 } else {
633 printf("# [ppoll] timeout\n");
634 }
635}
636
637void stress_ppoll(int *fds, int value)
638{
639 pthread_t writer;
640 int iter, ret;
641 struct ppoll_thread_data thread_data;
642 struct pollfd ufds[MAX_FDS];
643
644 thread_data.ufds = ufds;
645 thread_data.value = value;
646
647 stop_thread = 0;
648 ret = pthread_create(&writer, NULL, &ppoll_writer, (void *) &thread_data);
649 if (ret != 0) {
650 fprintf(stderr, "[error] pthread_create\n");
651 goto end;
652 }
653 for (iter = 0; iter < NR_ITER; iter++) {
654 do_ppoll(fds, ufds);
655 }
656 stop_thread = 1;
657 ret = pthread_join(writer, NULL);
658 if (ret) {
659 fprintf(stderr, "[error] pthread_join\n");
660 goto end;
661 }
662end:
663 return;
664}
665
666/*
667 * 3 rounds of NR_ITER iterations with concurrent updates of the pollfd
668 * structure:
669 * - memset to 0
670 * - memset to 1
671 * - memset to INT_MAX
672 * Waits for input, but also set a timeout in case the input FD is overwritten
673 * before entering in the syscall. We use MAX_FDS FDs (dup of stdin), so the
674 * resulting trace is big (20MB).
675 *
676 * ppoll should work as expected and the trace should be readable at the end.
677 */
678void ppoll_concurrent_write(void)
679{
680 int i, ret, fds[MAX_FDS];
681
682 for (i = 0; i < MAX_FDS; i++) {
683 fds[i] = dup(wait_fd);
684 if (fds[i] < 0) {
685 perror("dup");
686 }
687 }
688
689 stress_ppoll(fds, 0);
690 stress_ppoll(fds, 1);
691 stress_ppoll(fds, INT_MAX);
692
693 for (i = 0; i < MAX_FDS; i++) {
694 ret = close(fds[i]);
695 if (ret != 0) {
696 perror("close");
697 }
698 }
699
700 return;
701}
702
703void *epoll_pwait_writer(void *addr)
704{
705 srand(time(NULL));
706
707 while (!stop_thread) {
708 usleep(rand() % 30);
709 munmap(addr, MAX_FDS * sizeof(struct epoll_event));
710 }
711
712 return NULL;
713}
714
715/*
716 * epoll_pwait on MAX_FDS fds while a concurrent thread munmaps the
717 * buffer allocated for the returned data. This should randomly segfault.
718 * The trace should be readable and no kernel OOPS should occur.
719 */
720void epoll_pwait_concurrent_munmap(void)
721{
722 int ret, epollfd, i, fds[MAX_FDS];
723 char buf[BUF_SIZE];
724 struct epoll_event *epoll_event;
725 pthread_t writer;
726
727 epollfd = epoll_create(MAX_FDS);
728 if (epollfd < 0) {
729 perror("[eppoll] create");
730 goto end;
731 }
732
733 epoll_event = mmap(NULL, MAX_FDS * sizeof(struct epoll_event),
734 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
735 -1, 0);
736 if (epoll_event == MAP_FAILED) {
737 perror("mmap");
738 goto end;
739 }
740
741 for (i = 0; i < MAX_FDS; i++) {
742 fds[i] = dup(wait_fd);
743 if (fds[i] < 0) {
744 perror("dup");
745 }
746 epoll_event[i].events = EPOLLIN | EPOLLPRI | EPOLLET;
747 epoll_event[i].data.fd = fds[i];
748 ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fds[i], epoll_event);
749 if (ret < 0) {
750 perror("[eppoll] add");
751 goto end_unmap;
752 }
753 }
754 stop_thread = 0;
755 ret = pthread_create(&writer, NULL, &epoll_pwait_writer,
756 (void *) epoll_event);
757 if (ret != 0) {
758 fprintf(stderr, "[error] pthread_create\n");
759 goto end_unmap;
760 }
761
762 ret = epoll_pwait(epollfd, epoll_event, 1, 1, NULL);
763
764 if (ret == 1) {
765 printf("# [eppoll] data available\n");
766 ret = read(wait_fd, buf, BUF_SIZE);
767 if (ret < 0) {
768 perror("[eppoll] read");
769 }
770 } else if (ret == 0) {
771 printf("# [eppoll] timeout\n");
772 } else {
773 perror("# epoll_pwait");
774 }
775
776 stop_thread = 1;
777 ret = pthread_join(writer, NULL);
778 if (ret) {
779 fprintf(stderr, "[error] pthread_join\n");
780 goto end_unmap;
781 }
782end_unmap:
783 for (i = 0; i < MAX_FDS; i++) {
784 ret = close(fds[i]);
785 if (ret != 0) {
786 perror("close");
787 }
788 }
789
790 ret = munmap(epoll_event, MAX_FDS * sizeof(struct epoll_event));
791 if (ret != 0) {
792 perror("munmap");
793 }
794
795end:
796 return;
797}
798
799void usage(poptContext optCon, int exitcode, char *error, char *addl)
800{
801 poptPrintUsage(optCon, stderr, 0);
802 if (error) {
803 fprintf(stderr, "%s: %s\n", error, addl);
804 }
805 exit(exitcode);
806}
807
808void print_list(void)
809{
810 fprintf(stderr, "Test list (-t X):\n");
811 fprintf(stderr, "\t1: Working cases for select, pselect6, poll, ppoll "
812 "and epoll, waiting for input\n");
813 fprintf(stderr, "\t2: Timeout cases (1ms) for select, pselect6, poll, "
814 "ppoll and epoll\n");
815 fprintf(stderr, "\t3: pselect with a FD > 1023\n");
816 fprintf(stderr, "\t4: ppoll with %d FDs\n", MAX_FDS);
817 fprintf(stderr, "\t5: ppoll buffer overflow, should segfault, waits "
818 "for input\n");
819 fprintf(stderr, "\t6: pselect with invalid pointer, waits for "
820 "input\n");
821 fprintf(stderr, "\t7: ppoll with ulong_max fds, waits for input\n");
822 fprintf(stderr, "\t8: epoll_pwait with invalid pointer, waits for "
823 "input\n");
824 fprintf(stderr, "\t9: epoll_pwait with maxevents set to INT_MAX, "
825 "waits for input\n");
826 fprintf(stderr, "\t10: ppoll with concurrent updates of the structure "
827 "from user-space, stress test (3000 iterations), "
828 "waits for input + timeout 1ms\n");
829 fprintf(stderr, "\t11: epoll_pwait with concurrent munmap of the buffer "
830 "from user-space, should randomly segfault, run "
831 "multiple times, waits for input + timeout 1ms\n");
832}
833
834int main(int argc, const char **argv)
835{
836 int c, ret, test = -1;
837 poptContext optCon;
838 struct rlimit open_lim;
839
840 struct poptOption optionsTable[] = {
841 { "test", 't', POPT_ARG_INT, &test, 0,
842 "Test to run", NULL },
843 { "list", 'l', 0, 0, 'l',
844 "List of tests (-t X)", NULL },
845 POPT_AUTOHELP
846 { NULL, 0, 0, NULL, 0 }
847 };
848
849 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
850
851 if (argc < 2) {
852 poptPrintUsage(optCon, stderr, 0);
853 ret = -1;
854 goto end;
855 }
856
857 ret = 0;
858
859 while ((c = poptGetNextOpt(optCon)) >= 0) {
860 switch(c) {
861 case 'l':
862 print_list();
863 goto end;
864 }
865 }
866
867 open_lim.rlim_cur = MAX_FDS + MIN_NR_FDS;
868 open_lim.rlim_max = MAX_FDS + MIN_NR_FDS;
869
870 ret = setrlimit(RLIMIT_NOFILE, &open_lim);
871 if (ret < 0) {
872 perror("setrlimit");
873 goto end;
874 }
875
876 /*
877 * Some tests might segfault, but we need the getpid() to be output
878 * for the validation, disabling the buffering on stdout works.
879 */
880 setbuf(stdout, NULL);
881 printf("%d\n", getpid());
882
883 wait_fd = STDIN_FILENO;
884
885 switch(test) {
886 case 1:
887 timeout = -1;
888 run_working_cases();
889 break;
890 case 2:
891 timeout = 1;
892 run_working_cases();
893 break;
894 case 3:
895 pselect_fd_too_big();
896 break;
897 case 4:
898 test_ppoll_big();
899 break;
900 case 5:
901 ppoll_fds_buffer_overflow();
902 break;
903 case 6:
904 pselect_invalid_pointer();
905 break;
906 case 7:
907 ppoll_fds_ulong_max();
908 break;
909 case 8:
910 epoll_pwait_invalid_pointer();
911 break;
912 case 9:
913 epoll_pwait_int_max();
914 break;
915 case 10:
916 ppoll_concurrent_write();
917 break;
918 case 11:
919 epoll_pwait_concurrent_munmap();
920 break;
921 default:
922 poptPrintUsage(optCon, stderr, 0);
923 ret = -1;
924 break;
925 }
926
927end:
928 poptFreeContext(optCon);
929 return ret;
930}
This page took 0.026616 seconds and 4 git commands to generate.