(root)/
glibc-2.38/
sysdeps/
pthread/
tst-sem16.c
       1  /* Test for sem_open cancellation handling: BZ #15765.
       2     Copyright (C) 2016-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 <pthread.h>
      20  #include <sys/mman.h>
      21  #include <semaphore.h>
      22  #include <stdio.h>
      23  #include <fcntl.h>
      24  #include <unistd.h>
      25  #include <errno.h>
      26  #include <stdlib.h>
      27  
      28  static sem_t sem;	/* Use to sync with thread start.  */
      29  static const char pipe_name[] = "/glibc-tst-sem16";
      30  
      31  static void
      32  remove_sem (int status, void *arg)
      33  {
      34    sem_unlink (arg);
      35  }
      36  
      37  static void *
      38  tf (void *arg)
      39  {
      40    pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0);
      41  
      42    if (sem_wait (&sem) != 0)
      43      {
      44        printf ("error: sem_wait failed: %m");
      45        exit (1);
      46      }
      47  
      48    if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0) != 0)
      49      {
      50        printf ("error: pthread_setcancelstate failed: %m");
      51        exit (1);
      52      }
      53  
      54    /* Neither sem_unlink or sem_open should act on thread cancellation.  */
      55    sem_unlink (pipe_name);
      56    on_exit (remove_sem, (void *) pipe_name);
      57  
      58    sem_t *s = sem_open (pipe_name, O_CREAT, 0600, 1);
      59    if (s == SEM_FAILED)
      60      {
      61        int exit_code;
      62        if (errno == ENOSYS || errno == EACCES)
      63  	exit_code = 77;
      64        else
      65  	exit_code = 1;
      66        exit (exit_code);
      67      }
      68  
      69    if (pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, 0) != 0)
      70      {
      71        printf ("error: pthread_setcancelstate failed: %m");
      72        exit (1);
      73      }
      74  
      75    if (sem_close (s) != 0)
      76      {
      77        printf ("error: sem_close failed: %m");
      78        exit (1);
      79      }
      80  
      81    return NULL;
      82  }
      83  
      84  static int
      85  do_test (void)
      86  {
      87    pthread_t td;
      88  
      89    if (sem_init (&sem, 0, 0))
      90      {
      91        printf ("error: sem_init failed: %m\n");
      92        exit (1);
      93      }
      94  
      95    if (pthread_create (&td, NULL, tf, NULL) != 0)
      96      {
      97        printf ("error: pthread_create failed: %m\n");
      98        exit (1);
      99      }
     100  
     101    if (pthread_cancel (td) != 0)
     102      {
     103        printf ("error: pthread_cancel failed: %m\n");
     104        exit (1);
     105      }
     106  
     107    if (sem_post (&sem) != 0)
     108      {
     109        printf ("error: sem_post failed: %m\n");
     110        exit (1);
     111      }
     112  
     113    void *r;
     114    if (pthread_join (td, &r) != 0)
     115      {
     116        printf ("error: pthread_join failed: %m\n");
     117        exit (1);
     118      }
     119  
     120    if (r == PTHREAD_CANCELED)
     121      {
     122        puts ("error: pthread_join returned PTHREAD_CANCELED");
     123        exit (1);
     124      }
     125  
     126    return 0;
     127  }
     128  
     129  #define TEST_FUNCTION do_test ()
     130  #include <test-skeleton.c>