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

📄 alloc.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
字号:
/* * Amanda, The Advanced Maryland Automatic Network Disk Archiver * Copyright (c) 1991-1999 University of Maryland at College Park * All Rights Reserved. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of U.M. not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission.  U.M. makes no representations about the * suitability of this software for any purpose.  It is provided "as is" * without express or implied warranty. * * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Authors: the Amanda Development Team.  Its members are listed in a * file named AUTHORS, in the root directory of this distribution. *//* * $Id: alloc.c 5280 2007-02-13 15:58:56Z martineau $ * * Memory allocators with error handling.  If the allocation fails, * errordump() is called, relieving the caller from checking the return * code */#include "amanda.h"#include "arglist.h"#include "queue.h"#define	MIN_ALLOC	64static char *internal_vstralloc(const char *, int, const char *, va_list);/* * alloc - a wrapper for malloc. */void *debug_alloc(    const char *file,    int		line,    size_t	size){    void *addr;    addr = (void *)malloc(max(size, 1));    if (addr == NULL) {	errordump(_("%s@%d: memory allocation failed (%zu bytes requested)"),		  file ? file : _("(unknown)"),		  file ? line : -1,		  size);	/*NOTREACHED*/    }    return addr;}/* * newalloc - free existing buffer and then alloc a new one. */void *debug_newalloc(    const char *file,    int		line,    void *	old,    size_t	size){    char *addr;    addr = debug_alloc(file, line, size);    amfree(old);    return addr;}/* * stralloc - copies the given string into newly allocated memory. *            Just like strdup()! */char *debug_stralloc(    const char *file,    int		line,    const char *str){    char *addr;    addr = debug_alloc(file, line, strlen(str) + 1);    strcpy(addr, str);    return (addr);}/* * internal_vstralloc - copies up to MAX_STR_ARGS strings into newly * allocated memory. * * The MAX_STR_ARGS limit is purely an efficiency issue so we do not have * to scan the strings more than necessary. */#define	MAX_VSTRALLOC_ARGS	32static char *internal_vstralloc(    const char *file,    int		line,    const char *str,    va_list argp){    char *next;    char *result;    int a, b;    size_t total_len;    const char *arg[MAX_VSTRALLOC_ARGS+1];    size_t len[MAX_VSTRALLOC_ARGS+1];    size_t l;    if (str == NULL) {	errordump(_("internal_vstralloc: str is NULL"));	/*NOTREACHED*/    }    a = 0;    arg[a] = str;    l = strlen(str);    total_len = len[a] = l;    a++;    while ((next = arglist_val(argp, char *)) != NULL) {	if ((l = strlen(next)) == 0) {	    continue;				/* minor optimisation */	}	if (a >= MAX_VSTRALLOC_ARGS) {	    errordump(_("%s@%d: more than %d args to vstralloc"),		      file ? file : _("(unknown)"),		      file ? line : -1,		      MAX_VSTRALLOC_ARGS);	    /*NOTREACHED*/	}	arg[a] = next;	len[a] = l;	total_len += l;	a++;    }    result = debug_alloc(file, line, total_len+1);    next = result;    for (b = 0; b < a; b++) {	memcpy(next, arg[b], len[b]);	next += len[b];    }    *next = '\0';    return result;}/* * vstralloc - copies multiple strings into newly allocated memory. */char *debug_vstralloc(    const char *file,    int		line,    const char *str,    ...){    va_list argp;    char *result;    arglist_start(argp, str);    result = internal_vstralloc(file, line, str, argp);    arglist_end(argp);    return result;}/* * newstralloc - free existing string and then stralloc a new one. */char *debug_newstralloc(    const char *file,    int		line,    char *	oldstr,    const char *newstr){    char *addr;    addr = debug_stralloc(file, line, newstr);    amfree(oldstr);    return (addr);}/* * newvstralloc - free existing string and then vstralloc a new one. */char *debug_newvstralloc(    const char *file,    int		line,    char *	oldstr,    const char *newstr,    ...){    va_list argp;    char *result;    arglist_start(argp, newstr);    result = internal_vstralloc(file, line, newstr, argp);    arglist_end(argp);    amfree(oldstr);    return result;}/* * vstrallocf - copies printf formatted string into newly allocated memory. */char *debug_vstrallocf(    const char *file,    int		line,    const char *fmt,    ...){    char *	result;    size_t	size;    va_list	argp;    result = debug_alloc(file, line, MIN_ALLOC);    if (result != NULL) {	arglist_start(argp, fmt);	size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);	arglist_end(argp);	if (size >= (size_t)MIN_ALLOC) {	    amfree(result);	    result = debug_alloc(file, line, size + 1);	    arglist_start(argp, fmt);	    (void)g_vsnprintf(result, size + 1, fmt, argp);	    arglist_end(argp);	}    }    return result;}/* * newvstrallocf - free existing string and then vstrallocf a new one. */char *debug_newvstrallocf(    const char *file,    int		line,    char *	oldstr,    const char *fmt,    ...){    size_t	size;    char *	result;    va_list	argp;    result = debug_alloc(file, line, MIN_ALLOC);    if (result != NULL) {	arglist_start(argp, fmt);	size = g_vsnprintf(result, MIN_ALLOC, fmt, argp);	arglist_end(argp);	if (size >= MIN_ALLOC) {	    amfree(result);	    result = debug_alloc(file, line, size + 1);	    arglist_start(argp, fmt);	    (void)g_vsnprintf(result, size + 1, fmt, argp);	    arglist_end(argp);	}    }    amfree(oldstr);    return result;}/* vstrextend -- Extends the existing string by appending the other  * arguments. */char *debug_vstrextend(    const char *file,    int		line,    char **	oldstr,    ...){	char *keep = *oldstr;	va_list ap;	arglist_start(ap, oldstr);	if (*oldstr == NULL)		*oldstr = "";	*oldstr = internal_vstralloc(file, line, *oldstr, ap);        amfree(keep);	arglist_end(ap);        return *oldstr;}extern char **environ;/* * safe_env - build a "safe" environment list. */char **safe_env(void){    static char *safe_env_list[] = {	"TZ",#ifdef __CYGWIN__	"SYSTEMROOT",#endif#ifdef NEED_PATH_ENV	"PATH",#endif	"DISPLAY",	NULL    };    /*     * If the initial environment pointer malloc fails, set up to     * pass back a pointer to the NULL string pointer at the end of     * safe_env_list so our result is always a valid, although possibly     * empty, environment list.     */#define SAFE_ENV_CNT	(size_t)(sizeof(safe_env_list) / sizeof(*safe_env_list))    char **envp = safe_env_list + SAFE_ENV_CNT - 1;    char **p;    char **q;    char *s;    char *v;    size_t l1, l2;    char **env;    int    env_cnt;    if (getuid() == geteuid() && getgid() == getegid()) {	env_cnt = 1;	for (env = environ; *env != NULL; env++)	    env_cnt++;	if ((q = (char **)malloc(env_cnt*SIZEOF(char *))) != NULL) {	    envp = q;	    p = envp;	    for (env = environ; *env != NULL; env++) {		if (strncmp("LANG=", *env, 5) != 0 &&		    strncmp("LC_", *env, 3) != 0) {		    *p = stralloc(*env);		    p++;		}	    }	    *p = NULL;	}	return envp;    }    if ((q = (char **)malloc(SIZEOF(safe_env_list))) != NULL) {	envp = q;	for (p = safe_env_list; *p != NULL; p++) {	    if ((v = getenv(*p)) == NULL) {		continue;			/* no variable to dup */	    }	    l1 = strlen(*p);			/* variable name w/o null */	    l2 = strlen(v) + 1;			/* include null byte here */	    if ((s = (char *)malloc(l1 + 1 + l2)) == NULL) {		break;				/* out of memory */	    }	    *q++ = s;				/* save the new pointer */	    memcpy(s, *p, l1);			/* left hand side */	    s += l1;	    *s++ = '=';	    memcpy(s, v, l2);			/* right hand side and null */	}	*q = NULL;				/* terminate the list */    }    return envp;}/* * amtable_alloc -- (re)allocate enough space for some number of elements. * * input:	table -- pointer to pointer to table *		current -- pointer to current number of elements *		elsize -- size of a table element *		count -- desired number of elements *		bump -- round up factor *		init_func -- optional element initialization function * output:	table -- possibly adjusted to point to new table area *		current -- possibly adjusted to new number of elements */intdebug_amtable_alloc(    const char *file,    int		line,    void **	table,    size_t *	current,    size_t	elsize,    size_t	count,    int		bump,    void (*init_func)(void *)){    void *table_new;    size_t table_count_new;    size_t i;    if (count >= *current) {	table_count_new = ((count + bump) / bump) * bump;	table_new = debug_alloc(file, line, table_count_new * elsize);	if (0 != *table) {	    memcpy(table_new, *table, *current * elsize);	    free(*table);	}	*table = table_new;	memset(((char *)*table) + *current * elsize,	       0,	       (table_count_new - *current) * elsize);	if (init_func != NULL) {	    for (i = *current; i < table_count_new; i++) {		(*init_func)(((char *)*table) + i * elsize);	    }	}	*current = table_count_new;    }    return 0;}/* * amtable_free -- release a table. * * input:	table -- pointer to pointer to table *		current -- pointer to current number of elements * output:	table -- possibly adjusted to point to new table area *		current -- possibly adjusted to new number of elements */voidamtable_free(    void **	table,    size_t *	current){    amfree(*table);    *current = 0;}

⌨️ 快捷键说明

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