github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/cmd/libsnap-confine-private/fault-injection.c (about)

     1  /*
     2   * Copyright (C) 2017 Canonical Ltd
     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 version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  #include "fault-injection.h"
    19  
    20  #ifdef _ENABLE_FAULT_INJECTION
    21  
    22  #include <stdlib.h>
    23  #include <string.h>
    24  
    25  struct sc_fault {
    26  	const char *name;
    27  	struct sc_fault *next;
    28  	sc_fault_fn fn;
    29  	struct sc_fault_state state;
    30  };
    31  
    32  static struct sc_fault *sc_faults = NULL;
    33  
    34  bool sc_faulty(const char *name, void *ptr)
    35  {
    36  	for (struct sc_fault * fault = sc_faults; fault != NULL;
    37  	     fault = fault->next) {
    38  		if (strcmp(name, fault->name) == 0) {
    39  			bool is_faulty = fault->fn(&fault->state, ptr);
    40  			fault->state.ncalls++;
    41  			return is_faulty;
    42  		}
    43  	}
    44  	return false;
    45  }
    46  
    47  void sc_break(const char *name, sc_fault_fn fn)
    48  {
    49  	struct sc_fault *fault = calloc(1, sizeof *fault);
    50  	if (fault == NULL) {
    51  		abort();
    52  	}
    53  	fault->name = name;
    54  	fault->next = sc_faults;
    55  	fault->fn = fn;
    56  	fault->state.ncalls = 0;
    57  	sc_faults = fault;
    58  }
    59  
    60  void sc_reset_faults(void)
    61  {
    62  	struct sc_fault *next_fault;
    63  	for (struct sc_fault * fault = sc_faults; fault != NULL;
    64  	     fault = next_fault) {
    65  		next_fault = fault->next;
    66  		free(fault);
    67  	}
    68  	sc_faults = NULL;
    69  }
    70  
    71  #else				// ifndef _ENABLE_FAULT_INJECTION
    72  
    73  bool sc_faulty(const char *name, void *ptr)
    74  {
    75  	return false;
    76  }
    77  
    78  #endif				// ifndef _ENABLE_FAULT_INJECTION