]>
Commit | Line | Data |
---|---|---|
bb742ede | 1 | /* |
359fc2d2 | 2 | * Copyright (C) the libgit2 contributors. All rights reserved. |
bb742ede VM |
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 | */ | |
76a8c447 AE |
7 | #ifndef INCLUDE_common_h__ |
8 | #define INCLUDE_common_h__ | |
9 | ||
0657e46d | 10 | #include "git2/common.h" |
8a086f87 | 11 | #include "cc-compat.h" |
b3039bee | 12 | |
72556cc6 RB |
13 | /** Declare a function as always inlined. */ |
14 | #if defined(_MSC_VER) | |
15 | # define GIT_INLINE(type) static __inline type | |
16 | #else | |
17 | # define GIT_INLINE(type) static inline type | |
18 | #endif | |
19 | ||
16942c6f ET |
20 | /** Support for gcc/clang __has_builtin intrinsic */ |
21 | #ifndef __has_builtin | |
22 | # define __has_builtin(x) 0 | |
23 | #endif | |
24 | ||
75d58430 | 25 | #include <assert.h> |
76a8c447 | 26 | #include <errno.h> |
028ef0de | 27 | #include <limits.h> |
76a8c447 | 28 | #include <stdlib.h> |
840fb8b7 | 29 | #include <stdio.h> |
76a8c447 AE |
30 | #include <string.h> |
31 | ||
840fb8b7 | 32 | #include <sys/types.h> |
90d4d2f0 | 33 | #include <sys/stat.h> |
840fb8b7 RJ |
34 | |
35 | #ifdef GIT_WIN32 | |
36 | ||
37 | # include <io.h> | |
502acd16 | 38 | # include <direct.h> |
ac8eac2f | 39 | # include <winsock2.h> |
79ca2edc | 40 | # include <windows.h> |
45df2237 | 41 | # include <ws2tcpip.h> |
678e9e04 VM |
42 | # include "win32/msvc-compat.h" |
43 | # include "win32/mingw-compat.h" | |
360dd4da | 44 | # include "win32/win32-compat.h" |
c70455c7 | 45 | # include "win32/error.h" |
5c5eeba6 | 46 | # include "win32/version.h" |
bb3de0c4 | 47 | # ifdef GIT_THREADS |
87d9869f | 48 | # include "win32/pthread.h" |
5c5eeba6 | 49 | # endif |
93b42728 JH |
50 | # if defined(GIT_MSVC_CRTDBG) |
51 | # include "win32/w32_stack.h" | |
52 | # include "win32/w32_crtdbg_stacktrace.h" | |
53 | # endif | |
79ca2edc | 54 | |
840fb8b7 | 55 | #else |
840fb8b7 | 56 | |
f443a72d | 57 | # include <unistd.h> |
6b05240c | 58 | # include <strings.h> |
bb3de0c4 | 59 | # ifdef GIT_THREADS |
87d9869f | 60 | # include <pthread.h> |
8a2834d3 | 61 | # include <sched.h> |
bb3de0c4 | 62 | # endif |
97b71374 RB |
63 | #define GIT_STDLIB_CALL |
64 | ||
9447b9e5 ET |
65 | #ifdef GIT_USE_STAT_ATIMESPEC |
66 | # define st_atim st_atimespec | |
67 | # define st_ctim st_ctimespec | |
68 | # define st_mtim st_mtimespec | |
69 | #endif | |
70 | ||
5588f073 ET |
71 | # include <arpa/inet.h> |
72 | ||
840fb8b7 RJ |
73 | #endif |
74 | ||
e52e38d3 | 75 | #include "git2/types.h" |
6810bf28 | 76 | #include "git2/errors.h" |
028ef0de | 77 | #include "thread-utils.h" |
190b76a6 | 78 | #include "integer.h" |
5ee2fe77 | 79 | |
dda708e7 VM |
80 | #include <regex.h> |
81 | ||
7dd22538 W |
82 | #define DEFAULT_BUFSIZE 65536 |
83 | #define FILEIO_BUFSIZE DEFAULT_BUFSIZE | |
84 | #define FILTERIO_BUFSIZE DEFAULT_BUFSIZE | |
85 | #define NETIO_BUFSIZE DEFAULT_BUFSIZE | |
86 | ||
1a628100 RB |
87 | /** |
88 | * Check a pointer allocation result, returning -1 if it failed. | |
89 | */ | |
dda708e7 VM |
90 | #define GITERR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; } |
91 | ||
859ed5dd PS |
92 | /** |
93 | * Check a buffer allocation result, returning -1 if it failed. | |
94 | */ | |
95 | #define GITERR_CHECK_ALLOC_BUF(buf) if ((void *)(buf) == NULL || git_buf_oom(buf)) { return -1; } | |
96 | ||
5540d947 | 97 | /** |
b874629b | 98 | * Check a return value and propagate result if non-zero. |
5540d947 RB |
99 | */ |
100 | #define GITERR_CHECK_ERROR(code) \ | |
25e0b157 | 101 | do { int _err = (code); if (_err) return _err; } while (0) |
5540d947 | 102 | |
1a628100 RB |
103 | /** |
104 | * Set the error message for this thread, formatting as needed. | |
105 | */ | |
dda708e7 | 106 | void giterr_set(int error_class, const char *string, ...); |
1a628100 RB |
107 | |
108 | /** | |
109 | * Set the error message for a regex failure, using the internal regex | |
cc146626 | 110 | * error code lookup and return a libgit error code. |
1a628100 | 111 | */ |
cc146626 | 112 | int giterr_set_regex(const regex_t *regex, int error_code); |
dda708e7 | 113 | |
25e0b157 RB |
114 | /** |
115 | * Set error message for user callback if needed. | |
116 | * | |
117 | * If the error code in non-zero and no error message is set, this | |
118 | * sets a generic error message. | |
119 | * | |
120 | * @return This always returns the `error_code` parameter. | |
121 | */ | |
26c1cb91 RB |
122 | GIT_INLINE(int) giterr_set_after_callback_function( |
123 | int error_code, const char *action) | |
25e0b157 RB |
124 | { |
125 | if (error_code) { | |
126 | const git_error *e = giterr_last(); | |
127 | if (!e || !e->message) | |
128 | giterr_set(e ? e->klass : GITERR_CALLBACK, | |
129 | "%s callback returned %d", action, error_code); | |
130 | } | |
131 | return error_code; | |
132 | } | |
133 | ||
60058018 | 134 | #ifdef GIT_WIN32 |
26c1cb91 RB |
135 | #define giterr_set_after_callback(code) \ |
136 | giterr_set_after_callback_function((code), __FUNCTION__) | |
60058018 | 137 | #else |
26c1cb91 RB |
138 | #define giterr_set_after_callback(code) \ |
139 | giterr_set_after_callback_function((code), __func__) | |
60058018 | 140 | #endif |
25e0b157 | 141 | |
c2408a69 ET |
142 | /** |
143 | * Gets the system error code for this thread. | |
144 | */ | |
96869a4e | 145 | int giterr_system_last(void); |
c2408a69 ET |
146 | |
147 | /** | |
148 | * Sets the system error code for this thread. | |
149 | */ | |
96869a4e RB |
150 | void giterr_system_set(int code); |
151 | ||
96869a4e RB |
152 | /** |
153 | * Structure to preserve libgit2 error state | |
154 | */ | |
155 | typedef struct { | |
ef4857c2 ET |
156 | int error_code; |
157 | unsigned int oom : 1; | |
96869a4e RB |
158 | git_error error_msg; |
159 | } git_error_state; | |
160 | ||
161 | /** | |
162 | * Capture current error state to restore later, returning error code. | |
ef4857c2 ET |
163 | * If `error_code` is zero, this does not clear the current error state. |
164 | * You must either restore this error state, or free it. | |
96869a4e | 165 | */ |
ef4857c2 | 166 | extern int giterr_state_capture(git_error_state *state, int error_code); |
96869a4e RB |
167 | |
168 | /** | |
169 | * Restore error state to a previous value, returning saved error code. | |
170 | */ | |
ef4857c2 ET |
171 | extern int giterr_state_restore(git_error_state *state); |
172 | ||
173 | /** Free an error state. */ | |
174 | extern void giterr_state_free(git_error_state *state); | |
96869a4e | 175 | |
c7231c45 BS |
176 | /** |
177 | * Check a versioned structure for validity | |
178 | */ | |
bf192cdb | 179 | GIT_INLINE(int) giterr__check_version(const void *structure, unsigned int expected_max, const char *name) |
c7231c45 | 180 | { |
43efaabd | 181 | unsigned int actual; |
8ff66112 | 182 | |
c7231c45 | 183 | if (!structure) |
bf192cdb | 184 | return 0; |
c7231c45 | 185 | |
43efaabd | 186 | actual = *(const unsigned int*)structure; |
c7231c45 | 187 | if (actual > 0 && actual <= expected_max) |
bf192cdb | 188 | return 0; |
c7231c45 BS |
189 | |
190 | giterr_set(GITERR_INVALID, "Invalid version %d on %s", actual, name); | |
bf192cdb | 191 | return -1; |
c7231c45 | 192 | } |
bf192cdb | 193 | #define GITERR_CHECK_VERSION(S,V,N) if (giterr__check_version(S,V,N) < 0) return -1 |
c7231c45 | 194 | |
0ab3a2ab BS |
195 | /** |
196 | * Initialize a structure with a version. | |
197 | */ | |
198 | GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version) | |
199 | { | |
200 | memset(structure, 0, len); | |
201 | *((int*)structure) = version; | |
202 | } | |
203 | #define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V) | |
204 | ||
702efc89 RB |
205 | #define GIT_INIT_STRUCTURE_FROM_TEMPLATE(PTR,VERSION,TYPE,TPL) do { \ |
206 | TYPE _tmpl = TPL; \ | |
207 | GITERR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE); \ | |
208 | memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0) | |
209 | ||
190b76a6 | 210 | |
f1453c59 ET |
211 | /** Check for additive overflow, setting an error if would occur. */ |
212 | #define GIT_ADD_SIZET_OVERFLOW(out, one, two) \ | |
213 | (git__add_sizet_overflow(out, one, two) ? (giterr_set_oom(), 1) : 0) | |
392702ee | 214 | |
f1453c59 ET |
215 | /** Check for additive overflow, setting an error if would occur. */ |
216 | #define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \ | |
217 | (git__multiply_sizet_overflow(out, nelem, elsize) ? (giterr_set_oom(), 1) : 0) | |
392702ee ET |
218 | |
219 | /** Check for additive overflow, failing if it would occur. */ | |
f1453c59 ET |
220 | #define GITERR_CHECK_ALLOC_ADD(out, one, two) \ |
221 | if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; } | |
392702ee | 222 | |
4bc9b74c ET |
223 | #define GITERR_CHECK_ALLOC_ADD3(out, one, two, three) \ |
224 | if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ | |
225 | GIT_ADD_SIZET_OVERFLOW(out, *(out), three)) { return -1; } | |
226 | ||
227 | #define GITERR_CHECK_ALLOC_ADD4(out, one, two, three, four) \ | |
228 | if (GIT_ADD_SIZET_OVERFLOW(out, one, two) || \ | |
229 | GIT_ADD_SIZET_OVERFLOW(out, *(out), three) || \ | |
230 | GIT_ADD_SIZET_OVERFLOW(out, *(out), four)) { return -1; } | |
231 | ||
392702ee | 232 | /** Check for multiplicative overflow, failing if it would occur. */ |
f1453c59 ET |
233 | #define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \ |
234 | if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; } | |
392702ee | 235 | |
1a628100 RB |
236 | /* NOTE: other giterr functions are in the public errors.h header file */ |
237 | ||
3f53c971 VM |
238 | #include "util.h" |
239 | ||
76a8c447 | 240 | #endif /* INCLUDE_common_h__ */ |