(root)/
glibc-2.38/
stdlib/
tst-setcontext7.c
       1  /* Check setcontext on the context from makecontext.
       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  #include <stdatomic.h>
      24  
      25  static ucontext_t ctx[5];
      26  static atomic_int done;
      27  
      28  static void
      29  f1 (void)
      30  {
      31    puts ("start f1");
      32    if (!done)
      33      {
      34        if (getcontext (&ctx[2]) != 0)
      35  	{
      36  	  printf ("%s: getcontext: %m\n", __FUNCTION__);
      37  	  exit (EXIT_FAILURE);
      38  	}
      39        if (done)
      40  	{
      41  	  puts ("set context in f1");
      42  	  if (setcontext (&ctx[3]) != 0)
      43  	    {
      44  	      printf ("%s: setcontext: %m\n", __FUNCTION__);
      45  	      exit (EXIT_FAILURE);
      46  	    }
      47  	}
      48      }
      49    done++;
      50    puts ("swap contexts in f1");
      51    if (swapcontext (&ctx[4], &ctx[2]) != 0)
      52      {
      53        printf ("%s: setcontext: %m\n", __FUNCTION__);
      54        exit (EXIT_FAILURE);
      55      }
      56    puts ("end f1");
      57    exit (done == 2 ? EXIT_SUCCESS : EXIT_FAILURE);
      58  }
      59  
      60  static int
      61  do_test (void)
      62  {
      63    char st1[32768];
      64    puts ("making contexts");
      65    if (getcontext (&ctx[0]) != 0)
      66      {
      67        printf ("%s: getcontext: %m\n", __FUNCTION__);
      68        exit (EXIT_FAILURE);
      69      }
      70    if (getcontext (&ctx[1]) != 0)
      71      {
      72        printf ("%s: getcontext: %m\n", __FUNCTION__);
      73        exit (EXIT_FAILURE);
      74      }
      75    ctx[1].uc_stack.ss_sp = st1;
      76    ctx[1].uc_stack.ss_size = sizeof st1;
      77    ctx[1].uc_link = &ctx[0];
      78    makecontext (&ctx[1], (void (*) (void)) f1, 0);
      79    puts ("swap contexts");
      80    if (swapcontext (&ctx[3], &ctx[1]) != 0)
      81      {
      82        printf ("%s: setcontext: %m\n", __FUNCTION__);
      83        exit (EXIT_FAILURE);
      84      }
      85    if (done != 1)
      86      exit (EXIT_FAILURE);
      87    done++;
      88    puts ("set context");
      89    if (setcontext (&ctx[4]) != 0)
      90      {
      91        printf ("%s: setcontext: %m\n", __FUNCTION__);
      92        exit (EXIT_FAILURE);
      93      }
      94    exit (EXIT_FAILURE);
      95  }
      96  
      97  #include <support/test-driver.c>