blob: 68861c2ce042dfb58f1654eede46a8ff6169b47b [file] [log] [blame] [raw]
Nicholas Marriottb4ac8c12009-01-14 19:29:32 +00001/* $Id: xmalloc.c,v 1.7 2009-01-14 19:29:32 nicm Exp $ */
Nicholas Marriotta41ece52007-07-09 19:04:12 +00002
3/*
4 * Copyright (c) 2004 Nicholas Marriott <nicm@users.sourceforge.net>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000019#include <sys/param.h>
Nicholas Marriotta41ece52007-07-09 19:04:12 +000020
21#include <errno.h>
22#include <libgen.h>
Nicholas Marriott92a42a92007-10-19 20:50:01 +000023#include <stdint.h>
Nicholas Marriotta41ece52007-07-09 19:04:12 +000024#include <stdlib.h>
25#include <string.h>
26
27#include "tmux.h"
Nicholas Marriott1e316cf2007-09-29 14:25:49 +000028
29char *
Nicholas Marriotta41ece52007-07-09 19:04:12 +000030xstrdup(const char *s)
31{
32 void *ptr;
33 size_t len;
34
35 len = strlen(s) + 1;
36 ptr = xmalloc(len);
37
38 return (strncpy(ptr, s, len));
39}
40
41void *
42xcalloc(size_t nmemb, size_t size)
43{
44 void *ptr;
45
46 if (size == 0 || nmemb == 0)
Nicholas Marriottb4ac8c12009-01-14 19:29:32 +000047 { abort();fatalx("zero size");}
Nicholas Marriotta41ece52007-07-09 19:04:12 +000048 if (SIZE_MAX / nmemb < size)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000049 fatalx("nmemb * size > SIZE_MAX");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000050 if ((ptr = calloc(nmemb, size)) == NULL)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000051 fatal("xcalloc failed");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000052
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000053#ifdef DEBUG
54 xmalloc_new(xmalloc_caller(), ptr, nmemb * size);
55#endif
Nicholas Marriotta41ece52007-07-09 19:04:12 +000056 return (ptr);
57}
58
59void *
60xmalloc(size_t size)
61{
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000062 void *ptr;
Nicholas Marriotta41ece52007-07-09 19:04:12 +000063
64 if (size == 0)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000065 fatalx("zero size");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000066 if ((ptr = malloc(size)) == NULL)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000067 fatal("xmalloc failed");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000068
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000069#ifdef DEBUG
70 xmalloc_new(xmalloc_caller(), ptr, size);
71#endif
Nicholas Marriotta41ece52007-07-09 19:04:12 +000072 return (ptr);
73}
74
75void *
76xrealloc(void *oldptr, size_t nmemb, size_t size)
77{
78 size_t newsize = nmemb * size;
79 void *newptr;
80
81 if (newsize == 0)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000082 fatalx("zero size");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000083 if (SIZE_MAX / nmemb < size)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000084 fatalx("nmemb * size > SIZE_MAX");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000085 if ((newptr = realloc(oldptr, newsize)) == NULL)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000086 fatal("xrealloc failed");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000087
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000088#ifdef DEBUG
89 xmalloc_change(xmalloc_caller(), oldptr, newptr, nmemb * size);
90#endif
Nicholas Marriotta41ece52007-07-09 19:04:12 +000091 return (newptr);
92}
93
94void
95xfree(void *ptr)
96{
97 if (ptr == NULL)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +000098 fatalx("null pointer");
Nicholas Marriotta41ece52007-07-09 19:04:12 +000099 free(ptr);
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000100
101#ifdef DEBUG
102 xmalloc_free(ptr);
103#endif
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000104}
105
106int printflike2
107xasprintf(char **ret, const char *fmt, ...)
108{
109 va_list ap;
110 int i;
111
112 va_start(ap, fmt);
113 i = xvasprintf(ret, fmt, ap);
114 va_end(ap);
115
116 return (i);
117}
118
119int
120xvasprintf(char **ret, const char *fmt, va_list ap)
121{
122 int i;
123
124 i = vasprintf(ret, fmt, ap);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000125 if (i < 0 || *ret == NULL)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000126 fatal("xvasprintf failed");
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000127
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000128#ifdef DEBUG
129 xmalloc_new(xmalloc_caller(), *ret, i + 1);
130#endif
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000131 return (i);
132}
133
134int printflike3
135xsnprintf(char *buf, size_t len, const char *fmt, ...)
136{
137 va_list ap;
138 int i;
139
140 va_start(ap, fmt);
141 i = xvsnprintf(buf, len, fmt, ap);
142 va_end(ap);
143
144 return (i);
145}
146
147int
148xvsnprintf(char *buf, size_t len, const char *fmt, va_list ap)
149{
150 int i;
151
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000152 if (len > INT_MAX)
153 fatalx("len > INT_MAX");
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000154
155 i = vsnprintf(buf, len, fmt, ap);
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000156 if (i < 0)
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000157 fatal("vsnprintf failed");
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000158
159 return (i);
160}
161
162/*
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000163 * Some systems modify the path in place. This function and xbasename below
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000164 * avoid that by using a temporary buffer.
165 */
166char *
167xdirname(const char *src)
168{
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000169 static char dst[MAXPATHLEN];
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000170
171 strlcpy(dst, src, sizeof dst);
172 return (dirname(dst));
173}
174
175char *
176xbasename(const char *src)
177{
Nicholas Marriott4b62b1d2007-07-25 23:13:18 +0000178 static char dst[MAXPATHLEN];
Nicholas Marriotta41ece52007-07-09 19:04:12 +0000179
180 strlcpy(dst, src, sizeof dst);
181 return (basename(dst));
182}