doc/Makefile.am: do not install internal documentation
[babeltrace.git] / include / babeltrace / compat / fcntl-internal.h
CommitLineData
a323afb2
JG
1#ifndef _BABELTRACE_COMPAT_FCNTL_H
2#define _BABELTRACE_COMPAT_FCNTL_H
3
4/*
5 * babeltrace/compat/fcntl.h
6 *
7 * Copyright 2015 (c) - Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 *
9 * fcntl compatibility layer.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * SOFTWARE.
28 */
29
a323afb2
JG
30#ifdef BABELTRACE_HAVE_POSIX_FALLOCATE
31
32#include <fcntl.h>
33
34static inline
35int bt_posix_fallocate(int fd, off_t offset, off_t len)
36{
37 return posix_fallocate(fd, offset, len);
38}
39
26fdbcef
MJ
40#elif defined(__MINGW32__) /* #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
41
42#include <assert.h>
43#include <windows.h>
44#include <fcntl.h>
45
46static inline
47int bt_posix_fallocate(int fd, off_t offset, off_t len)
48{
49 HANDLE handle;
50 LARGE_INTEGER pos, file_pos, orig_end_offset, range_end;
51 int ret = 0;
52 char zero = 0;
53 DWORD byteswritten;
54
55 if (offset < 0 || len <= 0) {
56 ret = EINVAL;
57 goto end;
58 }
59
60 range_end.QuadPart = (__int64) offset + (__int64) len;
61
62 /* Get a handle from the fd */
63 handle = (HANDLE) _get_osfhandle(fd);
64 if (handle == INVALID_HANDLE_VALUE) {
65 ret = EBADF;
66 goto end;
67 }
68
69 /* Get the file original end offset */
70 ret = GetFileSizeEx(handle, &orig_end_offset);
71 if (ret == 0) {
72 ret = EBADF;
73 goto end;
74 }
75
76 /* Make sure we don't truncate the file */
77 if (orig_end_offset.QuadPart >= range_end.QuadPart) {
78 ret = 0;
79 goto end;
80 }
81
82 /* Get the current file pointer position */
83 pos.QuadPart = 0;
84 ret = SetFilePointerEx(handle, pos, &file_pos, FILE_CURRENT);
85 if (ret == 0) {
86 ret = EBADF;
87 goto end;
88 }
89
90 /* Move the file pointer to the new end offset */
91 ret = SetFilePointerEx(handle, range_end, NULL, FILE_BEGIN);
92 if (ret == 0) {
93 ret = EBADF;
94 goto end;
95 }
96
97 /* Sets the physical file size to the current position */
98 ret = SetEndOfFile(handle);
99 if (ret == 0) {
100 ret = EINVAL;
101 goto restore;
102 }
103
104 /*
105 * Move the file pointer back 1 byte, and write a single 0 at the
106 * last byte of the new end offset, the operating system will zero
107 * fill the file.
108 */
109 pos.QuadPart = -1;
110 ret = SetFilePointerEx(handle, pos, NULL, FILE_END);
111 if (ret == 0) {
112 ret = EBADF;
113 goto end;
114 }
115
116 ret = WriteFile(handle, &zero, 1, &byteswritten, NULL);
117 if (ret == 0 || byteswritten != 1) {
118 ret = ENOSPC;
119 } else {
120 ret = 0;
121 }
122
123restore:
124 /* Restore the original file pointer position */
125 if (!SetFilePointerEx(handle, file_pos, NULL, FILE_BEGIN)) {
126 /* We moved the file pointer but failed to restore it. */
127 assert(0);
128 }
129
130end:
131 return ret;
132}
133
134#else
a323afb2
JG
135
136#include <sys/types.h>
137#include <unistd.h>
138#include <string.h>
139
140#define BABELTRACE_FALLOCATE_BUFLEN 256
141
142#ifndef min_t
143#define min_t(type, a, b) \
144 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
145#endif
146
147static inline
148int bt_posix_fallocate(int fd, off_t offset, off_t len)
149{
150 int ret = 0;
151 ssize_t copy_len;
152 char buf[BABELTRACE_FALLOCATE_BUFLEN];
153 off_t i, file_pos, orig_end_offset, range_end;
154
155 if (offset < 0 || len < 0) {
156 ret = EINVAL;
157 goto end;
158 }
159
160 range_end = offset + len;
161 if (range_end < 0) {
162 ret = EFBIG;
163 goto end;
164 }
165
166 file_pos = lseek(fd, 0, SEEK_CUR);
167 if (file_pos < 0) {
168 ret = errno;
169 goto end;
170 }
171
172 orig_end_offset = lseek(fd, 0, SEEK_END);
173 if (orig_end_offset < 0) {
174 ret = errno;
175 goto end;
176 }
177
178 /* Seek back to original position. */
179 ret = lseek(fd, file_pos, SEEK_SET);
180 if (ret) {
181 ret = errno;
182 goto end;
183 }
184
185 /*
186 * The file may not need to grow, but we want to ensure the
187 * space has actually been reserved by the file system. First, copy
188 * the "existing" region of the file, then grow the file if needed.
189 */
190 for (i = file_pos; i < min_t(off_t, range_end, orig_end_offset);
191 i += copy_len) {
192 ssize_t copy_ret;
193
194 copy_len = min_t(size_t, BABELTRACE_FALLOCATE_BUFLEN,
195 min_t(off_t, range_end - i,
196 orig_end_offset - i));
197 copy_ret = pread(fd, &buf, copy_len, i);
198 if (copy_ret < copy_len) {
199 /*
200 * The caller must handle any EINTR.
201 * POSIX_FALLOCATE(3) does not mention EINTR.
202 * However, glibc does forward to fallocate()
203 * directly on Linux, which may be interrupted.
204 */
205 ret = errno;
206 goto end;
207 }
208
209 copy_ret = pwrite(fd, &buf, copy_len, i);
210 if (copy_ret < copy_len) {
211 /* Same caveat as noted at pread() */
212 ret = errno;
213 goto end;
214 }
215 }
216
217 /* Grow file, as necessary. */
218 memset(&buf, 0, BABELTRACE_FALLOCATE_BUFLEN);
219 for (i = orig_end_offset; i < range_end; i += copy_len) {
220 ssize_t write_ret;
221
222 copy_len = min_t(size_t, BABELTRACE_FALLOCATE_BUFLEN,
223 range_end - i);
224 write_ret = pwrite(fd, &buf, copy_len, i);
225 if (write_ret < copy_len) {
226 ret = errno;
227 goto end;
228 }
229 }
230end:
231 return ret;
232}
233#endif /* #else #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
234
0bb657dc
MD
235
236#ifdef BABELTRACE_HAVE_FACCESSAT
237
238#include <fcntl.h>
239#include <unistd.h>
240
241static inline
242int bt_faccessat(int dirfd, const char *dirname,
243 const char *pathname, int mode, int flags)
244{
245 return faccessat(dirfd, pathname, mode, flags);
246}
247
248#else /* #ifdef BABELTRACE_HAVE_FACCESSAT */
249
250#include <string.h>
251#include <unistd.h>
252
253static inline
254int bt_faccessat(int dirfd, const char *dirname,
255 const char *pathname, int mode, int flags)
256{
257 char cpath[PATH_MAX];
258
259 if (flags != 0) {
260 errno = EINVAL;
261 return -1;
262 }
263 /* Includes middle / and final \0. */
264 if (strlen(dirname) + strlen(pathname) + 2 > PATH_MAX) {
265 return -1;
266 }
267 strcpy(cpath, dirname);
268 strcat(cpath, "/");
269 strcat(cpath, pathname);
270 return access(cpath, mode);
271}
272
273#endif /* #else #ifdef BABELTRACE_HAVE_FACCESSAT */
274
a323afb2 275#endif /* _BABELTRACE_COMPAT_FCNTL_H */
This page took 0.042551 seconds and 4 git commands to generate.