| /* $Id: xmalloc.c,v 1.8 2009-01-29 19:24:34 nicm Exp $ */ | 
 |  | 
 | /* | 
 |  * Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net> | 
 |  * | 
 |  * Permission to use, copy, modify, and distribute this software for any | 
 |  * purpose with or without fee is hereby granted, provided that the above | 
 |  * copyright notice and this permission notice appear in all copies. | 
 |  * | 
 |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
 |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
 |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
 |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
 |  * WHATSOEVER RESULTING FROM LOSS OF MIND, 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. | 
 |  */ | 
 |  | 
 | #include <sys/param.h> | 
 |  | 
 | #include <errno.h> | 
 | #include <libgen.h> | 
 | #include <stdint.h> | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 |  | 
 | #include "tmux.h" | 
 |  | 
 | char * | 
 | xstrdup(const char *s) | 
 | { | 
 | 	void	*ptr; | 
 | 	size_t	 len; | 
 |  | 
 | 	len = strlen(s) + 1; | 
 | 	ptr = xmalloc(len); | 
 |  | 
 |         return (strncpy(ptr, s, len)); | 
 | } | 
 |  | 
 | void * | 
 | xcalloc(size_t nmemb, size_t size) | 
 | { | 
 |         void	*ptr; | 
 |  | 
 |         if (size == 0 || nmemb == 0) | 
 | 		fatalx("zero size"); | 
 |         if (SIZE_MAX / nmemb < size) | 
 |                 fatalx("nmemb * size > SIZE_MAX"); | 
 |         if ((ptr = calloc(nmemb, size)) == NULL) | 
 | 		fatal("xcalloc failed"); | 
 |  | 
 | #ifdef DEBUG | 
 | 	xmalloc_new(xmalloc_caller(), ptr, nmemb * size); | 
 | #endif | 
 |         return (ptr); | 
 | } | 
 |  | 
 | void * | 
 | xmalloc(size_t size) | 
 | { | 
 | 	void	*ptr; | 
 |  | 
 |         if (size == 0) | 
 |                 fatalx("zero size"); | 
 |         if ((ptr = malloc(size)) == NULL) | 
 | 		fatal("xmalloc failed"); | 
 |  | 
 | #ifdef DEBUG | 
 | 	xmalloc_new(xmalloc_caller(), ptr, size); | 
 | #endif | 
 |         return (ptr); | 
 | } | 
 |  | 
 | void * | 
 | xrealloc(void *oldptr, size_t nmemb, size_t size) | 
 | { | 
 | 	size_t	 newsize = nmemb * size; | 
 | 	void	*newptr; | 
 |  | 
 | 	if (newsize == 0) | 
 |                 fatalx("zero size"); | 
 |         if (SIZE_MAX / nmemb < size) | 
 |                 fatalx("nmemb * size > SIZE_MAX"); | 
 |         if ((newptr = realloc(oldptr, newsize)) == NULL) | 
 | 		fatal("xrealloc failed"); | 
 |  | 
 | #ifdef DEBUG | 
 | 	xmalloc_change(xmalloc_caller(), oldptr, newptr, nmemb * size); | 
 | #endif | 
 |         return (newptr); | 
 | } | 
 |  | 
 | void | 
 | xfree(void *ptr) | 
 | { | 
 | 	if (ptr == NULL) | 
 | 		fatalx("null pointer"); | 
 | 	free(ptr); | 
 |  | 
 | #ifdef DEBUG | 
 | 	xmalloc_free(ptr); | 
 | #endif | 
 | } | 
 |  | 
 | int printflike2 | 
 | xasprintf(char **ret, const char *fmt, ...) | 
 | { | 
 |         va_list ap; | 
 |         int	i; | 
 |  | 
 |         va_start(ap, fmt); | 
 |         i = xvasprintf(ret, fmt, ap); | 
 |         va_end(ap); | 
 |  | 
 | 	return (i); | 
 | } | 
 |  | 
 | int | 
 | xvasprintf(char **ret, const char *fmt, va_list ap) | 
 | { | 
 | 	int	i; | 
 |  | 
 | 	i = vasprintf(ret, fmt, ap); | 
 |         if (i < 0 || *ret == NULL) | 
 |                 fatal("xvasprintf failed"); | 
 |  | 
 | #ifdef DEBUG | 
 | 	xmalloc_new(xmalloc_caller(), *ret, i + 1); | 
 | #endif | 
 |         return (i); | 
 | } | 
 |  | 
 | int printflike3 | 
 | xsnprintf(char *buf, size_t len, const char *fmt, ...) | 
 | { | 
 |         va_list ap; | 
 |         int	i; | 
 |  | 
 |         va_start(ap, fmt); | 
 |         i = xvsnprintf(buf, len, fmt, ap); | 
 |         va_end(ap); | 
 |  | 
 | 	return (i); | 
 | } | 
 |  | 
 | int | 
 | xvsnprintf(char *buf, size_t len, const char *fmt, va_list ap) | 
 | { | 
 | 	int	i; | 
 |  | 
 | 	if (len > INT_MAX) | 
 | 		fatalx("len > INT_MAX"); | 
 |  | 
 | 	i = vsnprintf(buf, len, fmt, ap); | 
 |         if (i < 0) | 
 |                 fatal("vsnprintf failed"); | 
 |  | 
 |         return (i); | 
 | } | 
 |  | 
 | /* | 
 |  * Some systems modify the path in place. This function and xbasename below | 
 |  * avoid that by using a temporary buffer. | 
 |  */ | 
 | char * | 
 | xdirname(const char *src) | 
 | { | 
 | 	static char	dst[MAXPATHLEN]; | 
 |  | 
 | 	strlcpy(dst, src, sizeof dst); | 
 | 	return (dirname(dst)); | 
 | } | 
 |  | 
 | char * | 
 | xbasename(const char *src) | 
 | { | 
 | 	static char	dst[MAXPATHLEN]; | 
 |  | 
 | 	strlcpy(dst, src, sizeof dst); | 
 | 	return (basename(dst)); | 
 | } |