(root)/
glibc-2.38/
time/
tst-itimer.c
       1  /* Basic tests for getitimer and setitimer.
       2     Copyright (C) 2021-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <array_length.h>
      20  #include <errno.h>
      21  #include <stdlib.h>
      22  #include <sys/time.h>
      23  #include <support/check.h>
      24  #include <support/support.h>
      25  #include <support/xsignal.h>
      26  #include <unistd.h>
      27  #include <time.h>
      28  
      29  static sig_atomic_t cnt;
      30  
      31  static void
      32  alrm_handler (int sig)
      33  {
      34    if (++cnt > 3)
      35      cnt = 3;
      36  }
      37  
      38  static void
      39  intr_sleep (int sec)
      40  {
      41    struct timespec ts = { .tv_sec = sec, .tv_nsec = 0 };
      42    while (nanosleep (&ts, &ts) == -1 && errno == EINTR)
      43      ;
      44  }
      45  
      46  static int
      47  do_test (void)
      48  {
      49    struct itimerval it, it_old;
      50    const int timers[] = { ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF };
      51    for (int i = 0; i < array_length (timers); i++)
      52      {
      53        TEST_COMPARE (getitimer (timers[i], &it), 0);
      54  
      55        /* No timer set, all value should be 0.  */
      56        TEST_COMPARE (it.it_interval.tv_sec, 0);
      57        TEST_COMPARE (it.it_interval.tv_usec, 0);
      58        TEST_COMPARE (it.it_value.tv_sec, 0);
      59        TEST_COMPARE (it.it_value.tv_usec, 0);
      60  
      61        it.it_interval.tv_sec = 10;
      62        it.it_interval.tv_usec = 20;
      63        TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
      64  
      65        TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { 0 }, &it_old),
      66  		    0);
      67        /* ITIMER_REAL returns { 0, 0 } for single-shot timers, while
      68  	 other timers returns setitimer value.  */
      69        if (timers[i] == ITIMER_REAL)
      70  	{
      71  	  TEST_COMPARE (it_old.it_interval.tv_sec, 0);
      72  	  TEST_COMPARE (it_old.it_interval.tv_usec, 0);
      73  	}
      74        else
      75  	{
      76  	  TEST_COMPARE (it_old.it_interval.tv_sec, 10);
      77  	  /* Some systems might use a different precision for ITIMER_VIRTUAL
      78  	     and ITIMER_IPROF and thus the value might be adjusted.  To avoid
      79  	     trying to guess the resolution, we do not check it.  */
      80  	}
      81  
      82        /* Create a periodic timer and check if the return value is the one
      83  	 previously set.  */
      84        it.it_interval.tv_sec = 10;
      85        it.it_interval.tv_usec = 20;
      86        it.it_value.tv_sec = 30;
      87        it.it_value.tv_usec = 40;
      88        TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
      89  
      90        TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { 0 }, &it_old),
      91  		    0);
      92        TEST_COMPARE (it.it_interval.tv_sec, it_old.it_interval.tv_sec);
      93        if (timers[i] == ITIMER_REAL)
      94  	TEST_COMPARE (it.it_interval.tv_usec, it_old.it_interval.tv_usec);
      95  
      96        if (sizeof (time_t) == 4)
      97  	continue;
      98  
      99        /* Same as before, but with a 64 bit time_t value.  */
     100        it.it_interval.tv_sec = (time_t) 0x1ffffffffull;
     101        it.it_interval.tv_usec = 20;
     102        it.it_value.tv_sec = 0;
     103        it.it_value.tv_usec = 0;
     104  
     105        /* Linux does not provide 64 bit time_t support for getitimer and
     106  	 setitimer on architectures with 32 bit time_t support.  */
     107        if (support_itimer_support_time64())
     108  	{
     109  	  TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
     110  	  TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { 0 },
     111  				   &it_old),
     112  			0);
     113  	  /* ITIMER_REAL returns { 0, 0 } for single-sort timers, while other
     114  	     timers returns setitimer value.  */
     115  	  if (timers[i] == ITIMER_REAL)
     116  	    {
     117  	      TEST_COMPARE (it_old.it_interval.tv_sec, 0ull);
     118  	      TEST_COMPARE (it_old.it_interval.tv_usec, 0);
     119  	    }
     120  	}
     121        else
     122  	{
     123  	  TEST_COMPARE (setitimer (timers[i], &it, NULL), -1);
     124  	  TEST_COMPARE (errno, EOVERFLOW);
     125  	}
     126  
     127        /* Create a periodic timer and check if the return value is the one
     128  	 previously set.  */
     129        it.it_interval.tv_sec = (time_t) 0x1ffffffffull;
     130        it.it_interval.tv_usec = 20;
     131        it.it_value.tv_sec = 30;
     132        it.it_value.tv_usec = 40;
     133        if (support_itimer_support_time64())
     134  	{
     135  	  TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
     136  
     137  	  TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { 0 },
     138  				   &it_old),
     139  			0);
     140  	  if (timers[i] == ITIMER_REAL)
     141  	    {
     142  	      TEST_COMPARE (it.it_interval.tv_sec, it_old.it_interval.tv_sec);
     143  	      TEST_COMPARE (it.it_interval.tv_usec, it_old.it_interval.tv_usec);
     144  	    }
     145  	}
     146        else
     147  	{
     148  	  TEST_COMPARE (setitimer (timers[i], &it, NULL), -1);
     149  	  TEST_COMPARE (errno, EOVERFLOW);
     150  	}
     151    }
     152  
     153    {
     154      struct sigaction sa = { .sa_handler = alrm_handler, .sa_flags = 0 };
     155      sigemptyset (&sa.sa_mask);
     156      xsigaction (SIGALRM, &sa, NULL);
     157    }
     158  
     159    /* Setup a timer to 0.1s and sleep for 1s and check to 3 signal handler
     160       execution.  */
     161    it.it_interval.tv_sec = 0;
     162    it.it_interval.tv_usec = 100000;
     163    it.it_value.tv_sec = 0;
     164    it.it_value.tv_usec = 100000;
     165  
     166    /* Check ITIMER_VIRTUAL and ITIMER_PROF would require to generate load
     167       and be subject to system load.  */
     168    cnt = 0;
     169    TEST_COMPARE (setitimer (ITIMER_REAL, &it, NULL), 0);
     170    intr_sleep (1);
     171    TEST_COMPARE (cnt, 3);
     172    TEST_COMPARE (setitimer (ITIMER_REAL, &(struct itimerval) { 0 }, NULL), 0);
     173  
     174    return 0;
     175  }
     176  
     177  #include <support/test-driver.c>