Port: Include config.h globally trough DEFAULT_INCLUDES
[babeltrace.git] / include / babeltrace / compat / fcntl.h
CommitLineData
edcad9c1
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
edcad9c1
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
40#else /* #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
41
42#include <sys/types.h>
43#include <unistd.h>
44#include <string.h>
45
46#define BABELTRACE_FALLOCATE_BUFLEN 256
47
48#ifndef min_t
49#define min_t(type, a, b) \
50 ((type) (a) < (type) (b) ? (type) (a) : (type) (b))
51#endif
52
53static inline
54int bt_posix_fallocate(int fd, off_t offset, off_t len)
55{
56 int ret = 0;
57 ssize_t copy_len;
58 char buf[BABELTRACE_FALLOCATE_BUFLEN];
59 off_t i, file_pos, orig_end_offset, range_end;
60
61 if (offset < 0 || len < 0) {
62 ret = EINVAL;
63 goto end;
64 }
65
66 range_end = offset + len;
67 if (range_end < 0) {
68 ret = EFBIG;
69 goto end;
70 }
71
72 file_pos = lseek(fd, 0, SEEK_CUR);
73 if (file_pos < 0) {
74 ret = errno;
75 goto end;
76 }
77
78 orig_end_offset = lseek(fd, 0, SEEK_END);
79 if (orig_end_offset < 0) {
80 ret = errno;
81 goto end;
82 }
83
84 /* Seek back to original position. */
85 ret = lseek(fd, file_pos, SEEK_SET);
86 if (ret) {
87 ret = errno;
88 goto end;
89 }
90
91 /*
92 * The file may not need to grow, but we want to ensure the
93 * space has actually been reserved by the file system. First, copy
94 * the "existing" region of the file, then grow the file if needed.
95 */
96 for (i = file_pos; i < min_t(off_t, range_end, orig_end_offset);
97 i += copy_len) {
98 ssize_t copy_ret;
99
100 copy_len = min_t(size_t, BABELTRACE_FALLOCATE_BUFLEN,
101 min_t(off_t, range_end - i,
102 orig_end_offset - i));
103 copy_ret = pread(fd, &buf, copy_len, i);
104 if (copy_ret < copy_len) {
105 /*
106 * The caller must handle any EINTR.
107 * POSIX_FALLOCATE(3) does not mention EINTR.
108 * However, glibc does forward to fallocate()
109 * directly on Linux, which may be interrupted.
110 */
111 ret = errno;
112 goto end;
113 }
114
115 copy_ret = pwrite(fd, &buf, copy_len, i);
116 if (copy_ret < copy_len) {
117 /* Same caveat as noted at pread() */
118 ret = errno;
119 goto end;
120 }
121 }
122
123 /* Grow file, as necessary. */
124 memset(&buf, 0, BABELTRACE_FALLOCATE_BUFLEN);
125 for (i = orig_end_offset; i < range_end; i += copy_len) {
126 ssize_t write_ret;
127
128 copy_len = min_t(size_t, BABELTRACE_FALLOCATE_BUFLEN,
129 range_end - i);
130 write_ret = pwrite(fd, &buf, copy_len, i);
131 if (write_ret < copy_len) {
132 ret = errno;
133 goto end;
134 }
135 }
136end:
137 return ret;
138}
139#endif /* #else #ifdef BABELTRACE_HAVE_POSIX_FALLOCATE */
140
ff48c2b0
MD
141
142#ifdef BABELTRACE_HAVE_FACCESSAT
143
144#include <fcntl.h>
145#include <unistd.h>
146
147static inline
148int bt_faccessat(int dirfd, const char *dirname,
149 const char *pathname, int mode, int flags)
150{
151 return faccessat(dirfd, pathname, mode, flags);
152}
153
154#else /* #ifdef BABELTRACE_HAVE_FACCESSAT */
155
156#include <string.h>
157#include <unistd.h>
158
159static inline
160int bt_faccessat(int dirfd, const char *dirname,
161 const char *pathname, int mode, int flags)
162{
163 char cpath[PATH_MAX];
164
165 if (flags != 0) {
166 errno = EINVAL;
167 return -1;
168 }
169 /* Includes middle / and final \0. */
170 if (strlen(dirname) + strlen(pathname) + 2 > PATH_MAX) {
171 return -1;
172 }
173 strcpy(cpath, dirname);
174 strcat(cpath, "/");
175 strcat(cpath, pathname);
176 return access(cpath, mode);
177}
178
179#endif /* #else #ifdef BABELTRACE_HAVE_FACCESSAT */
180
edcad9c1 181#endif /* _BABELTRACE_COMPAT_FCNTL_H */
This page took 0.0291 seconds and 4 git commands to generate.