Coverage Report

Created: 2026-09-01 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl/lib/api.h
Line
Count
Source
1
#ifndef HEADER_CURL_API_H
2
#define HEADER_CURL_API_H
3
/***************************************************************************
4
 *                                  _   _ ____  _
5
 *  Project                     ___| | | |  _ \| |
6
 *                             / __| | | | |_) | |
7
 *                            | (__| |_| |  _ <| |___
8
 *                             \___|\___/|_| \_\_____|
9
 *
10
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
11
 *
12
 * This software is licensed as described in the file COPYING, which
13
 * you should have received as part of this distribution. The terms
14
 * are also available at https://curl.se/docs/copyright.html.
15
 *
16
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
17
 * copies of the Software, and permit persons to whom the Software is
18
 * furnished to do so, under the terms of the COPYING file.
19
 *
20
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21
 * KIND, either express or implied.
22
 *
23
 * SPDX-License-Identifier: curl
24
 *
25
 ***************************************************************************/
26
#include "curl_setup.h"
27
28
426k
#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU
29
#ifdef DEBUGBUILD
30
/* On a debug build, we want to fail hard on easy handles that
31
 * are not NULL, but no longer have the MAGIC touch. This gives
32
 * us early warning on things only discovered by valgrind otherwise. */
33
#define GOOD_EASY_HANDLE(x) \
34
405k
  (((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER)) ? TRUE : \
35
405k
   (DEBUGASSERT(!(x)), FALSE))
36
#else
37
#define GOOD_EASY_HANDLE(x) \
38
  ((x) && ((x)->magic == CURLEASY_MAGIC_NUMBER))
39
#endif
40
41
2.48M
#define CURLMULTI_MAGIC_NUMBER 0x000bab1e
42
43
#ifdef DEBUGBUILD
44
/* On a debug build, we want to fail hard on multi handles that
45
 * are not NULL, but no longer have the MAGIC touch. This gives
46
 * us early warning on things only discovered by valgrind otherwise. */
47
#define GOOD_MULTI_HANDLE(x)                         \
48
2.47M
  (((x) && (x)->magic == CURLMULTI_MAGIC_NUMBER) ? TRUE : \
49
2.47M
  (DEBUGASSERT(!(x)), FALSE))
50
#else
51
#define GOOD_MULTI_HANDLE(x) \
52
  ((x) && (x)->magic == CURLMULTI_MAGIC_NUMBER)
53
#endif
54
55
/* the API functions called on a CURL* */
56
typedef enum {
57
  CURL_EAPI_FN_easy_cleanup,
58
  CURL_EAPI_FN_easy_duphandle,
59
  CURL_EAPI_FN_easy_getinfo,
60
  CURL_EAPI_FN_easy_header,
61
  CURL_EAPI_FN_easy_nextheader,
62
  CURL_EAPI_FN_easy_pause,
63
  CURL_EAPI_FN_easy_perform_ev,
64
  CURL_EAPI_FN_easy_perform,
65
  CURL_EAPI_FN_easy_recv,
66
  CURL_EAPI_FN_easy_reset,
67
  CURL_EAPI_FN_easy_send,
68
  CURL_EAPI_FN_easy_setopt,
69
  CURL_EAPI_FN_easy_ssls_export,
70
  CURL_EAPI_FN_easy_ssls_import,
71
  CURL_EAPI_FN_easy_upkeep,
72
  CURL_EAPI_FN_ws_recv,
73
  CURL_EAPI_FN_ws_send,
74
  CURL_EAPI_FN_ws_start_frame,
75
  CURL_EAPI_FN_LAST
76
} Curl_eapi_fn;
77
78
/* the API functions called on a CURLM* */
79
typedef enum {
80
  CURL_MAPI_FN_multi_add_handle,
81
  CURL_MAPI_FN_multi_assign,
82
  CURL_MAPI_FN_multi_cleanup,
83
  CURL_MAPI_FN_multi_fdset,
84
  CURL_MAPI_FN_multi_get_handles,
85
  CURL_MAPI_FN_multi_get_offt,
86
  CURL_MAPI_FN_multi_info_read,
87
  CURL_MAPI_FN_multi_notify_disable,
88
  CURL_MAPI_FN_multi_notify_enable,
89
  CURL_MAPI_FN_multi_perform,
90
  CURL_MAPI_FN_multi_poll,
91
  CURL_MAPI_FN_multi_remove_handle,
92
  CURL_MAPI_FN_multi_setopt,
93
  CURL_MAPI_FN_multi_socket_action,
94
  CURL_MAPI_FN_multi_socket_all,
95
  CURL_MAPI_FN_multi_socket,
96
  CURL_MAPI_FN_multi_timeout,
97
  CURL_MAPI_FN_multi_wait,
98
  CURL_MAPI_FN_multi_waitfds,
99
  CURL_MAPI_FN_LAST
100
} Curl_mapi_fn;
101
102
2.40M
#define CURL_CBAPI_FN_START        (16 * 1024)
103
104
/* the callback functions */
105
typedef enum {
106
  CURL_CBAPI_FN_easy_chunk_bgn = CURL_CBAPI_FN_START,
107
  CURL_CBAPI_FN_easy_chunk_end,
108
  CURL_CBAPI_FN_easy_closesocket,
109
  CURL_CBAPI_FN_easy_cr_in_read,
110
  CURL_CBAPI_FN_easy_cr_in_resume_from,
111
  CURL_CBAPI_FN_easy_cw_out_cb,
112
  CURL_CBAPI_FN_easy_fdebug,
113
  CURL_CBAPI_FN_easy_fnmatch_data,
114
  CURL_CBAPI_FN_easy_fopensocket,
115
  CURL_CBAPI_FN_easy_fprereq,
116
  CURL_CBAPI_FN_easy_fprogress,
117
  CURL_CBAPI_FN_easy_fread_func,
118
  CURL_CBAPI_FN_easy_fsockopt,
119
  CURL_CBAPI_FN_easy_fsslctx,
120
  CURL_CBAPI_FN_easy_fwrite_rtp,
121
  CURL_CBAPI_FN_easy_fxferinfo,
122
  CURL_CBAPI_FN_easy_ioctl_func,
123
  CURL_CBAPI_FN_easy_resolver_start,
124
  CURL_CBAPI_FN_easy_seek_func,
125
  CURL_CBAPI_FN_easy_ssh_hostkeyfunc,
126
  CURL_CBAPI_FN_easy_ssh_keyfunc,
127
  CURL_CBAPI_FN_easy_trailer_callback,
128
129
  CURL_CBAPI_FN_multi_ntfy_cb,
130
  CURL_CBAPI_FN_multi_push_cb,
131
  CURL_CBAPI_FN_multi_socket_cb,
132
  CURL_CBAPI_FN_multi_timer_cb,
133
134
  CURL_CBAPI_FN_LAST
135
} Curl_cbapi_fn;
136
137
/* EAPI */
138
139
185k
#define CURL_EAPI_MAX_RECURSION       7
140
141
struct Curl_eapi_stack {
142
  uint16_t count;
143
  uint16_t calls[CURL_EAPI_MAX_RECURSION];
144
};
145
146
struct Curl_eapi_guard {
147
  struct Curl_easy *data;  /* != NULL if handle stays */
148
  uint16_t depth;  /* > 0 if this guard was entered */
149
};
150
151
bool Curl_eapi_enter(struct Curl_eapi_guard *guard,
152
                     CURL *curl,
153
                     Curl_eapi_fn fn,
154
                     CURLcode *presult);
155
void Curl_eapi_leave(struct Curl_eapi_guard *guard);
156
157
/* Convert an EAPI failure to a header API result */
158
CURLHcode Curl_eapi_hcode(CURLcode result);
159
160
/* Curl_eapi_enter() checks for curl being NULL, but windows compiler
161
 * analyzers do not realize this. *sigh* */
162
#define CURL_EAPI_ENTER(g, curl, fn, r) \
163
185k
  Curl_eapi_enter((g), (curl), CURL_EAPI_FN_##fn, (r)) && (curl)
164
#define CURL_EAPI_LEAVE(g) \
165
185k
  Curl_eapi_leave(g)
166
167
/* MAPI */
168
169
2.44M
#define CURL_MAPI_MAX_RECURSION       15
170
171
struct Curl_mapi_stack {
172
  uint16_t count;
173
  uint16_t calls[CURL_MAPI_MAX_RECURSION];
174
};
175
176
struct Curl_mapi_guard {
177
  struct Curl_multi *multi;  /* != NULL if handle stays */
178
  uint16_t depth;  /* > 0 if this guard was entered */
179
};
180
181
bool Curl_mapi_enter(struct Curl_mapi_guard *guard,
182
                     CURLM *m,
183
                     Curl_mapi_fn fn,
184
                     CURLMcode *pmresult);
185
void Curl_mapi_leave(struct Curl_mapi_guard *guard);
186
187
/* Curl_mapi_enter() checks for m being NULL, but windows compiler
188
 * analyzers do not realize this. *sigh* */
189
#define CURL_MAPI_ENTER(g, m, fn, r) \
190
37.1k
  Curl_mapi_enter((g), (m), CURL_MAPI_FN_##fn, (r)) && (m)
191
#define CURL_MAPI_LEAVE(g) \
192
37.1k
  Curl_mapi_leave(g)
193
194
void Curl_cbapi_enter(struct Curl_mapi_guard *guard,
195
                      struct Curl_easy *data,
196
                      struct Curl_multi *multi,
197
                      Curl_cbapi_fn fn);
198
void Curl_cbapi_leave(struct Curl_mapi_guard *guard);
199
200
#define CURL_CBAPI_START(g, d, fn) \
201
2.40M
  Curl_cbapi_enter((g), (d), NULL, CURL_CBAPI_FN_##fn)
202
#define CURL_CBAPI_MULTI_START(g, m, fn) \
203
0
  Curl_cbapi_enter((g), NULL, (m), CURL_CBAPI_FN_##fn)
204
#define CURL_CBAPI_END(g) \
205
2.40M
  Curl_cbapi_leave(g)
206
#define CURL_CBAPI_MULTI_END(g) \
207
0
  Curl_cbapi_leave(g)
208
209
bool Curl_api_is_in_callback(struct Curl_easy *data);
210
bool Curl_api_multi_is_in_callback(struct Curl_multi *multi);
211
212
#endif /* HEADER_CURL_API_H */