(root)/
glibc-2.38/
sysdeps/
pthread/
eintr.c
       1  /* Copyright (C) 2003-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library 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 the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <pthread.h>
      19  #include <signal.h>
      20  #include <unistd.h>
      21  #include <support/xthread.h>
      22  #include <support/xsignal.h>
      23  #include <support/xthread.h>
      24  
      25  
      26  static int the_sig;
      27  
      28  
      29  static void
      30  eintr_handler (int sig)
      31  {
      32    if (sig != the_sig)
      33      {
      34        /* empty if statement avoids warn unused result */
      35        if (write (STDOUT_FILENO,
      36  		 "eintr_handler: signal number wrong\n", 35) < 35) {};
      37        _exit (1);
      38      }
      39    if (write (STDOUT_FILENO, ".", 1)) {/* Avoid warn unused result */};
      40  }
      41  
      42  
      43  static void *
      44  eintr_source (void *arg)
      45  {
      46    struct timespec ts = { .tv_sec = 0, .tv_nsec = 500000 };
      47  
      48    if (arg == NULL)
      49      {
      50        sigset_t ss;
      51        sigemptyset (&ss);
      52        sigaddset (&ss, the_sig);
      53        xpthread_sigmask (SIG_BLOCK, &ss, NULL);
      54      }
      55  
      56    while (1)
      57      {
      58        if (arg != NULL)
      59  	pthread_kill (*(pthread_t *) arg, the_sig);
      60        else
      61  	kill (getpid (), the_sig);
      62  
      63        nanosleep (&ts, NULL);
      64      }
      65  
      66    /* NOTREACHED */
      67    return NULL;
      68  }
      69  
      70  
      71  static void
      72  setup_eintr (int sig, pthread_t *thp)
      73  {
      74    struct sigaction sa;
      75    sigemptyset (&sa.sa_mask);
      76    sa.sa_flags = 0;
      77    sa.sa_handler = eintr_handler;
      78    if (sigaction (sig, &sa, NULL) != 0)
      79      {
      80        puts ("setup_eintr: sigaction failed");
      81        exit (1);
      82      }
      83    the_sig = sig;
      84  
      85    /* Create the thread which will fire off the signals.  */
      86    xpthread_create (NULL, eintr_source, thp);
      87  }