2 * virfilewrapper.c: Wrapper for universal file access
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
25 # include "viralloc.h"
27 # include "virfilewrapper.h"
29 # include "virstring.h"
32 /* Mapping for prefix overrides */
33 static size_t noverrides
;
34 static const char **overrides
;
36 /* nprefixes == noverrides, but two variables make it easier to use
37 * VIR_*_ELEMENT macros */
38 static size_t nprefixes
;
39 static const char **prefixes
;
42 static int (*real_open
)(const char *path
, int flags
, ...);
43 static FILE *(*real_fopen
)(const char *path
, const char *mode
);
44 static int (*real_access
)(const char *path
, int mode
);
45 static int (*real_mkdir
)(const char *path
, mode_t mode
);
46 static DIR *(*real_opendir
)(const char *path
);
48 static void init_syms(void)
53 VIR_MOCK_REAL_INIT(fopen
);
54 VIR_MOCK_REAL_INIT(access
);
55 VIR_MOCK_REAL_INIT(mkdir
);
56 VIR_MOCK_REAL_INIT(open
);
57 VIR_MOCK_REAL_INIT(opendir
);
62 virFileWrapperAddPrefix(const char *prefix
,
65 /* Both parameters are mandatory */
66 if (!prefix
|| !override
) {
67 fprintf(stderr
, "Attempt to add invalid path override\n");
73 if (VIR_APPEND_ELEMENT_QUIET(prefixes
, nprefixes
, prefix
) < 0 ||
74 VIR_APPEND_ELEMENT_QUIET(overrides
, noverrides
, override
) < 0) {
77 fprintf(stderr
, "Unable to add path override for '%s'\n", prefix
);
84 virFileWrapperRemovePrefix(const char *prefix
)
88 for (i
= 0; i
< noverrides
; i
++) {
89 if (STREQ(prefixes
[i
], prefix
))
96 VIR_DELETE_ELEMENT(overrides
, i
, noverrides
);
97 VIR_DELETE_ELEMENT(prefixes
, i
, nprefixes
);
101 virFileWrapperClearPrefixes(void)
110 # include "virmockstathelpers.c"
113 virMockStatRedirect(const char *path
, char **newpath
)
117 for (i
= 0; i
< noverrides
; i
++) {
118 const char *tmp
= STRSKIP(path
, prefixes
[i
]);
123 if (virAsprintfQuiet(newpath
, "%s%s", overrides
[i
], tmp
) < 0)
133 # define PATH_OVERRIDE(newpath, path) \
137 if (virMockStatRedirect(path, &newpath) < 0) \
142 FILE *fopen(const char *path
, const char *mode
)
144 VIR_AUTOFREE(char *) newpath
= NULL
;
146 PATH_OVERRIDE(newpath
, path
);
148 return real_fopen(newpath
? newpath
: path
, mode
);
151 int access(const char *path
, int mode
)
153 VIR_AUTOFREE(char *) newpath
= NULL
;
155 PATH_OVERRIDE(newpath
, path
);
157 return real_access(newpath
? newpath
: path
, mode
);
160 int open(const char *path
, int flags
, ...)
162 VIR_AUTOFREE(char *) newpath
= NULL
;
166 PATH_OVERRIDE(newpath
, path
);
168 /* The mode argument is mandatory when O_CREAT is set in flags,
169 * otherwise the argument is ignored.
171 if (flags
& O_CREAT
) {
173 mode
= (mode_t
) va_arg(ap
, int);
177 return real_open(newpath
? newpath
: path
, flags
, mode
);
180 DIR *opendir(const char *path
)
182 VIR_AUTOFREE(char *) newpath
= NULL
;
184 PATH_OVERRIDE(newpath
, path
);
186 return real_opendir(newpath
? newpath
: path
);