]> git.proxmox.com Git - libgit2.git/blob - src/errors.c
Add dependency on ca-certificates and libpcre3-dev
[libgit2.git] / src / errors.c
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 "common.h"
9
10 #include "global.h"
11 #include "posix.h"
12 #include "buffer.h"
13
14 /********************************************
15 * New error handling
16 ********************************************/
17
18 static git_error g_git_oom_error = {
19 "Out of memory",
20 GIT_ERROR_NOMEMORY
21 };
22
23 static void set_error_from_buffer(int error_class)
24 {
25 git_error *error = &GIT_GLOBAL->error_t;
26 git_buf *buf = &GIT_GLOBAL->error_buf;
27
28 error->message = buf->ptr;
29 error->klass = error_class;
30
31 GIT_GLOBAL->last_error = error;
32 }
33
34 static void set_error(int error_class, char *string)
35 {
36 git_buf *buf = &GIT_GLOBAL->error_buf;
37
38 git_buf_clear(buf);
39 if (string) {
40 git_buf_puts(buf, string);
41 git__free(string);
42 }
43
44 set_error_from_buffer(error_class);
45 }
46
47 void git_error_set_oom(void)
48 {
49 GIT_GLOBAL->last_error = &g_git_oom_error;
50 }
51
52 void git_error_set(int error_class, const char *fmt, ...)
53 {
54 va_list ap;
55
56 va_start(ap, fmt);
57 git_error_vset(error_class, fmt, ap);
58 va_end(ap);
59 }
60
61 void git_error_vset(int error_class, const char *fmt, va_list ap)
62 {
63 #ifdef GIT_WIN32
64 DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
65 #endif
66 int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
67 git_buf *buf = &GIT_GLOBAL->error_buf;
68
69 git_buf_clear(buf);
70 if (fmt) {
71 git_buf_vprintf(buf, fmt, ap);
72 if (error_class == GIT_ERROR_OS)
73 git_buf_PUTS(buf, ": ");
74 }
75
76 if (error_class == GIT_ERROR_OS) {
77 #ifdef GIT_WIN32
78 char * win32_error = git_win32_get_error_message(win32_error_code);
79 if (win32_error) {
80 git_buf_puts(buf, win32_error);
81 git__free(win32_error);
82
83 SetLastError(0);
84 }
85 else
86 #endif
87 if (error_code)
88 git_buf_puts(buf, strerror(error_code));
89
90 if (error_code)
91 errno = 0;
92 }
93
94 if (!git_buf_oom(buf))
95 set_error_from_buffer(error_class);
96 }
97
98 int git_error_set_str(int error_class, const char *string)
99 {
100 git_buf *buf = &GIT_GLOBAL->error_buf;
101
102 assert(string);
103
104 if (!string) {
105 git_error_set(GIT_ERROR_INVALID, "unspecified caller error");
106 return -1;
107 }
108
109 git_buf_clear(buf);
110 git_buf_puts(buf, string);
111
112 if (git_buf_oom(buf))
113 return -1;
114
115 set_error_from_buffer(error_class);
116 return 0;
117 }
118
119 void git_error_clear(void)
120 {
121 if (GIT_GLOBAL->last_error != NULL) {
122 set_error(0, NULL);
123 GIT_GLOBAL->last_error = NULL;
124 }
125
126 errno = 0;
127 #ifdef GIT_WIN32
128 SetLastError(0);
129 #endif
130 }
131
132 const git_error *git_error_last(void)
133 {
134 return GIT_GLOBAL->last_error;
135 }
136
137 int git_error_state_capture(git_error_state *state, int error_code)
138 {
139 git_error *error = GIT_GLOBAL->last_error;
140 git_buf *error_buf = &GIT_GLOBAL->error_buf;
141
142 memset(state, 0, sizeof(git_error_state));
143
144 if (!error_code)
145 return 0;
146
147 state->error_code = error_code;
148 state->oom = (error == &g_git_oom_error);
149
150 if (error) {
151 state->error_msg.klass = error->klass;
152
153 if (state->oom)
154 state->error_msg.message = g_git_oom_error.message;
155 else
156 state->error_msg.message = git_buf_detach(error_buf);
157 }
158
159 git_error_clear();
160 return error_code;
161 }
162
163 int git_error_state_restore(git_error_state *state)
164 {
165 int ret = 0;
166
167 git_error_clear();
168
169 if (state && state->error_msg.message) {
170 if (state->oom)
171 git_error_set_oom();
172 else
173 set_error(state->error_msg.klass, state->error_msg.message);
174
175 ret = state->error_code;
176 memset(state, 0, sizeof(git_error_state));
177 }
178
179 return ret;
180 }
181
182 void git_error_state_free(git_error_state *state)
183 {
184 if (!state)
185 return;
186
187 if (!state->oom)
188 git__free(state->error_msg.message);
189
190 memset(state, 0, sizeof(git_error_state));
191 }
192
193 int git_error_system_last(void)
194 {
195 #ifdef GIT_WIN32
196 return GetLastError();
197 #else
198 return errno;
199 #endif
200 }
201
202 void git_error_system_set(int code)
203 {
204 #ifdef GIT_WIN32
205 SetLastError(code);
206 #else
207 errno = code;
208 #endif
209 }
210
211 /* Deprecated error values and functions */
212
213 const git_error *giterr_last(void)
214 {
215 return git_error_last();
216 }
217
218 void giterr_clear(void)
219 {
220 git_error_clear();
221 }
222
223 void giterr_set_str(int error_class, const char *string)
224 {
225 git_error_set_str(error_class, string);
226 }
227
228 void giterr_set_oom(void)
229 {
230 git_error_set_oom();
231 }