/src/util-linux/include/vfs.h
Line | Count | Source |
1 | | /* |
2 | | * No copyright is claimed. This code is in the public domain; do with |
3 | | * it what you wish. |
4 | | */ |
5 | | #ifndef UTIL_LINUX_VFS_H |
6 | | #define UTIL_LINUX_VFS_H |
7 | | |
8 | | #include <stdio.h> |
9 | | #include <stdlib.h> |
10 | | #include <unistd.h> |
11 | | #include <fcntl.h> |
12 | | #include <sys/types.h> |
13 | | #include <string.h> |
14 | | |
15 | | #ifndef UL_VFS_OPS_DEFINED |
16 | | #define UL_VFS_OPS_DEFINED |
17 | | |
18 | | struct ul_vfs_ops { |
19 | | size_t size; |
20 | | |
21 | | ssize_t (*vfs_read)(int fd, void *buf, size_t count); |
22 | | ssize_t (*vfs_write)(int fd, const void *buf, size_t count); |
23 | | int (*vfs_open)(const char *pathname, int flags, mode_t mode); |
24 | | int (*vfs_close)(int fd); |
25 | | off_t (*vfs_lseek)(int fd, off_t offset, int whence); |
26 | | int (*vfs_fsync)(int fd); |
27 | | |
28 | | FILE *(*vfs_fopen)(const char *pathname, const char *mode); |
29 | | }; |
30 | | |
31 | | #endif /* UL_VFS_OPS_DEFINED */ |
32 | | |
33 | | static inline void ul_vfs_init(struct ul_vfs_ops *dst, |
34 | | const struct ul_vfs_ops *src) |
35 | 0 | { |
36 | 0 | memset(dst, 0, sizeof(*dst)); |
37 | 0 | if (src && src->size > 0) { |
38 | 0 | size_t sz = src->size < sizeof(*dst) ? src->size : sizeof(*dst); |
39 | 0 | memcpy(dst, src, sz); |
40 | 0 | } |
41 | 0 | dst->size = sizeof(*dst); |
42 | 0 | } Unexecuted instantiation: last.c:ul_vfs_init Unexecuted instantiation: fileutils.c:ul_vfs_init Unexecuted instantiation: canonicalize.c:ul_vfs_init |
43 | | |
44 | | static inline struct ul_vfs_ops *ul_vfs_copy(const struct ul_vfs_ops *src) |
45 | 0 | { |
46 | 0 | struct ul_vfs_ops *dst; |
47 | 0 |
|
48 | 0 | if (!src) |
49 | 0 | return NULL; |
50 | 0 | dst = malloc(sizeof(*dst)); |
51 | 0 | if (!dst) |
52 | 0 | return NULL; |
53 | 0 | memcpy(dst, src, sizeof(*dst)); |
54 | 0 | return dst; |
55 | 0 | } Unexecuted instantiation: last.c:ul_vfs_copy Unexecuted instantiation: fileutils.c:ul_vfs_copy Unexecuted instantiation: canonicalize.c:ul_vfs_copy |
56 | | |
57 | | static inline ssize_t ul_vfs_read(const struct ul_vfs_ops *vfs, |
58 | | int fd, void *buf, size_t count) |
59 | 0 | { |
60 | 0 | if (vfs && vfs->vfs_read) |
61 | 0 | return vfs->vfs_read(fd, buf, count); |
62 | 0 | return read(fd, buf, count); |
63 | 0 | } Unexecuted instantiation: last.c:ul_vfs_read Unexecuted instantiation: fileutils.c:ul_vfs_read Unexecuted instantiation: canonicalize.c:ul_vfs_read |
64 | | |
65 | | static inline ssize_t ul_vfs_write(const struct ul_vfs_ops *vfs, |
66 | | int fd, const void *buf, size_t count) |
67 | 0 | { |
68 | 0 | if (vfs && vfs->vfs_write) |
69 | 0 | return vfs->vfs_write(fd, buf, count); |
70 | 0 | return write(fd, buf, count); |
71 | 0 | } Unexecuted instantiation: last.c:ul_vfs_write Unexecuted instantiation: fileutils.c:ul_vfs_write Unexecuted instantiation: canonicalize.c:ul_vfs_write |
72 | | |
73 | | static inline int ul_vfs_open(const struct ul_vfs_ops *vfs, |
74 | | const char *pathname, int flags, mode_t mode) |
75 | 0 | { |
76 | 0 | if (vfs && vfs->vfs_open) |
77 | 0 | return vfs->vfs_open(pathname, flags, mode); |
78 | 0 | return open(pathname, flags, mode); |
79 | 0 | } Unexecuted instantiation: last.c:ul_vfs_open Unexecuted instantiation: fileutils.c:ul_vfs_open Unexecuted instantiation: canonicalize.c:ul_vfs_open |
80 | | |
81 | | static inline int ul_vfs_close(const struct ul_vfs_ops *vfs, int fd) |
82 | 0 | { |
83 | 0 | if (vfs && vfs->vfs_close) |
84 | 0 | return vfs->vfs_close(fd); |
85 | 0 | return close(fd); |
86 | 0 | } Unexecuted instantiation: last.c:ul_vfs_close Unexecuted instantiation: fileutils.c:ul_vfs_close Unexecuted instantiation: canonicalize.c:ul_vfs_close |
87 | | |
88 | | static inline off_t ul_vfs_lseek(const struct ul_vfs_ops *vfs, |
89 | | int fd, off_t offset, int whence) |
90 | 0 | { |
91 | 0 | if (vfs && vfs->vfs_lseek) |
92 | 0 | return vfs->vfs_lseek(fd, offset, whence); |
93 | 0 | return lseek(fd, offset, whence); |
94 | 0 | } Unexecuted instantiation: last.c:ul_vfs_lseek Unexecuted instantiation: fileutils.c:ul_vfs_lseek Unexecuted instantiation: canonicalize.c:ul_vfs_lseek |
95 | | |
96 | | static inline int ul_vfs_fsync(const struct ul_vfs_ops *vfs, int fd) |
97 | 0 | { |
98 | 0 | if (vfs && vfs->vfs_fsync) |
99 | 0 | return vfs->vfs_fsync(fd); |
100 | 0 | return fsync(fd); |
101 | 0 | } Unexecuted instantiation: last.c:ul_vfs_fsync Unexecuted instantiation: fileutils.c:ul_vfs_fsync Unexecuted instantiation: canonicalize.c:ul_vfs_fsync |
102 | | |
103 | | static inline int ul_mode_to_flags(const char *mode) |
104 | 0 | { |
105 | 0 | int flags = 0; |
106 | 0 | const char *p; |
107 | 0 |
|
108 | 0 | for (p = mode; p && *p; p++) { |
109 | 0 | if (*p == 'r' && *(p + 1) == '+') |
110 | 0 | flags |= O_RDWR; |
111 | 0 | else if (*p == 'r') |
112 | 0 | flags |= O_RDONLY; |
113 | 0 |
|
114 | 0 | else if (*p == 'w' && *(p + 1) == '+') |
115 | 0 | flags |= O_RDWR | O_TRUNC; |
116 | 0 | else if (*p == 'w') |
117 | 0 | flags |= O_WRONLY | O_TRUNC; |
118 | 0 |
|
119 | 0 | else if (*p == 'a' && *(p + 1) == '+') |
120 | 0 | flags |= O_RDWR | O_APPEND; |
121 | 0 | else if (*p == 'a') |
122 | 0 | flags |= O_WRONLY | O_APPEND; |
123 | 0 | #ifdef O_CLOEXEC |
124 | 0 | else if (*p == 'e') |
125 | 0 | flags |= O_CLOEXEC; |
126 | 0 | #endif |
127 | 0 | } |
128 | 0 |
|
129 | 0 | return flags; |
130 | 0 | } Unexecuted instantiation: last.c:ul_mode_to_flags Unexecuted instantiation: fileutils.c:ul_mode_to_flags Unexecuted instantiation: canonicalize.c:ul_mode_to_flags |
131 | | |
132 | | #ifdef __GLIBC__ |
133 | | |
134 | | struct ul_vfs_cookie { |
135 | | const struct ul_vfs_ops *vfs; |
136 | | int fd; |
137 | | }; |
138 | | |
139 | | static inline ssize_t ul_vfs_cookie_read(void *cookie, char *buf, size_t count) |
140 | 0 | { |
141 | 0 | struct ul_vfs_cookie *ck = (struct ul_vfs_cookie *) cookie; |
142 | 0 | return ul_vfs_read(ck->vfs, ck->fd, buf, count); |
143 | 0 | } Unexecuted instantiation: last.c:ul_vfs_cookie_read Unexecuted instantiation: fileutils.c:ul_vfs_cookie_read Unexecuted instantiation: canonicalize.c:ul_vfs_cookie_read |
144 | | |
145 | | static inline ssize_t ul_vfs_cookie_write(void *cookie, const char *buf, size_t count) |
146 | 0 | { |
147 | 0 | struct ul_vfs_cookie *ck = (struct ul_vfs_cookie *) cookie; |
148 | 0 | return ul_vfs_write(ck->vfs, ck->fd, buf, count); |
149 | 0 | } Unexecuted instantiation: last.c:ul_vfs_cookie_write Unexecuted instantiation: fileutils.c:ul_vfs_cookie_write Unexecuted instantiation: canonicalize.c:ul_vfs_cookie_write |
150 | | |
151 | | static inline int ul_vfs_cookie_seek(void *cookie, off64_t *pos, int whence) |
152 | 0 | { |
153 | 0 | struct ul_vfs_cookie *ck = (struct ul_vfs_cookie *) cookie; |
154 | 0 | off_t rc = ul_vfs_lseek(ck->vfs, ck->fd, (off_t) *pos, whence); |
155 | 0 |
|
156 | 0 | if (rc == (off_t) -1) |
157 | 0 | return -1; |
158 | 0 | *pos = (off64_t) rc; |
159 | 0 | return 0; |
160 | 0 | } Unexecuted instantiation: last.c:ul_vfs_cookie_seek Unexecuted instantiation: fileutils.c:ul_vfs_cookie_seek Unexecuted instantiation: canonicalize.c:ul_vfs_cookie_seek |
161 | | |
162 | | static inline int ul_vfs_cookie_close(void *cookie) |
163 | 0 | { |
164 | 0 | struct ul_vfs_cookie *ck = (struct ul_vfs_cookie *) cookie; |
165 | 0 | int rc = ul_vfs_close(ck->vfs, ck->fd); |
166 | 0 |
|
167 | 0 | free(ck); |
168 | 0 | return rc; |
169 | 0 | } Unexecuted instantiation: last.c:ul_vfs_cookie_close Unexecuted instantiation: fileutils.c:ul_vfs_cookie_close Unexecuted instantiation: canonicalize.c:ul_vfs_cookie_close |
170 | | |
171 | | static inline FILE *ul_vfs_fdopen(const struct ul_vfs_ops *vfs, |
172 | | int fd, const char *mode) |
173 | 0 | { |
174 | 0 | struct ul_vfs_cookie *ck; |
175 | 0 | cookie_io_functions_t io_funcs = { |
176 | 0 | .read = ul_vfs_cookie_read, |
177 | 0 | .write = ul_vfs_cookie_write, |
178 | 0 | .seek = ul_vfs_cookie_seek, |
179 | 0 | .close = ul_vfs_cookie_close, |
180 | 0 | }; |
181 | 0 |
|
182 | 0 | if (!vfs) |
183 | 0 | return fdopen(fd, mode); |
184 | 0 |
|
185 | 0 | ck = malloc(sizeof(*ck)); |
186 | 0 | if (!ck) |
187 | 0 | return NULL; |
188 | 0 | ck->vfs = vfs; |
189 | 0 | ck->fd = fd; |
190 | 0 |
|
191 | 0 | return fopencookie(ck, mode, io_funcs); |
192 | 0 | } Unexecuted instantiation: last.c:ul_vfs_fdopen Unexecuted instantiation: fileutils.c:ul_vfs_fdopen Unexecuted instantiation: canonicalize.c:ul_vfs_fdopen |
193 | | |
194 | | #else /* !__GLIBC__ */ |
195 | | |
196 | | static inline FILE *ul_vfs_fdopen( |
197 | | const struct ul_vfs_ops *vfs __attribute__((__unused__)), |
198 | | int fd, const char *mode) |
199 | | { |
200 | | return fdopen(fd, mode); |
201 | | } |
202 | | |
203 | | #endif /* __GLIBC__ */ |
204 | | |
205 | | static inline FILE *ul_vfs_fopen(const struct ul_vfs_ops *vfs, |
206 | | const char *path, const char *mode) |
207 | 0 | { |
208 | 0 | if (vfs && vfs->vfs_fopen) |
209 | 0 | return vfs->vfs_fopen(path, mode); |
210 | 0 | #ifdef __GLIBC__ |
211 | 0 | if (vfs && vfs->vfs_open) { |
212 | 0 | int flags = ul_mode_to_flags(mode); |
213 | 0 | int fd = ul_vfs_open(vfs, path, flags, 0); |
214 | 0 |
|
215 | 0 | if (fd < 0) |
216 | 0 | return NULL; |
217 | 0 | return ul_vfs_fdopen(vfs, fd, mode); |
218 | 0 | } |
219 | 0 | #endif |
220 | 0 | return fopen(path, mode); |
221 | 0 | } Unexecuted instantiation: last.c:ul_vfs_fopen Unexecuted instantiation: fileutils.c:ul_vfs_fopen Unexecuted instantiation: canonicalize.c:ul_vfs_fopen |
222 | | |
223 | | #endif /* UTIL_LINUX_VFS_H */ |