(root)/
glibc-2.38/
rt/
tst-aio4.c
       1  /* Test for completion signal handling.
       2     Copyright (C) 2000-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 <aio.h>
      20  #include <signal.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <unistd.h>
      24  #include <errno.h>
      25  
      26  int my_signo;
      27  
      28  volatile sig_atomic_t flag;
      29  
      30  
      31  static void
      32  sighandler (const int signo)
      33  {
      34    flag = signo;
      35  }
      36  
      37  static int
      38  wait_flag (void)
      39  {
      40    while (flag == 0)
      41      {
      42        puts ("Sleeping...");
      43        sleep (1);
      44      }
      45  
      46    if (flag != my_signo)
      47      {
      48        printf ("signal handler received wrong signal, flag is %d\n", flag);
      49        return 1;
      50      }
      51  
      52    return 0;
      53  }
      54  
      55  #ifndef SIGRTMIN
      56  # define SIGRTMIN -1
      57  # define SIGRTMAX -1
      58  #endif
      59  
      60  static int
      61  do_test (int argc, char *argv[])
      62  {
      63    char name[] = "/tmp/aio4.XXXXXX";
      64    int fd;
      65    struct aiocb *arr[1];
      66    struct aiocb cb;
      67    static const char buf[] = "Hello World\n";
      68    struct aioinit init = {10, 20, 0};
      69    struct sigaction sa;
      70    struct sigevent ev;
      71  
      72    if (SIGRTMIN == -1)
      73    {
      74        printf ("RT signals not supported.\n");
      75        return 0;
      76    }
      77  
      78    /* Select a signal from the middle of the available choices... */
      79    my_signo = (SIGRTMAX + SIGRTMIN) / 2;
      80  
      81    fd = mkstemp (name);
      82    if (fd == -1)
      83      {
      84        printf ("cannot open temp name: %m\n");
      85        return 1;
      86      }
      87  
      88    unlink (name);
      89  
      90    /* Test also aio_init.  */
      91    aio_init (&init);
      92  
      93    arr[0] = &cb;
      94  
      95    cb.aio_fildes = fd;
      96    cb.aio_lio_opcode = LIO_WRITE;
      97    cb.aio_reqprio = 0;
      98    cb.aio_buf = (void *) buf;
      99    cb.aio_nbytes = sizeof (buf) - 1;
     100    cb.aio_offset = 0;
     101    cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
     102    cb.aio_sigevent.sigev_notify_function = NULL;
     103    cb.aio_sigevent.sigev_notify_attributes = NULL;
     104    cb.aio_sigevent.sigev_signo = my_signo;
     105    cb.aio_sigevent.sigev_value.sival_ptr = NULL;
     106  
     107    ev.sigev_notify = SIGEV_SIGNAL;
     108    ev.sigev_notify_function = NULL;
     109    ev.sigev_notify_attributes = NULL;
     110    ev.sigev_signo = my_signo;
     111  
     112    sa.sa_handler = sighandler;
     113    sigemptyset (&sa.sa_mask);
     114    sa.sa_flags = SA_RESTART;
     115  
     116    if (sigaction (my_signo, &sa, NULL) < 0)
     117      {
     118        printf ("sigaction failed: %m\n");
     119        return 1;
     120      }
     121  
     122    flag = 0;
     123    /* First use aio_write.  */
     124    if (aio_write (arr[0]) < 0)
     125      {
     126        if (errno == ENOSYS)
     127  	{
     128  	  puts ("no aio support in this configuration");
     129  	  return 0;
     130  	}
     131        printf ("aio_write failed: %m\n");
     132        return 1;
     133      }
     134  
     135    if (wait_flag ())
     136      return 1;
     137  
     138    puts ("aio_write OK");
     139  
     140    flag = 0;
     141    /* Again with lio_listio.  */
     142    if (lio_listio (LIO_NOWAIT, arr, 1, &ev) < 0)
     143      {
     144        printf ("lio_listio failed: %m\n");
     145        return 1;
     146      }
     147  
     148    if (wait_flag ())
     149      return 1;
     150  
     151    puts ("all OK");
     152  
     153    return 0;
     154  }
     155  
     156  #include "../test-skeleton.c"