]> git.proxmox.com Git - libgit2.git/blame - src/errors.c
Drop patch as it is merged upstream
[libgit2.git] / src / errors.c
CommitLineData
02f9e637 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
02f9e637 3 *
bb742ede
VM
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.
02f9e637 6 */
eae0bfdc 7
ae234862 8#include "common.h"
eae0bfdc 9
a15c550d 10#include "global.h"
60bc2d20 11#include "posix.h"
22772166 12#include "buffer.h"
02f9e637 13
60bc2d20
VM
14/********************************************
15 * New error handling
16 ********************************************/
17
1a481123
VM
18static git_error g_git_oom_error = {
19 "Out of memory",
ac3d33df 20 GIT_ERROR_NOMEMORY
1a481123
VM
21};
22
f85fc367 23static void set_error_from_buffer(int error_class)
22772166
VM
24{
25 git_error *error = &GIT_GLOBAL->error_t;
f85fc367 26 git_buf *buf = &GIT_GLOBAL->error_buf;
22772166 27
f85fc367 28 error->message = buf->ptr;
22772166
VM
29 error->klass = error_class;
30
31 GIT_GLOBAL->last_error = error;
32}
33
f85fc367
CMN
34static 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
ac3d33df 47void git_error_set_oom(void)
1a481123
VM
48{
49 GIT_GLOBAL->last_error = &g_git_oom_error;
50}
51
0c9c969a
UG
52void 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
61void git_error_vset(int error_class, const char *fmt, va_list ap)
60bc2d20 62{
3ae0aad7 63#ifdef GIT_WIN32
ac3d33df 64 DWORD win32_error_code = (error_class == GIT_ERROR_OS) ? GetLastError() : 0;
3ae0aad7 65#endif
ac3d33df 66 int error_code = (error_class == GIT_ERROR_OS) ? errno : 0;
f85fc367 67 git_buf *buf = &GIT_GLOBAL->error_buf;
60bc2d20 68
f85fc367 69 git_buf_clear(buf);
0c9c969a
UG
70 if (fmt) {
71 git_buf_vprintf(buf, fmt, ap);
ac3d33df 72 if (error_class == GIT_ERROR_OS)
f85fc367 73 git_buf_PUTS(buf, ": ");
e62f96de 74 }
60bc2d20 75
ac3d33df 76 if (error_class == GIT_ERROR_OS) {
e1de726c 77#ifdef GIT_WIN32
c70455c7
SS
78 char * win32_error = git_win32_get_error_message(win32_error_code);
79 if (win32_error) {
f85fc367 80 git_buf_puts(buf, win32_error);
c70455c7 81 git__free(win32_error);
8f624a47
PK
82
83 SetLastError(0);
e1de726c 84 }
8f624a47 85 else
e1de726c 86#endif
e62f96de 87 if (error_code)
f85fc367 88 git_buf_puts(buf, strerror(error_code));
8f624a47
PK
89
90 if (error_code)
91 errno = 0;
ae9e29fd
RB
92 }
93
f85fc367
CMN
94 if (!git_buf_oom(buf))
95 set_error_from_buffer(error_class);
dda708e7
VM
96}
97
0c9c969a 98int git_error_set_str(int error_class, const char *string)
dda708e7 99{
f85fc367 100 git_buf *buf = &GIT_GLOBAL->error_buf;
1a628100
RB
101
102 assert(string);
103
0c9c969a
UG
104 if (!string) {
105 git_error_set(GIT_ERROR_INVALID, "unspecified caller error");
106 return -1;
107 }
dda708e7 108
f85fc367
CMN
109 git_buf_clear(buf);
110 git_buf_puts(buf, string);
6c72035f 111
0c9c969a
UG
112 if (git_buf_oom(buf))
113 return -1;
6c72035f 114
0c9c969a
UG
115 set_error_from_buffer(error_class);
116 return 0;
dda708e7
VM
117}
118
ac3d33df 119void git_error_clear(void)
60bc2d20 120{
96869a4e
RB
121 if (GIT_GLOBAL->last_error != NULL) {
122 set_error(0, NULL);
123 GIT_GLOBAL->last_error = NULL;
124 }
97a17e4e
RB
125
126 errno = 0;
127#ifdef GIT_WIN32
128 SetLastError(0);
129#endif
60bc2d20 130}
e3c47510 131
ac3d33df 132const git_error *git_error_last(void)
ef4857c2
ET
133{
134 return GIT_GLOBAL->last_error;
135}
136
ac3d33df 137int git_error_state_capture(git_error_state *state, int error_code)
d6c60169 138{
d6c60169 139 git_error *error = GIT_GLOBAL->last_error;
ef4857c2 140 git_buf *error_buf = &GIT_GLOBAL->error_buf;
d6c60169 141
ef4857c2 142 memset(state, 0, sizeof(git_error_state));
d6c60169 143
ef4857c2
ET
144 if (!error_code)
145 return 0;
146
147 state->error_code = error_code;
148 state->oom = (error == &g_git_oom_error);
d6c60169 149
ef4857c2
ET
150 if (error) {
151 state->error_msg.klass = error->klass;
d6c60169 152
ef4857c2
ET
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);
0fcfb60d 157 }
d6c60169 158
ac3d33df 159 git_error_clear();
ef4857c2 160 return error_code;
d6c60169
RB
161}
162
ac3d33df 163int git_error_state_restore(git_error_state *state)
e3c47510 164{
ef4857c2 165 int ret = 0;
96869a4e 166
ac3d33df 167 git_error_clear();
96869a4e 168
ef4857c2
ET
169 if (state && state->error_msg.message) {
170 if (state->oom)
ac3d33df 171 git_error_set_oom();
ef4857c2 172 else
0fcfb60d 173 set_error(state->error_msg.klass, state->error_msg.message);
ef4857c2
ET
174
175 ret = state->error_code;
176 memset(state, 0, sizeof(git_error_state));
0fcfb60d 177 }
96869a4e 178
ef4857c2
ET
179 return ret;
180}
181
ac3d33df 182void git_error_state_free(git_error_state *state)
ef4857c2
ET
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));
96869a4e
RB
191}
192
ac3d33df 193int git_error_system_last(void)
96869a4e
RB
194{
195#ifdef GIT_WIN32
196 return GetLastError();
197#else
198 return errno;
199#endif
200}
201
ac3d33df 202void git_error_system_set(int code)
96869a4e
RB
203{
204#ifdef GIT_WIN32
205 SetLastError(code);
206#else
207 errno = code;
208#endif
209}
ac3d33df
JK
210
211/* Deprecated error values and functions */
212
213const git_error *giterr_last(void)
214{
215 return git_error_last();
216}
217
218void giterr_clear(void)
219{
220 git_error_clear();
221}
222
223void giterr_set_str(int error_class, const char *string)
224{
225 git_error_set_str(error_class, string);
226}
227
228void giterr_set_oom(void)
229{
230 git_error_set_oom();
231}