Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2020, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #include <string.h>
32 : : #include <stdbool.h>
33 : : #include <stdint.h>
34 : : #include <stdarg.h>
35 : : #include <stddef.h>
36 : : #include <setjmp.h>
37 : : #include <cmocka.h>
38 : : #include <errno.h>
39 : : #include <sys/socket.h>
40 : :
41 : : #include "control-wrappers.h"
42 : :
43 : : static int enable_mocks = 0;
44 : :
45 : :
46 : : FILE *
47 : : __real_fdopen(int fd, const char *mode);
48 : :
49 : : FILE *
50 : 2 : __wrap_fdopen(int fd, const char *mode)
51 : : {
52 [ - + ]: 2 : if (enable_mocks) {
53 : 0 : FILE *file = (FILE*)mock();
54 [ # # ]: 0 : if (file == NULL) {
55 : 0 : errno = ENOENT;
56 : : }
57 : :
58 : 0 : return file;
59 : : }
60 : :
61 : 2 : return __real_fdopen(fd, mode);
62 : : }
63 : :
64 : : int
65 : 7 : __wrap_ioctl(int fd, int request, ...)
66 : : {
67 : : int result;
68 : :
69 : 7 : check_expected(fd);
70 : 7 : check_expected(request);
71 : :
72 : 7 : result = (int)mock();
73 : :
74 [ + + ]: 7 : if (result != 0) {
75 : 1 : errno = result;
76 : 1 : result = -1;
77 : : }
78 : :
79 : 7 : return result;
80 : : }
81 : :
82 : : int
83 : : __real_open(const char *pathname, int flags);
84 : :
85 : : int
86 : 11 : __wrap_open(const char *pathname, int flags)
87 : : {
88 : : int result;
89 : :
90 [ + + ]: 11 : if (enable_mocks) {
91 : 8 : check_expected(pathname);
92 : 8 : result = mock();
93 [ + + ]: 8 : if (result == -1)
94 : 1 : errno = ENOENT;
95 : 8 : return result;
96 : : }
97 : :
98 : 3 : return __real_open(pathname, flags);
99 : : }
100 : :
101 : : int
102 : : __real_close(int fd);
103 : :
104 : : int
105 : 21 : __wrap_close(int fd)
106 : : {
107 : : int result;
108 : :
109 : 21 : check_expected(fd);
110 : 21 : result = mock();
111 [ - + ]: 21 : if (result != 0)
112 : : {
113 : 0 : errno = result;
114 : 0 : result = 1;
115 : : }
116 : 21 : return result;
117 : : }
118 : :
119 : : int
120 : : __real_access(const char *pathname, int mode);
121 : :
122 : : int
123 : 25 : __wrap_access(const char *pathname, int mode)
124 : : {
125 : : int result;
126 : :
127 [ + + ]: 25 : if (enable_mocks) {
128 : 20 : check_expected(pathname);
129 : :
130 : 20 : result = mock();
131 [ + + ]: 20 : if (result != 0) {
132 : 12 : errno = result;
133 : 12 : result = -1;
134 : : }
135 : 20 : return result;
136 : : }
137 : 5 : return __real_access(pathname, mode);
138 : : }
139 : :
140 : : size_t
141 : 13 : __wrap_read(int fd, void *buf, size_t count)
142 : : {
143 : 13 : int result = -1;
144 : : struct mock_read_params *params;
145 : :
146 : 13 : check_expected(fd);
147 : 13 : params = (struct mock_read_params *)mock();
148 : :
149 [ + + ]: 13 : if (params->result > 0) {
150 : 12 : memcpy(buf, params->data, params->result);
151 : 12 : result = params->result;
152 : : }
153 [ + - ]: 1 : else if (params->result < 0) {
154 : 1 : errno = -params->result;
155 : 1 : result = -1;
156 : : }
157 : :
158 : 13 : return result;
159 : : }
160 : :
161 : : /*
162 : : * Wrap the write call.
163 : : *
164 : : * Checks the passed FD is expected
165 : : * Mock result is amount of written data to report
166 : : * limited to count, negative values are errnos to
167 : : * set and return -1.
168 : : */
169 : : size_t
170 : 12 : __wrap_write(int fd, const void *buf, size_t count)
171 : : {
172 : : int result;
173 : :
174 : 12 : check_expected(fd);
175 : 12 : check_expected(buf);
176 : 12 : result = mock();
177 : :
178 [ + + ]: 12 : if (result > (int)count)
179 : : result = count;
180 [ + - ]: 1 : else if (result < 0) {
181 : 1 : errno = -result;
182 : 1 : result = -1;
183 : : }
184 : 12 : return result;
185 : : }
186 : :
187 : : int
188 : 14 : __wrap_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
189 : : {
190 : : int result;
191 : 14 : check_expected(sockfd);
192 : 14 : check_expected(addr);
193 : 14 : result = mock();
194 [ + + ]: 14 : if (result) {
195 : 1 : errno = result;
196 : 1 : result = -1;
197 : : }
198 : 14 : return result;
199 : : }
200 : :
201 : : int
202 : 27 : __wrap_select(int nfds, fd_set *readfds, fd_set *writefds,
203 : : fd_set *exceptfds, struct timeval *timeout)
204 : : {
205 : : struct mock_select_params *params;
206 : 27 : check_expected(timeout);
207 : 27 : params = (struct mock_select_params *)mock();
208 [ + + ]: 27 : if (readfds)
209 : 14 : memcpy(readfds, ¶ms->readfds, sizeof(fd_set));
210 [ + + ]: 27 : if (writefds)
211 : 13 : memcpy(writefds, ¶ms->writefds, sizeof(fd_set));
212 [ - + ]: 27 : if (exceptfds)
213 : 0 : memcpy(exceptfds, ¶ms->exceptfds, sizeof(fd_set));
214 : 27 : return params->result;
215 : : }
216 : :
217 : : int
218 : : __real_mkdir(const char *pathname, mode_t mode);
219 : :
220 : : int
221 : 22 : __wrap_mkdir(const char *pathname, mode_t mode)
222 : : {
223 : : int result;
224 [ + + ]: 22 : if (enable_mocks) {
225 : 21 : check_expected(pathname);
226 : 21 : result = mock();
227 [ + + ]: 21 : if (result != 0){
228 : 20 : errno = result;
229 : 20 : result = -1;
230 : : }
231 : 21 : return result;
232 : : }
233 : 1 : return __real_mkdir(pathname, mode);
234 : : }
235 : :
236 : : int
237 : 10 : __wrap_flock(int fd, int operation)
238 : : {
239 : : int result;
240 : 10 : check_expected(fd);
241 : 10 : result = mock();
242 [ - + ]: 10 : if (result != 0) {
243 : 0 : errno = result;
244 : 0 : result = -1;
245 : : }
246 : 10 : return result;
247 : : }
248 : :
249 : : int
250 : 9 : __wrap___xmknod(int ver, const char *pathname, mode_t mode, dev_t * dev)
251 : : {
252 : : int result;
253 : 9 : check_expected(pathname);
254 : 9 : result = mock();
255 [ + + ]: 9 : if (result != 0)
256 : : {
257 : 3 : errno = result;
258 : 3 : result = -1;
259 : : }
260 : 9 : return result;
261 : : }
262 : :
263 : : int
264 : 9 : __wrap_unlink(const char *pathname)
265 : : {
266 : : int result;
267 : 9 : check_expected(pathname);
268 : 9 : result = mock();
269 [ - + ]: 9 : if (result != 0)
270 : : {
271 : 0 : errno = result;
272 : 0 : result = -1;
273 : : }
274 : 9 : return result;
275 : : }
276 : :
277 : : int
278 : 14 : __wrap_socket(int domain, int type, int protocol)
279 : : {
280 : : int result;
281 : :
282 : 14 : check_expected(domain);
283 : 14 : check_expected(type);
284 : 14 : check_expected(protocol);
285 : :
286 : 14 : result = mock();
287 : :
288 [ - + ]: 14 : if (result < 0) {
289 : 0 : errno = -result;
290 : 0 : result = -1;
291 : : }
292 : 14 : return result;
293 : : }
294 : :
295 : : int
296 : 10 : __wrap_glob(const char *pattern, int flags,
297 : : int (*errfunc) (const char *epath, int eerrno),
298 : : glob_t *pglob)
299 : : {
300 : 10 : check_expected(pattern);
301 : 10 : int result = mock();
302 [ + + ]: 10 : if (result == 0)
303 : : {
304 : 6 : pglob->gl_pathc = mock();
305 : 6 : pglob->gl_pathv = (char **)mock();
306 : : }
307 : 10 : return result;
308 : : }
309 : :
310 : : void
311 : 6 : __wrap_globfree(glob_t *pglob)
312 : : {
313 [ + - ]: 6 : if (pglob->gl_pathv) {
314 : 6 : test_free(*(pglob->gl_pathv));
315 : : }
316 : 6 : }
317 : :
318 : :
319 : 4 : void enable_control_mocks()
320 : : {
321 : 4 : enable_mocks = true;
322 : 4 : }
323 : :
324 : 4 : void disable_control_mocks()
325 : : {
326 : 4 : enable_mocks = 0;
327 : 4 : }
|