]> git.proxmox.com Git - libgit2.git/blame - src/errors.c
New upstream version 0.27.7+dfsg.1
[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",
20 GITERR_NOMEMORY
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
1a481123
VM
47void giterr_set_oom(void)
48{
49 GIT_GLOBAL->last_error = &g_git_oom_error;
50}
51
52void giterr_set(int error_class, const char *string, ...)
60bc2d20 53{
60bc2d20 54 va_list arglist;
3ae0aad7
RB
55#ifdef GIT_WIN32
56 DWORD win32_error_code = (error_class == GITERR_OS) ? GetLastError() : 0;
57#endif
58 int error_code = (error_class == GITERR_OS) ? errno : 0;
f85fc367 59 git_buf *buf = &GIT_GLOBAL->error_buf;
60bc2d20 60
f85fc367 61 git_buf_clear(buf);
e62f96de
ET
62 if (string) {
63 va_start(arglist, string);
f85fc367 64 git_buf_vprintf(buf, string, arglist);
e62f96de
ET
65 va_end(arglist);
66
67 if (error_class == GITERR_OS)
f85fc367 68 git_buf_PUTS(buf, ": ");
e62f96de 69 }
60bc2d20 70
dda708e7 71 if (error_class == GITERR_OS) {
e1de726c 72#ifdef GIT_WIN32
c70455c7
SS
73 char * win32_error = git_win32_get_error_message(win32_error_code);
74 if (win32_error) {
f85fc367 75 git_buf_puts(buf, win32_error);
c70455c7 76 git__free(win32_error);
8f624a47
PK
77
78 SetLastError(0);
e1de726c 79 }
8f624a47 80 else
e1de726c 81#endif
e62f96de 82 if (error_code)
f85fc367 83 git_buf_puts(buf, strerror(error_code));
8f624a47
PK
84
85 if (error_code)
86 errno = 0;
ae9e29fd
RB
87 }
88
f85fc367
CMN
89 if (!git_buf_oom(buf))
90 set_error_from_buffer(error_class);
dda708e7
VM
91}
92
93void giterr_set_str(int error_class, const char *string)
94{
f85fc367 95 git_buf *buf = &GIT_GLOBAL->error_buf;
1a628100
RB
96
97 assert(string);
98
f85fc367
CMN
99 if (!string)
100 return;
dda708e7 101
f85fc367
CMN
102 git_buf_clear(buf);
103 git_buf_puts(buf, string);
104 if (!git_buf_oom(buf))
105 set_error_from_buffer(error_class);
60bc2d20
VM
106}
107
cc146626 108int giterr_set_regex(const regex_t *regex, int error_code)
dda708e7
VM
109{
110 char error_buf[1024];
6c72035f
PK
111
112 assert(error_code);
113
dda708e7
VM
114 regerror(error_code, regex, error_buf, sizeof(error_buf));
115 giterr_set_str(GITERR_REGEX, error_buf);
cc146626 116
117 if (error_code == REG_NOMATCH)
118 return GIT_ENOTFOUND;
6c72035f
PK
119
120 return GIT_EINVALIDSPEC;
dda708e7
VM
121}
122
1a481123 123void giterr_clear(void)
60bc2d20 124{
96869a4e
RB
125 if (GIT_GLOBAL->last_error != NULL) {
126 set_error(0, NULL);
127 GIT_GLOBAL->last_error = NULL;
128 }
97a17e4e
RB
129
130 errno = 0;
131#ifdef GIT_WIN32
132 SetLastError(0);
133#endif
60bc2d20 134}
e3c47510 135
ef4857c2
ET
136const git_error *giterr_last(void)
137{
138 return GIT_GLOBAL->last_error;
139}
140
141int giterr_state_capture(git_error_state *state, int error_code)
d6c60169 142{
d6c60169 143 git_error *error = GIT_GLOBAL->last_error;
ef4857c2 144 git_buf *error_buf = &GIT_GLOBAL->error_buf;
d6c60169 145
ef4857c2 146 memset(state, 0, sizeof(git_error_state));
d6c60169 147
ef4857c2
ET
148 if (!error_code)
149 return 0;
150
151 state->error_code = error_code;
152 state->oom = (error == &g_git_oom_error);
d6c60169 153
ef4857c2
ET
154 if (error) {
155 state->error_msg.klass = error->klass;
d6c60169 156
ef4857c2
ET
157 if (state->oom)
158 state->error_msg.message = g_git_oom_error.message;
159 else
160 state->error_msg.message = git_buf_detach(error_buf);
0fcfb60d 161 }
d6c60169 162
ef4857c2
ET
163 giterr_clear();
164 return error_code;
d6c60169
RB
165}
166
ef4857c2 167int giterr_state_restore(git_error_state *state)
e3c47510 168{
ef4857c2 169 int ret = 0;
96869a4e 170
ef4857c2 171 giterr_clear();
96869a4e 172
ef4857c2
ET
173 if (state && state->error_msg.message) {
174 if (state->oom)
0fcfb60d 175 giterr_set_oom();
ef4857c2 176 else
0fcfb60d 177 set_error(state->error_msg.klass, state->error_msg.message);
ef4857c2
ET
178
179 ret = state->error_code;
180 memset(state, 0, sizeof(git_error_state));
0fcfb60d 181 }
96869a4e 182
ef4857c2
ET
183 return ret;
184}
185
186void giterr_state_free(git_error_state *state)
187{
188 if (!state)
189 return;
190
191 if (!state->oom)
192 git__free(state->error_msg.message);
193
194 memset(state, 0, sizeof(git_error_state));
96869a4e
RB
195}
196
197int giterr_system_last(void)
198{
199#ifdef GIT_WIN32
200 return GetLastError();
201#else
202 return errno;
203#endif
204}
205
206void giterr_system_set(int code)
207{
208#ifdef GIT_WIN32
209 SetLastError(code);
210#else
211 errno = code;
212#endif
213}