]> granicus.if.org Git - strace/blob - xmalloc.c
evdev: decode struct input_absinfo regardless of in-kernel definitions
[strace] / xmalloc.c
1 /*
2  * Copyright (c) 2015 Dmitry V. Levin <ldv@altlinux.org>
3  * Copyright (c) 2015-2019 The strace developers.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: LGPL-2.1-or-later
7  */
8
9 #ifdef HAVE_CONFIG_H
10 # include "config.h"
11 #endif
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "error_prints.h"
17 #include "xmalloc.h"
18
19 static void
20 die_out_of_memory(void)
21 {
22         static int recursed;
23
24         if (recursed)
25                 exit(1);
26         recursed = 1;
27
28         error_msg_and_die("Out of memory");
29 }
30
31 void *
32 xmalloc(size_t size)
33 {
34         void *p = malloc(size);
35
36         if (!p)
37                 die_out_of_memory();
38
39         return p;
40 }
41
42 void *
43 xcalloc(size_t nmemb, size_t size)
44 {
45         void *p = calloc(nmemb, size);
46
47         if (!p)
48                 die_out_of_memory();
49
50         return p;
51 }
52
53 #define HALF_SIZE_T     (((size_t) 1) << (sizeof(size_t) * 4))
54
55 void *
56 xreallocarray(void *ptr, size_t nmemb, size_t size)
57 {
58         size_t bytes = nmemb * size;
59
60         if ((nmemb | size) >= HALF_SIZE_T &&
61             size && bytes / size != nmemb)
62                 die_out_of_memory();
63
64         void *p = realloc(ptr, bytes);
65
66         if (!p)
67                 die_out_of_memory();
68
69         return p;
70 }
71
72 void *
73 xgrowarray(void *const ptr, size_t *const nmemb, const size_t memb_size)
74 {
75         /* this is the same value as glibc DEFAULT_MXFAST */
76         enum { DEFAULT_ALLOC_SIZE = 64 * SIZEOF_LONG / 4 };
77
78         size_t grow_memb;
79
80         if (ptr == NULL)
81                 grow_memb = *nmemb ? 0 :
82                         (DEFAULT_ALLOC_SIZE + memb_size - 1) / memb_size;
83         else
84                 grow_memb = (*nmemb >> 1) + 1;
85
86         if ((*nmemb + grow_memb) < *nmemb)
87                 die_out_of_memory();
88
89         *nmemb += grow_memb;
90
91         return xreallocarray(ptr, *nmemb, memb_size);
92 }
93
94 char *
95 xstrdup(const char *str)
96 {
97         if (!str)
98                 return NULL;
99
100         char *p = strdup(str);
101
102         if (!p)
103                 die_out_of_memory();
104
105         return p;
106 }
107
108 char *
109 xstrndup(const char *str, size_t n)
110 {
111         char *p;
112
113         if (!str)
114                 return NULL;
115
116 #ifdef HAVE_STRNDUP
117         p = strndup(str, n);
118 #else
119         p = xmalloc(n + 1);
120 #endif
121
122         if (!p)
123                 die_out_of_memory();
124
125 #ifndef HAVE_STRNDUP
126         strncpy(p, str, n);
127         p[n] = '\0';
128 #endif
129
130         return p;
131 }