diff options
Diffstat (limited to 'libglusterfs/src/strfd.c')
| -rw-r--r-- | libglusterfs/src/strfd.c | 91 | 
1 files changed, 91 insertions, 0 deletions
diff --git a/libglusterfs/src/strfd.c b/libglusterfs/src/strfd.c new file mode 100644 index 00000000000..8c97670d4dd --- /dev/null +++ b/libglusterfs/src/strfd.c @@ -0,0 +1,91 @@ +/* +   Copyright (c) 2014 Red Hat, Inc. <http://www.redhat.com> +   This file is part of GlusterFS. + +   This file is licensed to you under your choice of the GNU Lesser +   General Public License, version 3 or any later version (LGPLv3 or +   later), or the GNU General Public License, version 2 (GPLv2), in all +   cases as published by the Free Software Foundation. +*/ + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#include <stdarg.h> + +#include "mem-types.h" +#include "mem-pool.h" +#include "strfd.h" +#include "common-utils.h" + + +strfd_t * +strfd_open () +{ +	strfd_t *strfd = NULL; + +	strfd = GF_CALLOC(1, sizeof(*strfd), gf_common_mt_strfd_t); + +	return strfd; +} + + +int +strprintf (strfd_t *strfd, const char *fmt, ...) +{ +	va_list ap; +	char *str = NULL; +	int size = 0; + +	va_start (ap, fmt); + +	size = vasprintf (&str, fmt, ap); + +	if (size < 0) +		return size; + +	if (!strfd->alloc_size) { +		strfd->data = GF_CALLOC (max(size + 1, 4096), 1, +					 gf_common_mt_strfd_data_t); +		if (!strfd->data) { +			free (str); /* NOT GF_FREE */ +			return -1; +		} +		strfd->alloc_size = max(size + 1, 4096); +	} + +	if (strfd->alloc_size <= (strfd->size + size)) { +		char *tmp_ptr = NULL; +		int new_size = max ((strfd->alloc_size * 2), +				    gf_roundup_next_power_of_two (strfd->size + size + 1)); +		tmp_ptr = GF_REALLOC (strfd->data, new_size); +		if (!tmp_ptr) { +			free (str); /* NOT GF_FREE */ +			return -1; +		} +		strfd->alloc_size = new_size; +		strfd->data = tmp_ptr; +	} + +	// Copy the trailing '\0', but do not account for it in ->size. +	// This allows safe use of strfd->data as a string. +	memcpy (strfd->data + strfd->size, str, size + 1); +	strfd->size += size; + +	free (str); /* NOT GF_FREE */ + +	return size; +} + + +int +strfd_close (strfd_t *strfd) +{ +	GF_FREE (strfd->data); +	GF_FREE (strfd); + +	return 0; +} +  | 
