⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 talloc.c

📁 openswan
💻 C
📖 第 1 页 / 共 2 页
字号:
}/*  A talloc version of realloc. The context argument is only used if  ptr is NULL*/void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name){	struct talloc_chunk *tc;	void *new_ptr;	/* size zero is equivalent to free() */	if (size == 0) {		talloc_free(ptr);		return NULL;	}	if (size >= MAX_TALLOC_SIZE) {		return NULL;	}	/* realloc(NULL) is equavalent to malloc() */	if (ptr == NULL) {		return talloc_named_const(context, size, name);	}	tc = talloc_chunk_from_ptr(ptr);	/* don't allow realloc on referenced pointers */	if (tc->refs) {		return NULL;	}	/* by resetting magic we catch users of the old memory */	tc->magic = TALLOC_MAGIC_FREE;#if ALWAYS_REALLOC	new_ptr = malloc(size + sizeof(*tc));	if (new_ptr) {		memcpy(new_ptr, tc, tc->size + sizeof(*tc));		free(tc);	}#else	new_ptr = realloc(tc, size + sizeof(*tc));#endif	if (!new_ptr) {			tc->magic = TALLOC_MAGIC; 		return NULL; 	}	tc = new_ptr;	tc->magic = TALLOC_MAGIC;	if (tc->parent) {		tc->parent->child = new_ptr;	}	if (tc->child) {		tc->child->parent = new_ptr;	}	if (tc->prev) {		tc->prev->next = tc;	}	if (tc->next) {		tc->next->prev = tc;	}	tc->size = size;	talloc_set_name_const(tc+1, name);	return (void *)(tc+1);}/*    move a lump of memory from one talloc context to another return the   ptr on success, or NULL if it could not be transferred*/void *talloc_steal(const void *new_ctx, const void *ptr){	struct talloc_chunk *tc, *new_tc;	if (!ptr) {		return NULL;	}	if (new_ctx == NULL) {		new_ctx = null_context;	}	tc = talloc_chunk_from_ptr(ptr);	if (new_ctx == NULL) {		if (tc->parent) {			_TLIST_REMOVE(tc->parent->child, tc);			if (tc->parent->child) {				tc->parent->child->parent = tc->parent;			}		} else {			if (tc->prev) tc->prev->next = tc->next;			if (tc->next) tc->next->prev = tc->prev;		}				tc->parent = tc->next = tc->prev = NULL;		return discard_const_p(void, ptr);	}	new_tc = talloc_chunk_from_ptr(new_ctx);	if (tc == new_tc) {		return discard_const_p(void, ptr);	}	if (tc->parent) {		_TLIST_REMOVE(tc->parent->child, tc);		if (tc->parent->child) {			tc->parent->child->parent = tc->parent;		}	} else {		if (tc->prev) tc->prev->next = tc->next;		if (tc->next) tc->next->prev = tc->prev;	}	tc->parent = new_tc;	if (new_tc->child) new_tc->child->parent = NULL;	_TLIST_ADD(new_tc->child, tc);	return discard_const_p(void, ptr);}/*  return the total size of a talloc pool (subtree)*/off_t talloc_total_size(const void *ptr){	off_t total = 0;	struct talloc_chunk *c, *tc;		if (ptr == NULL) {		ptr = null_context;	}	if (ptr == NULL) {		return 0;	}	tc = talloc_chunk_from_ptr(ptr);	total = tc->size;	for (c=tc->child;c;c=c->next) {		total += talloc_total_size(c+1);	}	return total;}/*  return the total number of blocks in a talloc pool (subtree)*/off_t talloc_total_blocks(const void *ptr){	off_t total = 0;	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);	total++;	for (c=tc->child;c;c=c->next) {		total += talloc_total_blocks(c+1);	}	return total;}/*  return the number of external references to a pointer*/static int talloc_reference_count(const void *ptr){	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);	struct talloc_reference_handle *h;	int ret = 0;	for (h=tc->refs;h;h=h->next) {		ret++;	}	return ret;}/*  report on memory usage by all children of a pointer, giving a full tree view*/static void talloc_report_depth(const void *ptr, FILE *f, int depth){	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);	for (c=tc->child;c;c=c->next) {		if (c->name == TALLOC_MAGIC_REFERENCE) {			struct talloc_reference_handle *handle = (void *)(c+1);			const char *name2 = talloc_get_name(handle->ptr);			fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);		} else {			const char *name = talloc_get_name(c+1);			fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n", 				depth*4, "",				name,				(unsigned long)talloc_total_size(c+1),				(unsigned long)talloc_total_blocks(c+1),				talloc_reference_count(c+1));			talloc_report_depth(c+1, f, depth+1);		}	}}/*  report on memory usage by all children of a pointer, giving a full tree view*/void talloc_report_full(const void *ptr, FILE *f){	if (ptr == NULL) {		ptr = null_context;	}	if (ptr == NULL) return;	fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n", 		talloc_get_name(ptr), 		(unsigned long)talloc_total_size(ptr),		(unsigned long)talloc_total_blocks(ptr));	talloc_report_depth(ptr, f, 1);}/*  report on memory usage by all children of a pointer*/void talloc_report(const void *ptr, FILE *f){	struct talloc_chunk *c, *tc;	if (ptr == NULL) {		ptr = null_context;	}	if (ptr == NULL) return;       	fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n", 		talloc_get_name(ptr), 		(unsigned long)talloc_total_size(ptr),		(unsigned long)talloc_total_blocks(ptr));	tc = talloc_chunk_from_ptr(ptr);	for (c=tc->child;c;c=c->next) {		fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n", 			talloc_get_name(c+1),			(unsigned long)talloc_total_size(c+1),			(unsigned long)talloc_total_blocks(c+1));	}}/*  report on any memory hanging off the null context*/static void talloc_report_null(void){	if (talloc_total_size(null_context) != 0) {		talloc_report(null_context, stderr);	}}/*  report on any memory hanging off the null context*/static void talloc_report_null_full(void){	if (talloc_total_size(null_context) != 0) {		talloc_report_full(null_context, stderr);	}}/*  enable leak reporting on exit*/void talloc_enable_leak_report(void){	null_context = talloc_named_const(NULL, 0, "null_context");	atexit(talloc_report_null);}/*  enable full leak reporting on exit*/void talloc_enable_leak_report_full(void){	null_context = talloc_named_const(NULL, 0, "null_context");	atexit(talloc_report_null_full);}/*    talloc and zero memory. */void *_talloc_zero(const void *ctx, size_t size, const char *name){	void *p = talloc_named_const(ctx, size, name);	if (p) {		memset(p, '\0', size);	}	return p;}/*  memdup with a talloc. */void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name){	void *newp = talloc_named_const(t, size, name);	if (newp) {		memcpy(newp, p, size);	}	return newp;}/*  strdup with a talloc */char *talloc_strdup(const void *t, const char *p){	char *ret;	if (!p) {		return NULL;	}	ret = talloc_memdup(t, p, strlen(p) + 1);	if (ret) {		talloc_set_name_const(ret, ret);	}	return ret;}/*  strndup with a talloc */char *talloc_strndup(const void *t, const char *p, size_t n){	size_t len;	char *ret;	for (len=0; p[len] && len<n; len++) ;	ret = _talloc(t, len + 1);	if (!ret) { return NULL; }	memcpy(ret, p, len);	ret[len] = 0;	talloc_set_name_const(ret, ret);	return ret;}char *talloc_vasprintf(const void *t, const char *fmt, va_list ap){		int len;	char *ret;	va_list ap2;		va_copy(ap2, ap);	len = vsnprintf(NULL, 0, fmt, ap2);	ret = _talloc(t, len+1);	if (ret) {		va_copy(ap2, ap);		vsnprintf(ret, len+1, fmt, ap2);		talloc_set_name_const(ret, ret);	}	return ret;}/*  Perform string formatting, and return a pointer to newly allocated  memory holding the result, inside a memory pool. */char *talloc_asprintf(const void *t, const char *fmt, ...){	va_list ap;	char *ret;	va_start(ap, fmt);	ret = talloc_vasprintf(t, fmt, ap);	va_end(ap);	return ret;}/** * Realloc @p s to append the formatted result of @p fmt and @p ap, * and return @p s, which may have moved.  Good for gradually * accumulating output into a string buffer. **/static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap){		int len, s_len;	va_list ap2;	va_copy(ap2, ap);	if (s) {		s_len = strlen(s);	} else {		s_len = 0;	}	len = vsnprintf(NULL, 0, fmt, ap2);	s = talloc_realloc(NULL, s, s_len + len+1);	if (!s) return NULL;	va_copy(ap2, ap);	vsnprintf(s+s_len, len+1, fmt, ap2);	talloc_set_name_const(s, s);	return s;}/*  Realloc @p s to append the formatted result of @p fmt and return @p  s, which may have moved.  Good for gradually accumulating output  into a string buffer. */char *talloc_asprintf_append(char *s, const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	s = talloc_vasprintf_append(s, fmt, ap);	va_end(ap);	return s;}/*  alloc an array, checking for integer overflow in the array size*/void *talloc_array_size(const void *ctx, size_t el_size, unsigned count, const char *name){	if (count >= MAX_TALLOC_SIZE/el_size) {		return NULL;	}	return talloc_named_const(ctx, el_size * count, name);}/*  alloc an zero array, checking for integer overflow in the array size*/void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name){	if (count >= MAX_TALLOC_SIZE/el_size) {		return NULL;	}	return _talloc_zero(ctx, el_size * count, name);}/*  realloc an array, checking for integer overflow in the array size*/void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name){	if (count >= MAX_TALLOC_SIZE/el_size) {		return NULL;	}	ptr = talloc_realloc(ctx, ptr, el_size * count);	if (ptr) {		talloc_set_name_const(ptr, name);	}	return ptr;}/*  a function version of talloc_realloc(), so it can be passed as a function pointer  to libraries that want a realloc function (a realloc function encapsulates  all the basic capabilities of an allocation library, which is why this is useful)*/void *talloc_realloc_fn(const void *context, void *ptr, size_t size){	return _talloc_realloc(context, ptr, size, NULL);}static void talloc_autofree(void){	talloc_free(cleanup_context);	cleanup_context = NULL;}/*  return a context which will be auto-freed on exit  this is useful for reducing the noise in leak reports*/void *talloc_autofree_context(void){	if (cleanup_context == NULL) {		cleanup_context = talloc_named_const(NULL, 0, "autofree_context");		atexit(talloc_autofree);	}	return cleanup_context;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -