(root)/
glibc-2.38/
intl/
tst-gettext5.c
       1  /* Test that gettext() in multithreaded applications works correctly if
       2     different threads operate in different locales referring to the same
       3     catalog file but with different encodings.
       4     Copyright (C) 2005-2023 Free Software Foundation, Inc.
       5     This file is part of the GNU C Library.
       6  
       7     The GNU C Library is free software; you can redistribute it and/or
       8     modify it under the terms of the GNU Lesser General Public
       9     License as published by the Free Software Foundation; either
      10     version 2.1 of the License, or (at your option) any later version.
      11  
      12     The GNU C Library is distributed in the hope that it will be useful,
      13     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15     Lesser General Public License for more details.
      16  
      17     You should have received a copy of the GNU Lesser General Public
      18     License along with the GNU C Library; if not, see
      19     <https://www.gnu.org/licenses/>.  */
      20  
      21  #include <libintl.h>
      22  #include <locale.h>
      23  #include <pthread.h>
      24  #include <stdio.h>
      25  #include <stdlib.h>
      26  #include <string.h>
      27  
      28  /* Set to 1 if the program is not behaving correctly.  */
      29  int result;
      30  
      31  /* Denotes which thread should run next.  */
      32  int flipflop;
      33  /* Lock and wait queue used to switch between the threads.  */
      34  pthread_mutex_t lock;
      35  pthread_cond_t waitqueue;
      36  
      37  /* Waits until the flipflop has a given value.
      38     Before the call, the lock is unlocked.  After the call, it is locked.  */
      39  static void
      40  waitfor (int value)
      41  {
      42    if (pthread_mutex_lock (&lock))
      43      exit (10);
      44    while (flipflop != value)
      45      if (pthread_cond_wait (&waitqueue, &lock))
      46        exit (11);
      47  }
      48  
      49  /* Sets the flipflop to a given value.
      50     Before the call, the lock is locked.  After the call, it is unlocked.  */
      51  static void
      52  setto (int value)
      53  {
      54    flipflop = value;
      55    if (pthread_cond_signal (&waitqueue))
      56      exit (20);
      57    if (pthread_mutex_unlock (&lock))
      58      exit (21);
      59  }
      60  
      61  void *
      62  thread1_execution (void *arg)
      63  {
      64    char *s;
      65  
      66    waitfor (1);
      67    uselocale (newlocale (LC_ALL_MASK, "de_DE.ISO-8859-1", NULL));
      68    setto (2);
      69  
      70    /* Here we expect output in ISO-8859-1.  */
      71  
      72    waitfor (1);
      73    s = gettext ("cheese");
      74    puts (s);
      75    if (strcmp (s, "K\344se"))
      76      {
      77        fprintf (stderr, "thread 1 call 1 returned: %s\n", s);
      78        result = 1;
      79      }
      80    setto (2);
      81  
      82    waitfor (1);
      83    s = gettext ("cheese");
      84    puts (s);
      85    if (strcmp (s, "K\344se"))
      86      {
      87        fprintf (stderr, "thread 1 call 2 returned: %s\n", s);
      88        result = 1;
      89      }
      90    setto (2);
      91  
      92    return NULL;
      93  }
      94  
      95  void *
      96  thread2_execution (void *arg)
      97  {
      98    char *s;
      99  
     100    waitfor (2);
     101    uselocale (newlocale (LC_ALL_MASK, "de_DE.UTF-8", NULL));
     102    setto (1);
     103  
     104    /* Here we expect output in UTF-8.  */
     105  
     106    waitfor (2);
     107    s = gettext ("cheese");
     108    puts (s);
     109    if (strcmp (s, "K\303\244se"))
     110      {
     111        fprintf (stderr, "thread 2 call 1 returned: %s\n", s);
     112        result = 1;
     113      }
     114    setto (1);
     115  
     116    waitfor (2);
     117    s = gettext ("cheese");
     118    puts (s);
     119    if (strcmp (s, "K\303\244se"))
     120      {
     121        fprintf (stderr, "thread 2 call 2 returned: %s\n", s);
     122        result = 1;
     123      }
     124    setto (1);
     125  
     126    return NULL;
     127  }
     128  
     129  int
     130  main (void)
     131  {
     132    pthread_t thread1;
     133    pthread_t thread2;
     134  
     135    unsetenv ("LANGUAGE");
     136    unsetenv ("OUTPUT_CHARSET");
     137    textdomain ("codeset");
     138    bindtextdomain ("codeset", OBJPFX "domaindir");
     139    result = 0;
     140  
     141    flipflop = 1;
     142    if (pthread_mutex_init (&lock, NULL))
     143      exit (2);
     144    if (pthread_cond_init (&waitqueue, NULL))
     145      exit (2);
     146    if (pthread_create (&thread1, NULL, &thread1_execution, NULL))
     147      exit (2);
     148    if (pthread_create (&thread2, NULL, &thread2_execution, NULL))
     149      exit (2);
     150    if (pthread_join (thread2, NULL))
     151      exit (3);
     152  
     153    return result;
     154  }