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