MySQL 8.4.0
Source Code Documentation
file.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2024, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is designed to work with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have either included with
14 the program or referenced in the documentation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*/
25
26#ifndef MYSQL_HARNESS_NET_TS_IMPL_FILE_H_
27#define MYSQL_HARNESS_NET_TS_IMPL_FILE_H_
28
29#include <array>
30#include <system_error>
31
32#ifdef _WIN32
33#include <WinSock2.h>
34#include <Windows.h>
35#else
36#include <fcntl.h>
37#include <unistd.h>
38#endif
39
41
42namespace net {
43namespace impl {
44namespace file {
45
46#ifdef _WIN32
48
49// can't be constexpr as INVALID_HANDLE_VALUE is a old-style-cast from -1 to
50// pointer
51const file_handle_type kInvalidHandle{INVALID_HANDLE_VALUE};
52#else
53using file_handle_type = int;
55#endif
56
57inline std::error_code last_error_code() {
58#ifdef _WIN32
59 return {static_cast<int>(GetLastError()), std::system_category()};
60#else
61 return {errno, std::generic_category()};
62#endif
63}
64
65template <int Name, class Arg>
67 public:
68 using value_type = Arg;
69
71
72 constexpr int name() const { return Name; }
73
74 constexpr value_type value() const { return v_; }
75
76 private:
78};
79
80template <int Name>
81class file_control_option<Name, void> {
82 public:
83 using arg_type = void;
84
86
87 constexpr int name() const { return Name; }
88
89 constexpr int value() const { return 0; }
90};
91
92#ifndef _WIN32
93// windows has "File Attribute Constants" (FILE_ATTRIBUTE_...) which
94// can be accessed via GetFileAttributes() and GetFileAttributesEx()
95// but there is no direct, good mapping to fcntl()
96
97// posix
100
101// posix
102//
103// - FD_CLOEXEC
106
107// posix
108//
109// - O_DIRECT
110// - O_NONBLOCK
113
114// posix
117
118#ifdef F_GETPIPE_SZ
119// linux
120using get_pipe_size = file_control_option<F_GETPIPE_SZ, void>;
121using set_pipe_size = file_control_option<F_SETPIPE_SZ, int>;
122#endif
123
124template <class FileControlOption>
126 file_handle_type fd, const FileControlOption &cmd) {
127 int res;
128 if (-1 == (res = ::fcntl(fd, cmd.name(), cmd.value()))) {
130 }
131
132 return {res};
133}
134#endif
135
136/**
137 * create pipe.
138 *
139 * @param flags flags passed to pipe2() like O_NONBLOCK or O_CLOEXEC
140 * @return pair file-handles or std::error_code
141 */
143 std::error_code>
144pipe(int flags = 0) {
145 std::array<file_handle_type, 2> fds{};
146#ifdef _WIN32
147 if (flags != 0) {
148 // on windows we can't set the flags
149 //
150 // PIPE_WAIT only exists for named-pipes
151 return stdx::unexpected(make_error_code(std::errc::invalid_argument));
152 }
153 if (0 == ::CreatePipe(&fds[0], &fds[1], nullptr, 0)) {
155 }
156#elif defined(__linux__) || defined(__FreeBSD__)
157 // pipe2() exists
158 // FreeBSD 10.0
159 // Linux 2.6.27
160 if (0 != ::pipe2(fds.data(), flags)) {
162 }
163#else
164 if (0 != ::pipe(fds.data())) {
166 }
167
169 auto fcntl_res = fcntl(fds[0], fl);
170 if (!fcntl_res) {
171 close(fds[0]);
172 close(fds[1]);
173
174 return stdx::unexpected(fcntl_res.error());
175 }
176
177 fcntl_res = fcntl(fds[1], fl);
178 if (!fcntl_res) {
179 close(fds[0]);
180 close(fds[1]);
181
182 return stdx::unexpected(fcntl_res.error());
183 }
184#endif
185
186 return std::make_pair(fds[0], fds[1]);
187}
188
189/**
190 * write a buffer to a file handle.
191 *
192 * calls write() on POSIX, WriteFile() on win32
193 */
195 const void *buf,
196 size_t buf_len) {
197#if defined(_WIN32)
198 DWORD transfered{0};
199 if (0 == ::WriteFile(handle, buf, buf_len, &transfered, nullptr)) {
201 }
202#else
203 ssize_t transfered = ::write(handle, buf, buf_len);
204 if (-1 == transfered) {
206 }
207#endif
208
209 return transfered;
210}
211
212/**
213 * read from file handle into a buffer.
214 *
215 * calls read() on POSIX, ReadFile() on win32
216 */
218 void *buf, size_t buf_len) {
219#if defined(_WIN32)
220 DWORD transfered{0};
221 if (0 == ::ReadFile(handle, buf, buf_len, &transfered, nullptr)) {
223 }
224#else
225 ssize_t transfered = ::read(handle, buf, buf_len);
226 if (-1 == transfered) {
228 }
229#endif
230
231 return transfered;
232}
233
234/**
235 * close file handle.
236 *
237 * calls close() on POSIX, CloseHandle() on win32
238 */
241#ifdef _WIN32
242 if (0 == ::CloseHandle(native_handle))
243#else
244 if (0 != ::close(native_handle))
245#endif
246 {
248 }
249 return {};
250} // namespace file
251
252} // namespace file
253} // namespace impl
254} // namespace net
255
256#endif
constexpr int value() const
Definition: file.h:89
constexpr int name() const
Definition: file.h:87
file_control_option(value_type v)
Definition: file.h:70
Arg value_type
Definition: file.h:68
value_type v_
Definition: file.h:77
constexpr value_type value() const
Definition: file.h:74
constexpr int name() const
Definition: file.h:72
Definition: expected.h:284
static int flags[50]
Definition: hp_test1.cc:40
Definition: buf0block_hint.cc:30
Definition: os0file.h:89
Definition: http_server_component.cc:34
stdx::expected< int, std::error_code > fcntl(file_handle_type fd, const FileControlOption &cmd)
Definition: file.h:125
stdx::expected< size_t, std::error_code > read(file_handle_type handle, void *buf, size_t buf_len)
read from file handle into a buffer.
Definition: file.h:217
int file_handle_type
Definition: file.h:53
constexpr file_handle_type kInvalidHandle
Definition: file.h:54
std::error_code last_error_code()
Definition: file.h:57
stdx::expected< std::pair< file_handle_type, file_handle_type >, std::error_code > pipe(int flags=0)
create pipe.
Definition: file.h:144
stdx::expected< size_t, std::error_code > write(file_handle_type handle, const void *buf, size_t buf_len)
write a buffer to a file handle.
Definition: file.h:194
stdx::expected< void, std::error_code > close(file_handle_type native_handle)
close file handle.
Definition: file.h:239
Definition: buffer.h:45
std::error_code make_error_code(net::stream_errc e) noexcept
Definition: buffer.h:103
static int handle(int sql_errno, const char *sqlstate, const char *message, void *state)
Bridge function between the C++ API offered by this module and the C API of the parser service.
Definition: services.cc:64
native_handle_type native_handle()
Definition: process.h:56
unexpected(E) -> unexpected< E >
#define HANDLE
Definition: violite.h:159