MySQL 8.2.0
Source Code Documentation
file.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2019, 2023, 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 also distributed 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 included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24
25#ifndef MYSQL_HARNESS_NET_TS_IMPL_FILE_H_
26#define MYSQL_HARNESS_NET_TS_IMPL_FILE_H_
27
28#include <array>
29#include <system_error>
30
31#ifdef _WIN32
32#include <WinSock2.h>
33#include <Windows.h>
34#else
35#include <fcntl.h>
36#include <unistd.h>
37#endif
38
40
41namespace net {
42namespace impl {
43namespace file {
44
45#ifdef _WIN32
47
48// can't be constexpr as INVALID_HANDLE_VALUE is a old-style-cast from -1 to
49// pointer
50const file_handle_type kInvalidHandle{INVALID_HANDLE_VALUE};
51#else
52using file_handle_type = int;
54#endif
55
56inline std::error_code last_error_code() {
57#ifdef _WIN32
58 return {static_cast<int>(GetLastError()), std::system_category()};
59#else
60 return {errno, std::generic_category()};
61#endif
62}
63
64template <int Name, class Arg>
66 public:
67 using value_type = Arg;
68
70
71 constexpr int name() const { return Name; }
72
73 constexpr value_type value() const { return v_; }
74
75 private:
77};
78
79template <int Name>
80class file_control_option<Name, void> {
81 public:
82 using arg_type = void;
83
85
86 constexpr int name() const { return Name; }
87
88 constexpr int value() const { return 0; }
89};
90
91#ifndef _WIN32
92// windows has "File Attribute Constants" (FILE_ATTRIBUTE_...) which
93// can be accessed via GetFileAttributes() and GetFileAttributesEx()
94// but there is no direct, good mapping to fcntl()
95
96// posix
99
100// posix
101//
102// - FD_CLOEXEC
105
106// posix
107//
108// - O_DIRECT
109// - O_NONBLOCK
112
113// posix
116
117#ifdef F_GETPIPE_SZ
118// linux
119using get_pipe_size = file_control_option<F_GETPIPE_SZ, void>;
120using set_pipe_size = file_control_option<F_SETPIPE_SZ, int>;
121#endif
122
123template <class FileControlOption>
125 file_handle_type fd, const FileControlOption &cmd) {
126 int res;
127 if (-1 == (res = ::fcntl(fd, cmd.name(), cmd.value()))) {
129 }
130
131 return {res};
132}
133#endif
134
135/**
136 * create pipe.
137 *
138 * @param flags flags passed to pipe2() like O_NONBLOCK or O_CLOEXEC
139 * @return pair file-handles or std::error_code
140 */
142 std::error_code>
143pipe(int flags = 0) {
144 std::array<file_handle_type, 2> fds{};
145#ifdef _WIN32
146 if (flags != 0) {
147 // on windows we can't set the flags
148 //
149 // PIPE_WAIT only exists for named-pipes
150 return stdx::make_unexpected(make_error_code(std::errc::invalid_argument));
151 }
152 if (0 == ::CreatePipe(&fds[0], &fds[1], nullptr, 0)) {
154 }
155#elif defined(__linux__) || defined(__FreeBSD__)
156 // pipe2() exists
157 // FreeBSD 10.0
158 // Linux 2.6.27
159 if (0 != ::pipe2(fds.data(), flags)) {
161 }
162#else
163 if (0 != ::pipe(fds.data())) {
165 }
166
168 auto fcntl_res = fcntl(fds[0], fl);
169 if (!fcntl_res) {
170 close(fds[0]);
171 close(fds[1]);
172
173 return stdx::make_unexpected(fcntl_res.error());
174 }
175
176 fcntl_res = fcntl(fds[1], fl);
177 if (!fcntl_res) {
178 close(fds[0]);
179 close(fds[1]);
180
181 return stdx::make_unexpected(fcntl_res.error());
182 }
183#endif
184
185 return std::make_pair(fds[0], fds[1]);
186}
187
188/**
189 * write a buffer to a file handle.
190 *
191 * calls write() on POSIX, WriteFile() on win32
192 */
194 const void *buf,
195 size_t buf_len) {
196#if defined(_WIN32)
197 DWORD transfered{0};
198 if (0 == ::WriteFile(handle, buf, buf_len, &transfered, nullptr)) {
200 }
201#else
202 ssize_t transfered = ::write(handle, buf, buf_len);
203 if (-1 == transfered) {
205 }
206#endif
207
208 return transfered;
209}
210
211/**
212 * read from file handle into a buffer.
213 *
214 * calls read() on POSIX, ReadFile() on win32
215 */
217 void *buf, size_t buf_len) {
218#if defined(_WIN32)
219 DWORD transfered{0};
220 if (0 == ::ReadFile(handle, buf, buf_len, &transfered, nullptr)) {
222 }
223#else
224 ssize_t transfered = ::read(handle, buf, buf_len);
225 if (-1 == transfered) {
227 }
228#endif
229
230 return transfered;
231}
232
233/**
234 * close file handle.
235 *
236 * calls close() on POSIX, CloseHandle() on win32
237 */
240#ifdef _WIN32
241 if (0 == ::CloseHandle(native_handle))
242#else
243 if (0 != ::close(native_handle))
244#endif
245 {
247 }
248 return {};
249} // namespace file
250
251} // namespace file
252} // namespace impl
253} // namespace net
254
255#endif
constexpr int value() const
Definition: file.h:88
constexpr int name() const
Definition: file.h:86
file_control_option(value_type v)
Definition: file.h:69
Arg value_type
Definition: file.h:67
value_type v_
Definition: file.h:76
constexpr value_type value() const
Definition: file.h:73
constexpr int name() const
Definition: file.h:71
Definition: expected.h:943
static int flags[50]
Definition: hp_test1.cc:39
Definition: buf0block_hint.cc:29
Definition: os0file.h:88
Definition: authentication.cc:35
stdx::expected< int, std::error_code > fcntl(file_handle_type fd, const FileControlOption &cmd)
Definition: file.h:124
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:216
int file_handle_type
Definition: file.h:52
constexpr file_handle_type kInvalidHandle
Definition: file.h:53
std::error_code last_error_code()
Definition: file.h:56
stdx::expected< std::pair< file_handle_type, file_handle_type >, std::error_code > pipe(int flags=0)
create pipe.
Definition: file.h:143
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:193
stdx::expected< void, std::error_code > close(file_handle_type native_handle)
close file handle.
Definition: file.h:238
Definition: buffer.h:44
std::error_code make_error_code(net::stream_errc e) noexcept
Definition: buffer.h:102
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:63
native_handle_type native_handle()
Definition: process.h:55
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
#define HANDLE
Definition: violite.h:158