(root)/
glibc-2.38/
stdlib/
tst-setcontext5.c
       1  /* Check multiple setcontext calls.
       2     Copyright (C) 2018-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 <stdio.h>
      20  #include <stdlib.h>
      21  #include <ucontext.h>
      22  #include <unistd.h>
      23  
      24  static ucontext_t ctx[2];
      25  static volatile int done;
      26  
      27  static void f2 (void);
      28  
      29  static void
      30  __attribute__ ((noinline, noclone))
      31  f1 (void)
      32  {
      33    printf ("start f1\n");
      34    f2 ();
      35  }
      36  
      37  static void
      38  __attribute__ ((noinline, noclone))
      39  f2 (void)
      40  {
      41    printf ("start f2\n");
      42    if (setcontext (&ctx[1]) != 0)
      43      {
      44        printf ("%s: setcontext: %m\n", __FUNCTION__);
      45        exit (EXIT_FAILURE);
      46      }
      47  }
      48  
      49  static void
      50  f3 (void)
      51  {
      52    printf ("start f3\n");
      53    if (done)
      54      exit (EXIT_SUCCESS);
      55    done = 1;
      56    if (setcontext (&ctx[0]) != 0)
      57      {
      58        printf ("%s: setcontext: %m\n", __FUNCTION__);
      59        exit (EXIT_FAILURE);
      60      }
      61  }
      62  
      63  static int
      64  do_test (void)
      65  {
      66    char st1[32768];
      67  
      68    puts ("making contexts");
      69    if (getcontext (&ctx[0]) != 0)
      70      {
      71        printf ("%s: getcontext: %m\n", __FUNCTION__);
      72        exit (EXIT_FAILURE);
      73      }
      74    if (getcontext (&ctx[1]) != 0)
      75      {
      76        printf ("%s: getcontext: %m\n", __FUNCTION__);
      77        exit (EXIT_FAILURE);
      78      }
      79    ctx[1].uc_stack.ss_sp = st1;
      80    ctx[1].uc_stack.ss_size = sizeof st1;
      81    ctx[1].uc_link = &ctx[0];
      82    makecontext (&ctx[1], (void (*) (void)) f3, 0);
      83    f1 ();
      84    puts ("FAIL: returned from f1 ()");
      85    exit (EXIT_FAILURE);
      86  }
      87  
      88  #include <support/test-driver.c>