/src/libgit2/src/util/alloc.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) the libgit2 contributors. All rights reserved. |
3 | | * |
4 | | * This file is part of libgit2, distributed under the GNU GPL v2 with |
5 | | * a Linking Exception. For full terms see the included COPYING file. |
6 | | */ |
7 | | |
8 | | #include "alloc.h" |
9 | | #include "runtime.h" |
10 | | |
11 | | #include "allocators/stdalloc.h" |
12 | | #include "allocators/debugalloc.h" |
13 | | #include "allocators/failalloc.h" |
14 | | #include "allocators/win32_leakcheck.h" |
15 | | |
16 | | /* Fail any allocation until git_libgit2_init is called. */ |
17 | | git_allocator git__allocator = { |
18 | | git_failalloc_malloc, |
19 | | git_failalloc_realloc, |
20 | | git_failalloc_free |
21 | | }; |
22 | | |
23 | | void *git__calloc(size_t nelem, size_t elsize) |
24 | 1.35M | { |
25 | 1.35M | size_t newsize; |
26 | 1.35M | void *ptr; |
27 | | |
28 | 1.35M | if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) |
29 | 0 | return NULL; |
30 | | |
31 | 1.35M | if ((ptr = git__malloc(newsize))) |
32 | 1.35M | memset(ptr, 0, newsize); |
33 | | |
34 | 1.35M | return ptr; |
35 | 1.35M | } |
36 | | |
37 | | void *git__reallocarray(void *ptr, size_t nelem, size_t elsize) |
38 | 386k | { |
39 | 386k | size_t newsize; |
40 | | |
41 | 386k | if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) |
42 | 0 | return NULL; |
43 | | |
44 | 386k | return git__realloc(ptr, newsize); |
45 | 386k | } |
46 | | |
47 | | void *git__mallocarray(size_t nelem, size_t elsize) |
48 | 0 | { |
49 | 0 | return git__reallocarray(NULL, nelem, elsize); |
50 | 0 | } |
51 | | |
52 | | char *git__strdup(const char *str) |
53 | 354k | { |
54 | 354k | size_t len = strlen(str) + 1; |
55 | 354k | void *ptr = git__malloc(len); |
56 | | |
57 | 354k | if (ptr) |
58 | 354k | memcpy(ptr, str, len); |
59 | | |
60 | 354k | return ptr; |
61 | 354k | } |
62 | | |
63 | | char *git__strndup(const char *str, size_t n) |
64 | 8.42M | { |
65 | 8.42M | size_t len = p_strnlen(str, n); |
66 | 8.42M | char *ptr = git__malloc(len + 1); |
67 | | |
68 | 8.42M | if (ptr) { |
69 | 8.42M | memcpy(ptr, str, len); |
70 | 8.42M | ptr[len] = '\0'; |
71 | 8.42M | } |
72 | | |
73 | 8.42M | return ptr; |
74 | 8.42M | } |
75 | | |
76 | | char *git__substrdup(const char *str, size_t n) |
77 | 14.6k | { |
78 | 14.6k | char *ptr = git__malloc(n + 1); |
79 | | |
80 | 14.6k | if (ptr) { |
81 | 14.6k | memcpy(ptr, str, n); |
82 | 14.6k | ptr[n] = '\0'; |
83 | 14.6k | } |
84 | | |
85 | 14.6k | return ptr; |
86 | 14.6k | } |
87 | | |
88 | | static int setup_default_allocator(void) |
89 | 15 | { |
90 | | #if defined(GIT_DEBUG_LEAKCHECK_WIN32) |
91 | | return git_win32_leakcheck_init_allocator(&git__allocator); |
92 | | #elif defined(GIT_DEBUG_STRICT_ALLOC) |
93 | | return git_debugalloc_init_allocator(&git__allocator); |
94 | | #else |
95 | 15 | return git_stdalloc_init_allocator(&git__allocator); |
96 | 15 | #endif |
97 | 15 | } |
98 | | |
99 | | int git_allocator_global_init(void) |
100 | 15 | { |
101 | | /* |
102 | | * We don't want to overwrite any allocator which has been set |
103 | | * before the init function is called. |
104 | | */ |
105 | 15 | if (git__allocator.gmalloc != git_failalloc_malloc) |
106 | 0 | return 0; |
107 | | |
108 | 15 | return setup_default_allocator(); |
109 | 15 | } |
110 | | |
111 | | int git_allocator_setup(git_allocator *allocator) |
112 | 0 | { |
113 | 0 | if (!allocator) |
114 | 0 | return setup_default_allocator(); |
115 | | |
116 | 0 | memcpy(&git__allocator, allocator, sizeof(*allocator)); |
117 | 0 | return 0; |
118 | 0 | } |