Coverage Report

Created: 2026-01-10 06:10

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.72k
static void* xmalloc(size_t size) {
63
3.72k
    void *p;
64
65
3.72k
    if (size == 0)
66
0
        return NULL;
67
68
3.72k
    if (!(p = malloc(size)))
69
0
        oom();
70
71
3.72k
    return p;
72
3.72k
}
73
74
/* Default implementation for avahi_realloc() */
75
157
static void *xrealloc(void *p, size_t size) {
76
77
157
    if (size == 0) {
78
0
        free(p);
79
0
        return NULL;
80
0
    }
81
82
157
    if (!(p = realloc(p, size)))
83
0
        oom();
84
85
157
    return p;
86
157
}
87
88
/* Default implementation for avahi_calloc() */
89
0
static void *xcalloc(size_t nmemb, size_t size) {
90
0
    void *p;
91
92
0
    if (size == 0 || nmemb == 0)
93
0
        return NULL;
94
95
0
    if (!(p = calloc(nmemb, size)))
96
0
        oom();
97
98
0
    return p;
99
0
}
100
101
3.72k
void *avahi_malloc(size_t size) {
102
103
3.72k
    if (size <= 0)
104
0
        return NULL;
105
106
3.72k
    if (!allocator)
107
3.72k
        return xmalloc(size);
108
109
3.72k
    assert(allocator->malloc);
110
0
    return allocator->malloc(size);
111
0
}
112
113
0
void *avahi_malloc0(size_t size) {
114
0
    void *p;
115
116
0
    if (size <= 0)
117
0
        return NULL;
118
119
0
    if (!allocator)
120
0
        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.72k
void avahi_free(void *p) {
133
134
3.72k
    if (!p)
135
0
        return;
136
137
3.72k
    if (!allocator) {
138
3.72k
        free(p);
139
3.72k
        return;
140
3.72k
    }
141
142
3.72k
    assert(allocator->free);
143
0
    allocator->free(p);
144
0
}
145
146
157
void *avahi_realloc(void *p, size_t size) {
147
148
157
    if (size == 0) {
149
0
        avahi_free(p);
150
0
        return NULL;
151
0
    }
152
153
157
    if (!allocator)
154
157
        return xrealloc(p, size);
155
156
157
    assert(allocator->realloc);
157
0
    return allocator->realloc(p, size);
158
0
}
159
160
990
char *avahi_strdup(const char *s) {
161
990
    char *r;
162
990
    size_t size;
163
164
990
    if (!s)
165
0
        return NULL;
166
167
990
    size = strlen(s);
168
990
    if (!(r = avahi_malloc(size+1)))
169
0
        return NULL;
170
171
990
    memcpy(r, s, size+1);
172
990
    return r;
173
990
}
174
175
0
char *avahi_strndup(const char *s, size_t max) {
176
0
    char *r;
177
0
    size_t size;
178
0
    const char *p;
179
180
0
    if (!s)
181
0
        return NULL;
182
183
0
    for (p = s, size = 0;
184
0
         size < max && *p;
185
0
         p++, size++);
186
187
0
    if (!(r = avahi_new(char, size+1)))
188
0
        return NULL;
189
190
0
    memcpy(r, s, size);
191
0
    r[size] = 0;
192
0
    return r;
193
0
}
194
195
/* Change the allocator */
196
0
void avahi_set_allocator(const AvahiAllocator *a) {
197
0
    allocator = a;
198
0
}
199
200
631
char *avahi_strdup_vprintf(const char *fmt, va_list ap) {
201
631
    size_t len = 80;
202
631
    char *buf;
203
204
631
    assert(fmt);
205
206
631
    if (!(buf = avahi_malloc(len)))
207
0
        return NULL;
208
209
788
    for (;;) {
210
788
        int n;
211
788
        char *nbuf;
212
788
        va_list ap2;
213
214
788
        va_copy (ap2, ap);
215
788
        n = vsnprintf(buf, len, fmt, ap2);
216
788
        va_end (ap2);
217
218
788
        if (n >= 0 && n < (int) len)
219
631
            return buf;
220
221
157
        if (n >= 0)
222
157
            len = n+1;
223
0
        else
224
0
            len *= 2;
225
226
157
        if (!(nbuf = avahi_realloc(buf, len))) {
227
0
            avahi_free(buf);
228
0
            return NULL;
229
0
        }
230
231
157
        buf = nbuf;
232
157
    }
233
631
}
234
235
631
char *avahi_strdup_printf(const char *fmt, ... ) {
236
631
    char *s;
237
631
    va_list ap;
238
239
631
    assert(fmt);
240
241
631
    va_start(ap, fmt);
242
631
    s = avahi_strdup_vprintf(fmt, ap);
243
631
    va_end(ap);
244
245
631
    return s;
246
631
}
247
248
0
void *avahi_memdup(const void *s, size_t l) {
249
0
    void *p;
250
0
    assert(s);
251
252
0
    if (!(p = avahi_malloc(l)))
253
0
        return NULL;
254
255
0
    memcpy(p, s, l);
256
0
    return p;
257
0
}