1/* $OpenBSD: xmalloc.c,v 1.13 2019/11/28 09:51:58 nicm Exp $ */
2
3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
6 *                    All rights reserved
7 * Versions of malloc and friends that check their results, and never return
8 * failure (they call fatalx if they encounter an error).
9 *
10 * As far as I am concerned, the code I have written for this software
11 * can be used freely for any purpose.  Any derived versions of this
12 * software must be clearly marked as such, and if the derived work is
13 * incompatible with the protocol description in the RFC file, it must be
14 * called by a name other than "ssh" or "Secure Shell".
15 */
16
17#include <errno.h>
18#include <limits.h>
19#include <stdint.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include "tmux.h"
25
26void *
27xmalloc(size_t size)
28{
29	void *ptr;
30
31	if (size == 0)
32		fatalx("xmalloc: zero size");
33	ptr = malloc(size);
34	if (ptr == NULL)
35		fatalx("xmalloc: allocating %zu bytes: %s",
36		    size, strerror(errno));
37	return ptr;
38}
39
40void *
41xcalloc(size_t nmemb, size_t size)
42{
43	void *ptr;
44
45	if (size == 0 || nmemb == 0)
46		fatalx("xcalloc: zero size");
47	ptr = calloc(nmemb, size);
48	if (ptr == NULL)
49		fatalx("xcalloc: allocating %zu * %zu bytes: %s",
50		    nmemb, size, strerror(errno));
51	return ptr;
52}
53
54void *
55xrealloc(void *ptr, size_t size)
56{
57	return xreallocarray(ptr, 1, size);
58}
59
60void *
61xreallocarray(void *ptr, size_t nmemb, size_t size)
62{
63	void *new_ptr;
64
65	if (nmemb == 0 || size == 0)
66		fatalx("xreallocarray: zero size");
67	new_ptr = reallocarray(ptr, nmemb, size);
68	if (new_ptr == NULL)
69		fatalx("xreallocarray: allocating %zu * %zu bytes: %s",
70		    nmemb, size, strerror(errno));
71	return new_ptr;
72}
73
74void *
75xrecallocarray(void *ptr, size_t oldnmemb, size_t nmemb, size_t size)
76{
77	void *new_ptr;
78
79	if (nmemb == 0 || size == 0)
80		fatalx("xrecallocarray: zero size");
81	new_ptr = recallocarray(ptr, oldnmemb, nmemb, size);
82	if (new_ptr == NULL)
83		fatalx("xrecallocarray: allocating %zu * %zu bytes: %s",
84		    nmemb, size, strerror(errno));
85	return new_ptr;
86}
87
88char *
89xstrdup(const char *str)
90{
91	char *cp;
92
93	if ((cp = strdup(str)) == NULL)
94		fatalx("xstrdup: %s", strerror(errno));
95	return cp;
96}
97
98char *
99xstrndup(const char *str, size_t maxlen)
100{
101	char *cp;
102
103	if ((cp = strndup(str, maxlen)) == NULL)
104		fatalx("xstrndup: %s", strerror(errno));
105	return cp;
106}
107
108int
109xasprintf(char **ret, const char *fmt, ...)
110{
111	va_list ap;
112	int i;
113
114	va_start(ap, fmt);
115	i = xvasprintf(ret, fmt, ap);
116	va_end(ap);
117
118	return i;
119}
120
121int
122xvasprintf(char **ret, const char *fmt, va_list ap)
123{
124	int i;
125
126	i = vasprintf(ret, fmt, ap);
127
128	if (i == -1)
129		fatalx("xasprintf: %s", strerror(errno));
130
131	return i;
132}
133
134int
135xsnprintf(char *str, size_t len, const char *fmt, ...)
136{
137	va_list ap;
138	int i;
139
140	va_start(ap, fmt);
141	i = xvsnprintf(str, len, fmt, ap);
142	va_end(ap);
143
144	return i;
145}
146
147int
148xvsnprintf(char *str, size_t len, const char *fmt, va_list ap)
149{
150	int i;
151
152	if (len > INT_MAX)
153		fatalx("xsnprintf: len > INT_MAX");
154
155	i = vsnprintf(str, len, fmt, ap);
156
157	if (i < 0 || i >= (int)len)
158		fatalx("xsnprintf: overflow");
159
160	return i;
161}
162