Coverage Report

Created: 2026-02-12 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avahi/avahi-common/malloc.c
Line
Count
Source
1
/***
2
  This file is part of avahi.
3
4
  avahi is free software; you can redistribute it and/or modify it
5
  under the terms of the GNU Lesser General Public License as
6
  published by the Free Software Foundation; either version 2.1 of the
7
  License, or (at your option) any later version.
8
9
  avahi is distributed in the hope that it will be useful, but WITHOUT
10
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
12
  Public License for more details.
13
14
  You should have received a copy of the GNU Lesser General Public
15
  License along with avahi; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17
  USA.
18
***/
19
20
#ifdef HAVE_CONFIG_H
21
#include <config.h>
22
#endif
23
24
#include <stdlib.h>
25
#include <string.h>
26
#include <assert.h>
27
#include <stdio.h>
28
#include <unistd.h>
29
30
#include "malloc.h"
31
32
#ifndef va_copy
33
#ifdef __va_copy
34
#define va_copy(DEST,SRC) __va_copy((DEST),(SRC))
35
#else
36
#define va_copy(DEST,SRC) memcpy(&(DEST), &(SRC), sizeof(va_list))
37
#endif
38
#endif
39
40
static const AvahiAllocator *allocator = NULL;
41
42
static void oom(void) AVAHI_GCC_NORETURN;
43
44
0
static void oom(void) {
45
46
0
    static const char msg[] = "Out of memory, aborting ...\n";
47
0
    const char *n = msg;
48
49
0
    while (strlen(n) > 0) {
50
0
        ssize_t r;
51
52
0
        if ((r = write(2, n, strlen(n))) < 0)
53
0
            break;
54
55
0
        n += r;
56
0
    }
57
58
0
    abort();
59
0
}
60
61
/* Default implementation for avahi_malloc() */
62
3.76M
static void* xmalloc(size_t size) {
63
3.76M
    void *p;
64
65
3.76M
    if (size == 0)
66
0
        return NULL;
67
68
3.76M
    if (!(p = malloc(size)))
69
0
        oom();
70
71
3.76M
    return p;
72
3.76M
}
73
74
/* Default implementation for avahi_realloc() */
75
12.3k
static void *xrealloc(void *p, size_t size) {
76
77
12.3k
    if (size == 0) {
78
0
        free(p);
79
0
        return NULL;
80
0
    }
81
82
12.3k
    if (!(p = realloc(p, size)))
83
0
        oom();
84
85
12.3k
    return p;
86
12.3k
}
87
88
/* Default implementation for avahi_calloc() */
89
2.43k
static void *xcalloc(size_t nmemb, size_t size) {
90
2.43k
    void *p;
91
92
2.43k
    if (size == 0 || nmemb == 0)
93
0
        return NULL;
94
95
2.43k
    if (!(p = calloc(nmemb, size)))
96
0
        oom();
97
98
2.43k
    return p;
99
2.43k
}
100
101
3.76M
void *avahi_malloc(size_t size) {
102
103
3.76M
    if (size <= 0)
104
0
        return NULL;
105
106
3.76M
    if (!allocator)
107
3.76M
        return xmalloc(size);
108
109
3.76M
    assert(allocator->malloc);
110
0
    return allocator->malloc(size);
111
0
}
112
113
2.43k
void *avahi_malloc0(size_t size) {
114
2.43k
    void *p;
115
116
2.43k
    if (size <= 0)
117
0
        return NULL;
118
119
2.43k
    if (!allocator)
120
2.43k
        return xcalloc(1, size);
121
122
0
    if (allocator->calloc)
123
0
        return allocator->calloc(1, size);
124
125
0
    assert(allocator->malloc);
126
0
    if ((p = allocator->malloc(size)))
127
0
        memset(p, 0, size);
128
129
0
    return p;
130
0
}
131
132
3.80M
void avahi_free(void *p) {
133
134
3.80M
    if (!p)
135
42.5k
        return;
136
137
3.76M
    if (!allocator) {
138
3.76M
        free(p);
139
3.76M
        return;
140
3.76M
    }
141
142
3.76M
    assert(allocator->free);
143
0
    allocator->free(p);
144
0
}
145
146
12.3k
void *avahi_realloc(void *p, size_t size) {
147
148
12.3k
    if (size == 0) {
149
0
        avahi_free(p);
150
0
        return NULL;
151
0
    }
152
153
12.3k
    if (!allocator)
154
12.3k
        return xrealloc(p, size);
155
156
12.3k
    assert(allocator->realloc);
157
0
    return allocator->realloc(p, size);
158
0
}
159
160
208k
char *avahi_strdup(const char *s) {
161
208k
    char *r;
162
208k
    size_t size;
163
164
208k
    if (!s)
165
0
        return NULL;
166
167
208k
    size = strlen(s);
168
208k
    if (!(r = avahi_malloc(size+1)))
169
0
        return NULL;
170
171
208k
    memcpy(r, s, size+1);
172
208k
    return r;
173
208k
}
174
175
6.06k
char *avahi_strndup(const char *s, size_t max) {
176
6.06k
    char *r;
177
6.06k
    size_t size;
178
6.06k
    const char *p;
179
180
6.06k
    if (!s)
181
0
        return NULL;
182
183
6.06k
    for (p = s, size = 0;
184
20.7k
         size < max && *p;
185
14.7k
         p++, size++);
186
187
6.06k
    if (!(r = avahi_new(char, size+1)))
188
0
        return NULL;
189
190
6.06k
    memcpy(r, s, size);
191
6.06k
    r[size] = 0;
192
6.06k
    return r;
193
6.06k
}
194
195
/* Change the allocator */
196
0
void avahi_set_allocator(const AvahiAllocator *a) {
197
0
    allocator = a;
198
0
}
199
200
149k
char *avahi_strdup_vprintf(const char *fmt, va_list ap) {
201
149k
    size_t len = 80;
202
149k
    char *buf;
203
204
149k
    assert(fmt);
205
206
149k
    if (!(buf = avahi_malloc(len)))
207
0
        return NULL;
208
209
161k
    for (;;) {
210
161k
        int n;
211
161k
        char *nbuf;
212
161k
        va_list ap2;
213
214
161k
        va_copy (ap2, ap);
215
161k
        n = vsnprintf(buf, len, fmt, ap2);
216
161k
        va_end (ap2);
217
218
161k
        if (n >= 0 && n < (int) len)
219
149k
            return buf;
220
221
12.3k
        if (n >= 0)
222
12.3k
            len = n+1;
223
0
        else
224
0
            len *= 2;
225
226
12.3k
        if (!(nbuf = avahi_realloc(buf, len))) {
227
0
            avahi_free(buf);
228
0
            return NULL;
229
0
        }
230
231
12.3k
        buf = nbuf;
232
12.3k
    }
233
149k
}
234
235
149k
char *avahi_strdup_printf(const char *fmt, ... ) {
236
149k
    char *s;
237
149k
    va_list ap;
238
239
149k
    assert(fmt);
240
241
149k
    va_start(ap, fmt);
242
149k
    s = avahi_strdup_vprintf(fmt, ap);
243
149k
    va_end(ap);
244
245
149k
    return s;
246
149k
}
247
248
4.69k
void *avahi_memdup(const void *s, size_t l) {
249
4.69k
    void *p;
250
4.69k
    assert(s);
251
252
4.69k
    if (!(p = avahi_malloc(l)))
253
0
        return NULL;
254
255
4.69k
    memcpy(p, s, l);
256
4.69k
    return p;
257
4.69k
}