1/* 2 * Copyright (C) 2015 Cyril Hrubis <chrubis@suse.cz> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19/* 20 * Check that select() timeouts correctly. 21 */ 22#include <unistd.h> 23#include <errno.h> 24#include <sys/time.h> 25#include <sys/types.h> 26#include <fcntl.h> 27 28#include "test.h" 29#include "safe_macros.h" 30 31char *TCID = "select04"; 32int TST_TOTAL = 1; 33 34static char *opt_sleep_us; 35 36static option_t opts[] = { 37 {"s:", NULL, &opt_sleep_us}, 38 {NULL, NULL, NULL}, 39}; 40 41static void help(void); 42static void setup(void); 43static void cleanup(void); 44 45static int fds[2]; 46 47int main(int ac, char **av) 48{ 49 int lc, treshold; 50 long long elapsed_us, sleep_us = 100000; 51 struct timeval timeout; 52 fd_set sfds; 53 54 tst_parse_opts(ac, av, opts, help); 55 56 if (opt_sleep_us) { 57 sleep_us = atoll(opt_sleep_us); 58 59 if (sleep_us == 0) { 60 tst_brkm(TBROK, NULL, "Invalid timeout '%s'", 61 opt_sleep_us); 62 } 63 } 64 65 treshold = sleep_us / 100 + 20000; 66 67 setup(); 68 69 FD_ZERO(&sfds); 70 71 for (lc = 0; TEST_LOOPING(lc); lc++) { 72 FD_SET(fds[0], &sfds); 73 timeout = tst_us_to_timeval(sleep_us); 74 75 tst_timer_start(CLOCK_MONOTONIC); 76 TEST(select(1, &sfds, NULL, NULL, &timeout)); 77 tst_timer_stop(); 78 79 if (TEST_RETURN != 0) { 80 tst_resm(TFAIL, "select() haven't timeouted ret=%li", 81 TEST_RETURN); 82 continue; 83 } 84 85 elapsed_us = tst_timer_elapsed_us(); 86 87 if (elapsed_us < sleep_us) { 88 tst_resm(TFAIL, 89 "select() woken up too early %llius, expected %llius", 90 elapsed_us, sleep_us); 91 continue; 92 } 93 94 if (elapsed_us - sleep_us > treshold) { 95 tst_resm(TFAIL, 96 "select() slept too long %llius, expected %llius, threshold %i", 97 elapsed_us, sleep_us, treshold); 98 continue; 99 } 100 101 tst_resm(TPASS, "select() slept %llius, expected %llius, treshold %i", 102 elapsed_us, sleep_us, treshold); 103 } 104 105 cleanup(); 106 tst_exit(); 107} 108 109static void setup(void) 110{ 111 tst_timer_check(CLOCK_MONOTONIC); 112 113 SAFE_PIPE(NULL, fds); 114} 115 116static void cleanup(void) 117{ 118 if (close(fds[0])) 119 tst_resm(TWARN | TERRNO, "close(fds[0]) failed"); 120 121 if (close(fds[1])) 122 tst_resm(TWARN | TERRNO, "close(fds[1]) failed"); 123} 124 125static void help(void) 126{ 127 printf(" -s select() timeout lenght in us\n"); 128} 129