Update Files
This commit is contained in:
		
							
								
								
									
										447
									
								
								Kinc/Sources/kinc/libs/system/fault-injection/fault-injection.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								Kinc/Sources/kinc/libs/system/fault-injection/fault-injection.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,447 @@
 | 
			
		||||
/*
 | 
			
		||||
 * lws System Fault Injection
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to
 | 
			
		||||
 * deal in the Software without restriction, including without limitation the
 | 
			
		||||
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 | 
			
		||||
 * sell copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 | 
			
		||||
 * IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "private-lib-core.h"
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
static lws_fi_priv_t *
 | 
			
		||||
lws_fi_lookup(const lws_fi_ctx_t *fic, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	lws_start_foreach_dll(struct lws_dll2 *, p, fic->fi_owner.head) {
 | 
			
		||||
		lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
 | 
			
		||||
 | 
			
		||||
		if (!strcmp(pv->fi.name, name))
 | 
			
		||||
			return pv;
 | 
			
		||||
 | 
			
		||||
	} lws_end_foreach_dll(p);
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lws_fi(const lws_fi_ctx_t *fic, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	lws_fi_priv_t *pv;
 | 
			
		||||
	int n;
 | 
			
		||||
 | 
			
		||||
	pv = lws_fi_lookup(fic, name);
 | 
			
		||||
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	switch (pv->fi.type) {
 | 
			
		||||
	case LWSFI_ALWAYS:
 | 
			
		||||
		goto inject;
 | 
			
		||||
 | 
			
		||||
	case LWSFI_DETERMINISTIC:
 | 
			
		||||
		pv->fi.times++;
 | 
			
		||||
		if (pv->fi.times >= pv->fi.pre)
 | 
			
		||||
			if (pv->fi.times < pv->fi.pre + pv->fi.count)
 | 
			
		||||
				goto inject;
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	case LWSFI_PROBABILISTIC:
 | 
			
		||||
		if (lws_xos_percent((lws_xos_t *)&fic->xos, (int)pv->fi.pre))
 | 
			
		||||
			goto inject;
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	case LWSFI_PATTERN:
 | 
			
		||||
	case LWSFI_PATTERN_ALLOC:
 | 
			
		||||
		n = (int)((pv->fi.times++) % pv->fi.count);
 | 
			
		||||
		if (pv->fi.pattern[n >> 3] & (1 << (n & 7)))
 | 
			
		||||
			goto inject;
 | 
			
		||||
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
inject:
 | 
			
		||||
	lwsl_warn("%s: Injecting fault %s->%s\n", __func__,
 | 
			
		||||
			fic->name ? fic->name : "unk", pv->fi.name);
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lws_fi_range(const lws_fi_ctx_t *fic, const char *name, uint64_t *result)
 | 
			
		||||
{
 | 
			
		||||
	lws_fi_priv_t *pv;
 | 
			
		||||
	uint64_t d;
 | 
			
		||||
 | 
			
		||||
	pv = lws_fi_lookup(fic, name);
 | 
			
		||||
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (pv->fi.type != LWSFI_RANGE) {
 | 
			
		||||
		lwsl_err("%s: fault %s is not a 123..456 range\n",
 | 
			
		||||
			 __func__, name);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	d = pv->fi.count - pv->fi.pre;
 | 
			
		||||
 | 
			
		||||
	*result = pv->fi.pre + (lws_xos((lws_xos_t *)&fic->xos) % d);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
_lws_fi_user_wsi_fi(struct lws *wsi, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return lws_fi(&wsi->fic, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
_lws_fi_user_context_fi(struct lws_context *ctx, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return lws_fi(&ctx->fic, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(LWS_WITH_SECURE_STREAMS)
 | 
			
		||||
int
 | 
			
		||||
_lws_fi_user_ss_fi(struct lws_ss_handle *h, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return lws_fi(&h->fic, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(LWS_WITH_SECURE_STREAMS_PROXY_API)
 | 
			
		||||
int
 | 
			
		||||
_lws_fi_user_sspc_fi(struct lws_sspc_handle *h, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	return lws_fi(&h->fic, name);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
lws_fi_add(lws_fi_ctx_t *fic, const lws_fi_t *fi)
 | 
			
		||||
{
 | 
			
		||||
	lws_fi_priv_t *pv;
 | 
			
		||||
	size_t n = strlen(fi->name);
 | 
			
		||||
 | 
			
		||||
	pv = lws_malloc(sizeof(*pv) + n + 1, __func__);
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	lws_dll2_clear(&pv->list);
 | 
			
		||||
 | 
			
		||||
	memcpy(&pv->fi, fi, sizeof(*fi));
 | 
			
		||||
	pv->fi.name = (const char *)&pv[1];
 | 
			
		||||
	memcpy(&pv[1], fi->name, n + 1);
 | 
			
		||||
 | 
			
		||||
	lws_dll2_add_tail(&pv->list, &fic->fi_owner);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_remove(lws_fi_ctx_t *fic, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	lws_fi_priv_t *pv = lws_fi_lookup(fic, name);
 | 
			
		||||
 | 
			
		||||
	if (!pv)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	lws_dll2_remove(&pv->list);
 | 
			
		||||
	lws_free(pv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	/* inherit the PRNG seed for our context from source guy too */
 | 
			
		||||
	lws_xos_init(&fic_dest->xos, lws_xos((lws_xos_t *)&fic_src->xos));
 | 
			
		||||
 | 
			
		||||
	lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,
 | 
			
		||||
				   fic_src->fi_owner.head) {
 | 
			
		||||
		lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
 | 
			
		||||
 | 
			
		||||
		lws_dll2_remove(&pv->list);
 | 
			
		||||
		lws_dll2_add_tail(&pv->list, &fic_dest->fi_owner);
 | 
			
		||||
 | 
			
		||||
	} lws_end_foreach_dll_safe(p, p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
do_inherit(lws_fi_ctx_t *fic_dest, lws_fi_t *pfi, size_t trim)
 | 
			
		||||
{
 | 
			
		||||
	lws_fi_t fi = *pfi;
 | 
			
		||||
 | 
			
		||||
	fi.name += trim;
 | 
			
		||||
 | 
			
		||||
	lwsl_info("%s: %s: %s inherited as %s\n", __func__, fic_dest->name,
 | 
			
		||||
		  pfi->name, fi.name);
 | 
			
		||||
 | 
			
		||||
	if (fi.type == LWSFI_PATTERN_ALLOC) {
 | 
			
		||||
		fi.pattern = lws_malloc((size_t)((fi.count >> 3) + 1), __func__);
 | 
			
		||||
		if (!fi.pattern)
 | 
			
		||||
			return;
 | 
			
		||||
		memcpy((uint8_t *)fi.pattern, pfi->pattern,
 | 
			
		||||
		       (size_t)((fi.count >> 3) + 1));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lws_fi_add(fic_dest, &fi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_inherit_copy(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src,
 | 
			
		||||
		    const char *scope, const char *value)
 | 
			
		||||
{
 | 
			
		||||
	size_t sl = 0, vl = 0;
 | 
			
		||||
 | 
			
		||||
	if (scope)
 | 
			
		||||
		sl = strlen(scope);
 | 
			
		||||
 | 
			
		||||
	if (value)
 | 
			
		||||
		vl = strlen(value);
 | 
			
		||||
 | 
			
		||||
	lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,
 | 
			
		||||
				   fic_src->fi_owner.head) {
 | 
			
		||||
		lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
 | 
			
		||||
		size_t nl = strlen(pv->fi.name);
 | 
			
		||||
 | 
			
		||||
		if (!scope)
 | 
			
		||||
			do_inherit(fic_dest, &pv->fi, 0);
 | 
			
		||||
		else
 | 
			
		||||
			if (nl > sl + 2 &&
 | 
			
		||||
			    !strncmp(pv->fi.name, scope, sl) &&
 | 
			
		||||
			    pv->fi.name[sl] == '/')
 | 
			
		||||
				do_inherit(fic_dest, &pv->fi, sl + 1);
 | 
			
		||||
			else {
 | 
			
		||||
				if (value && nl > sl + vl + 2 &&
 | 
			
		||||
				    pv->fi.name[sl] == '=' &&
 | 
			
		||||
				    !strncmp(pv->fi.name + sl + 1, value, vl) &&
 | 
			
		||||
				    pv->fi.name[sl + 1 + vl] == '/')
 | 
			
		||||
					do_inherit(fic_dest, &pv->fi, sl + vl + 2);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	} lws_end_foreach_dll_safe(p, p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_destroy(const lws_fi_ctx_t *fic)
 | 
			
		||||
{
 | 
			
		||||
	lws_start_foreach_dll_safe(struct lws_dll2 *, p, p1,
 | 
			
		||||
				   fic->fi_owner.head) {
 | 
			
		||||
		lws_fi_priv_t *pv = lws_container_of(p, lws_fi_priv_t, list);
 | 
			
		||||
 | 
			
		||||
		if (pv->fi.type == LWSFI_PATTERN_ALLOC && pv->fi.pattern) {
 | 
			
		||||
			lws_free((void *)pv->fi.pattern);
 | 
			
		||||
			pv->fi.pattern = NULL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		lws_dll2_remove(&pv->list);
 | 
			
		||||
		lws_free(pv);
 | 
			
		||||
 | 
			
		||||
	} lws_end_foreach_dll_safe(p, p1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * We want to support these kinds of qualifier
 | 
			
		||||
 *
 | 
			
		||||
 * myfault            true always
 | 
			
		||||
 * myfault(10%)       true 10% of the time
 | 
			
		||||
 * myfault(....X X)   true when X
 | 
			
		||||
 * myfault2(20..3000)  pick a number between 20 and 3000
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	PARSE_NAME,
 | 
			
		||||
	PARSE_WHEN,
 | 
			
		||||
	PARSE_PC,
 | 
			
		||||
	PARSE_ENDBR,
 | 
			
		||||
	PARSE_COMMA
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_deserialize(lws_fi_ctx_t *fic, const char *sers)
 | 
			
		||||
{
 | 
			
		||||
	int state = PARSE_NAME, m;
 | 
			
		||||
	struct lws_tokenize ts;
 | 
			
		||||
	lws_fi_t fi;
 | 
			
		||||
	char nm[64];
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Go through the comma-separated list of faults
 | 
			
		||||
	 * creating them and adding to the lws_context info
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	lws_tokenize_init(&ts, sers, LWS_TOKENIZE_F_DOT_NONTERM |
 | 
			
		||||
				     LWS_TOKENIZE_F_NO_INTEGERS |
 | 
			
		||||
				     LWS_TOKENIZE_F_NO_FLOATS |
 | 
			
		||||
				     LWS_TOKENIZE_F_EQUALS_NONTERM |
 | 
			
		||||
				     LWS_TOKENIZE_F_SLASH_NONTERM |
 | 
			
		||||
				     LWS_TOKENIZE_F_MINUS_NONTERM);
 | 
			
		||||
	ts.len = (unsigned int)strlen(sers);
 | 
			
		||||
	if (ts.len < 1 || ts.len > 10240)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		ts.e = (int8_t)lws_tokenize(&ts);
 | 
			
		||||
		switch (ts.e) {
 | 
			
		||||
		case LWS_TOKZE_TOKEN:
 | 
			
		||||
 | 
			
		||||
			if (state == PARSE_NAME) {
 | 
			
		||||
				/*
 | 
			
		||||
				 * One fault to inject looks like, eg,
 | 
			
		||||
				 *
 | 
			
		||||
				 *   vh=xxx/listenskt
 | 
			
		||||
				 */
 | 
			
		||||
 | 
			
		||||
				memset(&fi, 0, sizeof(fi));
 | 
			
		||||
 | 
			
		||||
				lws_strnncpy(nm, ts.token, ts.token_len,
 | 
			
		||||
					     sizeof(nm));
 | 
			
		||||
				fi.name = nm;
 | 
			
		||||
				fi.type = LWSFI_ALWAYS;
 | 
			
		||||
 | 
			
		||||
				lwsl_notice("%s: name %.*s\n", __func__,
 | 
			
		||||
					    (int)ts.token_len, ts.token);
 | 
			
		||||
 | 
			
		||||
				/* added later, potentially after (when) */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (state == PARSE_WHEN) {
 | 
			
		||||
				/* it's either numeric (then % or ..num2), or
 | 
			
		||||
				 * .X pattern */
 | 
			
		||||
 | 
			
		||||
				lwsl_notice("%s: when\n", __func__);
 | 
			
		||||
 | 
			
		||||
				if (*ts.token == '.' || *ts.token == 'X') {
 | 
			
		||||
					uint8_t *pat;
 | 
			
		||||
					size_t n;
 | 
			
		||||
 | 
			
		||||
					/*
 | 
			
		||||
					 * pattern... we need to allocate it
 | 
			
		||||
					 */
 | 
			
		||||
					fi.type = LWSFI_PATTERN_ALLOC;
 | 
			
		||||
					pat = lws_zalloc((ts.token_len >> 3) + 1,
 | 
			
		||||
							 __func__);
 | 
			
		||||
					if (!pat)
 | 
			
		||||
						return;
 | 
			
		||||
					fi.pattern = pat;
 | 
			
		||||
					fi.count = (uint64_t)ts.token_len;
 | 
			
		||||
 | 
			
		||||
					for (n = 0; n < ts.token_len; n++)
 | 
			
		||||
						if (ts.token[n] == 'X')
 | 
			
		||||
							pat[n >> 3] = (uint8_t)(
 | 
			
		||||
								pat[n >> 3] |
 | 
			
		||||
								(1 << (n & 7)));
 | 
			
		||||
 | 
			
		||||
					lwsl_hexdump_notice(pat,
 | 
			
		||||
						       (ts.token_len >> 3) + 1);
 | 
			
		||||
 | 
			
		||||
					state = PARSE_ENDBR;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				fi.pre = (uint64_t)atoll(ts.token);
 | 
			
		||||
 | 
			
		||||
				for (m = 0; m < (int)ts.token_len - 1; m++)
 | 
			
		||||
					if (ts.token[m] < '0' ||
 | 
			
		||||
					    ts.token[m] > '9')
 | 
			
		||||
						break;
 | 
			
		||||
 | 
			
		||||
				/*
 | 
			
		||||
				 * We can understand num% or num..num
 | 
			
		||||
				 */
 | 
			
		||||
 | 
			
		||||
				if (m != (int)ts.token_len &&
 | 
			
		||||
				    ts.token[m] == '.' &&
 | 
			
		||||
				    ts.token[m + 1] == '.') {
 | 
			
		||||
					fi.count = (uint64_t)atoll(
 | 
			
		||||
						&ts.token[m + 2]);
 | 
			
		||||
					fi.type = LWSFI_RANGE;
 | 
			
		||||
					state = PARSE_ENDBR;
 | 
			
		||||
 | 
			
		||||
					if (fi.pre >= fi.count) {
 | 
			
		||||
						lwsl_err("%s: range must have "
 | 
			
		||||
							 "smaller first!\n",
 | 
			
		||||
							 __func__);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					lwsl_notice("%s: range %llx .."
 | 
			
		||||
						    "%llx\n", __func__,
 | 
			
		||||
						    (unsigned long long)fi.pre,
 | 
			
		||||
						    (unsigned long long)fi.count);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				lwsl_notice("%s: prob %d%%\n", __func__,
 | 
			
		||||
					    (int)fi.pre);
 | 
			
		||||
				fi.type = LWSFI_PROBABILISTIC;
 | 
			
		||||
				state = PARSE_PC;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case LWS_TOKZE_DELIMITER:
 | 
			
		||||
			if (*ts.token == ',') {
 | 
			
		||||
				lws_fi_add(fic, &fi);
 | 
			
		||||
				state = PARSE_NAME;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (*ts.token == '(') {
 | 
			
		||||
				lwsl_notice("%s: (\n", __func__);
 | 
			
		||||
				if (state != PARSE_NAME) {
 | 
			
		||||
					lwsl_err("%s: misplaced (\n", __func__);
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				state = PARSE_WHEN;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (*ts.token == ')') {
 | 
			
		||||
				if (state != PARSE_ENDBR) {
 | 
			
		||||
					lwsl_err("%s: misplaced )\n", __func__);
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				state = PARSE_NAME;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (*ts.token == '%') {
 | 
			
		||||
				if (state != PARSE_PC) {
 | 
			
		||||
					lwsl_err("%s: misplaced %%\n", __func__);
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				state = PARSE_ENDBR;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case LWS_TOKZE_ENDED:
 | 
			
		||||
			lws_fi_add(fic, &fi);
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	} while (ts.e > 0);
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,35 @@
 | 
			
		||||
/*
 | 
			
		||||
 * lws System Message Distribution
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2019 - 2021 Andy Green <andy@warmcat.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to
 | 
			
		||||
 * deal in the Software without restriction, including without limitation the
 | 
			
		||||
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 | 
			
		||||
 * sell copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 | 
			
		||||
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 | 
			
		||||
 * IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if defined(LWS_WITH_SYS_FAULT_INJECTION)
 | 
			
		||||
 | 
			
		||||
typedef struct lws_fi_priv {
 | 
			
		||||
	lws_dll2_t		list;
 | 
			
		||||
	lws_fi_t		fi;
 | 
			
		||||
} lws_fi_priv_t;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
lws_fi_import(lws_fi_ctx_t *fic_dest, const lws_fi_ctx_t *fic_src);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user