Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 : : /*
3 : : * Copyright 2010 Couchbase, Inc
4 : : *
5 : : * Licensed under the Apache License, Version 2.0 (the "License");
6 : : * you may not use this file except in compliance with the License.
7 : : * You may obtain a copy of the License at
8 : : *
9 : : * http://www.apache.org/licenses/LICENSE-2.0
10 : : *
11 : : * Unless required by applicable law or agreed to in writing, software
12 : : * distributed under the License is distributed on an "AS IS" BASIS,
13 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : : * See the License for the specific language governing permissions and
15 : : * limitations under the License.
16 : : */
17 : :
18 : : #include <sys/types.h>
19 : : #include <sys/stat.h>
20 : : #include <unistd.h>
21 : : #include <stdint.h>
22 : : #include <fcntl.h>
23 : : #include <stdio.h>
24 : : #include <errno.h>
25 : : #include <string.h>
26 : :
27 : : #include "filemgr.h"
28 : : #include "filemgr_ops.h"
29 : :
30 : : #if !defined(WIN32) && !defined(_WIN32)
31 : :
32 : 1417 : int _filemgr_linux_open(const char *pathname, int flags, mode_t mode)
33 : : {
34 : : int fd;
35 [ + + - + ]: 2471 : do {
[ - + ]
36 : 1417 : fd = open(pathname, flags | O_LARGEFILE, mode);
37 : 1052 : } while (fd == -1 && errno == EINTR);
38 : :
39 [ + + ]: 1419 : if (fd < 0) {
40 [ + - ]: 1052 : if (errno == ENOENT) {
41 : 1052 : return (int) FDB_RESULT_NO_SUCH_FILE;
42 : : } else {
43 : : return (int) FDB_RESULT_OPEN_FAIL; // LCOV_EXCL_LINE
44 : : }
45 : : }
46 : 1419 : return fd;
47 : : }
48 : :
49 : 1203587 : ssize_t _filemgr_linux_pwrite(int fd, void *buf, size_t count, cs_off_t offset)
50 : : {
51 : : ssize_t rv;
52 [ - + # # ]: 1203660 : do {
[ - + ]
53 : 1203587 : rv = pwrite(fd, buf, count, offset);
54 : : } while (rv == -1 && errno == EINTR); // LCOV_EXCL_LINE
55 : :
56 [ - + ]: 1203666 : if (rv < 0) {
57 : : return (ssize_t) FDB_RESULT_WRITE_FAIL; // LCOV_EXCL_LINE
58 : : }
59 : 1203666 : return rv;
60 : : }
61 : :
62 : 1821874 : ssize_t _filemgr_linux_pread(int fd, void *buf, size_t count, cs_off_t offset)
63 : : {
64 : : ssize_t rv;
65 [ + + - + ]: 1838417 : do {
[ + + ]
66 : 1821874 : rv = pread(fd, buf, count, offset);
67 : : } while (rv == -1 && errno == EINTR); // LCOV_EXCL_LINE
68 : :
69 [ + + ]: 1840393 : if (rv < 0) {
70 : : return (ssize_t) FDB_RESULT_READ_FAIL; // LCOV_EXCL_LINE
71 : : }
72 : 1840393 : return rv;
73 : : }
74 : :
75 : 364 : int _filemgr_linux_close(int fd)
76 : : {
77 : 364 : int rv = 0;
78 [ + - ]: 364 : if (fd != -1) {
79 [ - + # # ]: 364 : do {
[ - + ]
80 : 364 : rv = close(fd);
81 : : } while (rv == -1 && errno == EINTR); // LCOV_EXCL_LINE
82 : : }
83 : :
84 [ - + ]: 364 : if (rv < 0) {
85 : : return FDB_RESULT_CLOSE_FAIL; // LCOV_EXCL_LINE
86 : : }
87 : :
88 : 364 : return FDB_RESULT_SUCCESS;
89 : : }
90 : :
91 : 211006 : cs_off_t _filemgr_linux_goto_eof(int fd)
92 : : {
93 : 211006 : cs_off_t rv = lseek(fd, 0, SEEK_END);
94 [ - + ]: 211006 : if (rv < 0) {
95 : : return (cs_off_t) FDB_RESULT_SEEK_FAIL; // LCOV_EXCL_LINE
96 : : }
97 : 211006 : return rv;
98 : : }
99 : :
100 : 0 : cs_off_t _filemgr_linux_file_size(const char *filename)
101 : : {
102 : : struct stat st;
103 [ # # ]: 0 : if (stat(filename, &st) == -1) {
104 : 0 : return (cs_off_t) FDB_RESULT_READ_FAIL;
105 : : }
106 : 0 : return st.st_size;
107 : : }
108 : :
109 : 17411 : int _filemgr_linux_fsync(int fd)
110 : : {
111 : : int rv;
112 [ - + # # ]: 17411 : do {
[ - + ]
113 : 17411 : rv = fsync(fd);
114 : : } while (rv == -1 && errno == EINTR); // LCOV_EXCL_LINE
115 : :
116 [ - + ]: 17411 : if (rv == -1) {
117 : : return FDB_RESULT_FSYNC_FAIL; // LCOV_EXCL_LINE
118 : : }
119 : :
120 : 17411 : return FDB_RESULT_SUCCESS;
121 : : }
122 : :
123 : 0 : int _filemgr_linux_fdatasync(int fd)
124 : : {
125 : : #if defined(__linux__) && !defined(__ANDROID__)
126 : : int rv;
127 [ # # # # ]: 0 : do {
[ # # ]
128 : 0 : rv = fdatasync(fd);
129 : 0 : } while (rv == -1 && errno == EINTR);
130 : :
131 [ # # ]: 0 : if (rv == -1) {
132 : 0 : return FDB_RESULT_FSYNC_FAIL;
133 : : }
134 : :
135 : 0 : return FDB_RESULT_SUCCESS;
136 : : #else // __linux__ && not __ANDROID__
137 : : return _filemgr_linux_fsync(fd);
138 : : #endif // __linux__ && not __ANDROID__
139 : : }
140 : :
141 : 7858 : void _filemgr_linux_get_errno_str(char *buf, size_t size) {
142 [ - + ]: 7858 : if (!buf) {
143 : 7858 : return;
144 : : } else {
145 : 7858 : char *tbuf = alca(char, size);
146 : : #ifdef _POSIX_SOURCE
147 : 7858 : char *ret = strerror_r(errno, tbuf, size);
148 : 7858 : snprintf(buf, size, "errno = %d: '%s'", errno, ret);
149 : : #else
150 : : (void)strerror_r(errno, tbuf, size);
151 : : snprintf(buf, size, "errno = %d: '%s'", errno, tbuf);
152 : : #endif
153 : : }
154 : : }
155 : :
156 : : struct filemgr_ops linux_ops = {
157 : : _filemgr_linux_open,
158 : : _filemgr_linux_pwrite,
159 : : _filemgr_linux_pread,
160 : : _filemgr_linux_close,
161 : : _filemgr_linux_goto_eof,
162 : : _filemgr_linux_file_size,
163 : : _filemgr_linux_fdatasync,
164 : : _filemgr_linux_fsync,
165 : : _filemgr_linux_get_errno_str
166 : : };
167 : :
168 : 1659 : struct filemgr_ops * get_linux_filemgr_ops()
169 : : {
170 : 1659 : return &linux_ops;
171 : : }
172 : :
173 : : #endif
|