root/maint/gnulib/tests/test-immutable.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. segv_handler
  2. install_segv_handler
  3. main

   1 /* Test of immutable data.
   2    Copyright (C) 2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Bruno Haible <bruno@clisp.org>, 2021.  */
  18 
  19 #include <config.h>
  20 
  21 #include "immutable.h"
  22 
  23 #include <signal.h>
  24 #include <stdbool.h>
  25 #include <stdlib.h>
  26 #include <string.h>
  27 
  28 #include "macros.h"
  29 
  30 struct data
  31 {
  32   int x;
  33   long y;
  34 };
  35 
  36 #if IMMUTABLE_EFFECTIVE
  37 
  38 static _GL_ASYNC_SAFE _Noreturn void
  39 segv_handler (int signo)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41   _Exit (0);
  42 }
  43 
  44 static void
  45 install_segv_handler (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47   signal (SIGSEGV, segv_handler);
  48 # if (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__
  49   signal (SIGBUS, segv_handler);
  50 # endif
  51 }
  52 
  53 #endif
  54 
  55 int
  56 main (int argc, char *argv[])
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58   if (argc != 2)
  59     {
  60       fprintf (stderr, "%s: need 1 argument\n", argv[0]);
  61       return 1;
  62     }
  63   int test = atoi (argv[1]);
  64   switch (test)
  65     {
  66     case 0:
  67       /* Indicates whether the implementation effectively rejects writes to
  68          immutable data.  */
  69       #if !IMMUTABLE_EFFECTIVE
  70       fputs ("Skipping test: immutability cannot be enforced\n", stderr);
  71       return 77;
  72       #else
  73       break;
  74       #endif
  75 
  76     case 1:
  77       /* Correct use of immmalloc.  */
  78       {
  79         struct data *wp;
  80         struct data const *p;
  81 
  82         wp = (struct data *) immmalloc (sizeof (struct data));
  83         ASSERT (wp != NULL);
  84         wp->x = 7;
  85         wp->y = 42;
  86         p = immfreeze (wp);
  87         ASSERT (p->x == 7);
  88         ASSERT (p->y == 42);
  89         immfree (p);
  90       }
  91       break;
  92 
  93     case 2:
  94       /* Catch invalid write access.  */
  95       {
  96         struct data *wp;
  97         struct data const *p;
  98 
  99         wp = (struct data *) immmalloc (sizeof (struct data));
 100         ASSERT (wp != NULL);
 101         wp->x = 7;
 102         wp->y = 42;
 103         p = immfreeze (wp);
 104         #if IMMUTABLE_EFFECTIVE
 105         install_segv_handler ();
 106         #endif
 107         /* This assignment should crash.  */
 108         ((struct data *) p)->y = 77;
 109         #if IMMUTABLE_EFFECTIVE
 110         return 1;
 111         #endif
 112       }
 113       break;
 114 
 115     case 3:
 116       /* Catch invalid write access while another data object is not frozen.  */
 117       {
 118         struct data *wp;
 119         struct data const *p;
 120         struct data *wp2;
 121 
 122         wp = (struct data *) immmalloc (sizeof (struct data));
 123         ASSERT (wp != NULL);
 124         wp->x = 7;
 125         wp->y = 42;
 126         p = immfreeze (wp);
 127         ASSERT (p->x == 7);
 128         ASSERT (p->y == 42);
 129 
 130         wp2 = (struct data *) immmalloc (sizeof (struct data));
 131         ASSERT (wp2 != NULL);
 132         wp2->x = 7;
 133         #if IMMUTABLE_EFFECTIVE
 134         install_segv_handler ();
 135         #endif
 136         /* This assignment should crash.  */
 137         ((struct data *) p)->y = 42;
 138         #if IMMUTABLE_EFFECTIVE
 139         return 1;
 140         #endif
 141       }
 142       break;
 143 
 144     case 4:
 145       /* Correct use of immstrdup.  */
 146       {
 147         const char *s = immstrdup ("Hello");
 148         ASSERT (strlen (s) == 5);
 149         ASSERT (strcmp (s, "Hello") == 0);
 150         immfree (s);
 151       }
 152       break;
 153 
 154     default:
 155       ASSERT (false);
 156     }
 157   return 0;
 158 }

/* [previous][next][first][last][top][bottom][index][help] */