Fix: src.ctf.fs: initialize the other_entry variable
[babeltrace.git] / src / compat / fcntl.h
CommitLineData
a323afb2
JG
1#ifndef _BABELTRACE_COMPAT_FCNTL_H
2#define _BABELTRACE_COMPAT_FCNTL_H
3
4/*
a323afb2
JG
5 * Copyright 2015 (c) - Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 *
7 * fcntl compatibility layer.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
498e7994
PP
28#include "common/common.h"
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
f23a034a 42#include <stdlib.h>
26fdbcef
MJ
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. */
498e7994 127 bt_common_abort();
26fdbcef
MJ
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
235#endif /* _BABELTRACE_COMPAT_FCNTL_H */
This page took 0.074157 seconds and 4 git commands to generate.