/* $Id: xmalloc.c,v 1.1.1.1 2007-07-09 19:03:33 nicm Exp $ */ /* * Copyright (c) 2004 Nicholas Marriott * * 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 #include #include #include #include #include #include #include #include #include "tmux.h" void * ensure_for(void *buf, size_t *len, size_t size, size_t adj) { if (adj == 0) log_fatalx("ensure_for: zero adj"); if (SIZE_MAX - size < adj) log_fatalx("ensure_for: size + adj > SIZE_MAX"); size += adj; if (*len == 0) { *len = BUFSIZ; buf = xmalloc(*len); } while (*len <= size) { buf = xrealloc(buf, 2, *len); *len *= 2; } return (buf); } void * ensure_size(void *buf, size_t *len, size_t nmemb, size_t size) { if (nmemb == 0 || size == 0) log_fatalx("ensure_size: zero size"); if (SIZE_MAX / nmemb < size) log_fatalx("ensure_size: nmemb * size > SIZE_MAX"); if (*len == 0) { *len = BUFSIZ; buf = xmalloc(*len); } while (*len <= nmemb * size) { buf = xrealloc(buf, 2, *len); *len *= 2; } return (buf); } 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) log_fatalx("xcalloc: zero size"); if (SIZE_MAX / nmemb < size) log_fatalx("xcalloc: nmemb * size > SIZE_MAX"); if ((ptr = calloc(nmemb, size)) == NULL) log_fatal("xcalloc"); return (ptr); } void * xmalloc(size_t size) { void *ptr; if (size == 0) log_fatalx("xmalloc: zero size"); if ((ptr = malloc(size)) == NULL) log_fatal("xmalloc"); return (ptr); } void * xrealloc(void *oldptr, size_t nmemb, size_t size) { size_t newsize = nmemb * size; void *newptr; if (newsize == 0) log_fatalx("xrealloc: zero size"); if (SIZE_MAX / nmemb < size) log_fatal("xrealloc: nmemb * size > SIZE_MAX"); if ((newptr = realloc(oldptr, newsize)) == NULL) log_fatal("xrealloc"); return (newptr); } void xfree(void *ptr) { if (ptr == NULL) log_fatalx("xfree: null pointer"); free(ptr); } 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) log_fatal("xvasprintf"); 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) { errno = EINVAL; log_fatal("xvsnprintf"); } i = vsnprintf(buf, len, fmt, ap); if (i < 0) log_fatal("xvsnprintf"); return (i); } /* * Print a path. Same as xsnprintf, but return ENAMETOOLONG on truncation. */ int printflike3 printpath(char *buf, size_t len, const char *fmt, ...) { va_list ap; int n; if (len > INT_MAX) { errno = ENAMETOOLONG; return (1); } va_start(ap, fmt); n = xvsnprintf(buf, len, fmt, ap); va_end(ap); if ((size_t) n > len) { errno = ENAMETOOLONG; return (1); } return (0); } /* * Some system modify the path in place. This function and xbasename below * avoid that by using a temporary buffer. */ char * xdirname(const char *src) { char dst[MAXPATHLEN]; strlcpy(dst, src, sizeof dst); return (dirname(dst)); } char * xbasename(const char *src) { char dst[MAXPATHLEN]; strlcpy(dst, src, sizeof dst); return (basename(dst)); }