/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 | 514k | { |
25 | 514k | size_t newsize; |
26 | 514k | void *ptr; |
27 | | |
28 | 514k | if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) |
29 | 0 | return NULL; |
30 | | |
31 | 514k | if ((ptr = git__malloc(newsize))) |
32 | 514k | memset(ptr, 0, newsize); |
33 | | |
34 | 514k | return ptr; |
35 | 514k | } |
36 | | |
37 | | void *git__reallocarray(void *ptr, size_t nelem, size_t elsize) |
38 | 13.0k | { |
39 | 13.0k | size_t newsize; |
40 | | |
41 | 13.0k | if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize)) |
42 | 0 | return NULL; |
43 | | |
44 | 13.0k | return git__realloc(ptr, newsize); |
45 | 13.0k | } |
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 | 5 | { |
54 | 5 | size_t len = strlen(str) + 1; |
55 | 5 | void *ptr = git__malloc(len); |
56 | | |
57 | 5 | if (ptr) |
58 | 5 | memcpy(ptr, str, len); |
59 | | |
60 | 5 | return ptr; |
61 | 5 | } |
62 | | |
63 | | char *git__strndup(const char *str, size_t n) |
64 | 0 | { |
65 | 0 | size_t len = p_strnlen(str, n); |
66 | 0 | char *ptr = git__malloc(len + 1); |
67 | |
|
68 | 0 | if (ptr) { |
69 | 0 | memcpy(ptr, str, len); |
70 | 0 | ptr[len] = '\0'; |
71 | 0 | } |
72 | |
|
73 | 0 | return ptr; |
74 | 0 | } |
75 | | |
76 | | char *git__substrdup(const char *str, size_t n) |
77 | 0 | { |
78 | 0 | char *ptr = git__malloc(n + 1); |
79 | |
|
80 | 0 | if (ptr) { |
81 | 0 | memcpy(ptr, str, n); |
82 | 0 | ptr[n] = '\0'; |
83 | 0 | } |
84 | |
|
85 | 0 | return ptr; |
86 | 0 | } |
87 | | |
88 | | static int setup_default_allocator(void) |
89 | 2 | { |
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 | 2 | return git_stdalloc_init_allocator(&git__allocator); |
96 | 2 | #endif |
97 | 2 | } |
98 | | |
99 | | int git_allocator_global_init(void) |
100 | 2 | { |
101 | | /* |
102 | | * We don't want to overwrite any allocator which has been set |
103 | | * before the init function is called. |
104 | | */ |
105 | 2 | if (git__allocator.gmalloc != git_failalloc_malloc) |
106 | 0 | return 0; |
107 | | |
108 | 2 | return setup_default_allocator(); |
109 | 2 | } |
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 | } |