2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
20 * Copyright 2020 ScyllaDB
25 #include <seastar/core/future.hh>
26 #include <seastar/core/file.hh>
27 #include <seastar/core/thread.hh>
28 #include <seastar/util/std-compat.hh>
32 const std::filesystem::path& default_tmpdir();
33 void set_default_tmpdir(std::filesystem::path);
36 std::filesystem::path _path;
38 bool _is_open = false;
40 static_assert(std::is_nothrow_constructible<std::filesystem::path>::value,
41 "filesystem::path's constructor must not throw");
42 static_assert(std::is_nothrow_move_constructible<std::filesystem::path>::value,
43 "filesystem::path's move constructor must not throw");
45 tmp_file() noexcept = default;
46 tmp_file(const tmp_file&) = delete;
47 tmp_file(tmp_file&& x) noexcept;
49 tmp_file& operator=(tmp_file&&) noexcept = default;
53 future<> open(std::filesystem::path path_template = default_tmpdir(),
54 open_flags oflags = open_flags::rw,
55 file_open_options options = {}) noexcept;
56 future<> close() noexcept;
57 future<> remove() noexcept;
59 template <typename Func>
60 static future<> do_with(std::filesystem::path path_template, Func&& func,
61 open_flags oflags = open_flags::rw,
62 file_open_options options = {}) noexcept {
63 static_assert(std::is_nothrow_move_constructible<Func>::value,
64 "Func's move constructor must not throw");
65 return seastar::do_with(tmp_file(), [func = std::move(func), path_template = std::move(path_template), oflags, options = std::move(options)] (tmp_file& t) mutable {
66 return t.open(std::move(path_template), oflags, std::move(options)).then([&t, func = std::move(func)] () mutable {
69 return t.close().finally([&t] {
76 template <typename Func>
77 static future<> do_with(Func&& func) noexcept {
78 return do_with(default_tmpdir(), std::move(func));
81 bool has_path() const {
82 return !_path.empty();
85 bool is_open() const {
89 const std::filesystem::path& get_path() const {
98 /// Returns a future for an opened tmp_file exclusively created by the function.
100 /// \param path_template - path where the file is to be created,
101 /// optionally including a template for the file name.
102 /// \param oflags - optional \ref open_flags (open_flags::create | open_flags::exclusive are added to those by default)
103 /// \param options - additional \ref file_open_options, e.g. for setting the created file permission.
106 /// path_template may optionally include a filename template in the last component of the path.
107 /// The template is indicated by two or more consecutive XX's.
108 /// Those will be replaced in the result path by a unique string.
110 /// If no filename template is found, then path_template is assumed to refer to the directory where
111 /// the temporary file is to be created at (a.k.a. the parent directory) and `default_tmp_name_template`
112 /// is appended to the path as the filename template.
114 /// The parent directory must exist and be writable to the current process.
116 future<tmp_file> make_tmp_file(std::filesystem::path path_template = default_tmpdir(),
117 open_flags oflags = open_flags::rw, file_open_options options = {}) noexcept;
120 std::filesystem::path _path;
124 tmp_dir(const tmp_dir&) = delete;
125 tmp_dir(tmp_dir&& x) = default;
127 tmp_dir& operator=(tmp_dir&&) noexcept = default;
131 future<> create(std::filesystem::path path_template = default_tmpdir(),
132 file_permissions create_permissions = file_permissions::default_dir_permissions) noexcept;
133 future<> remove() noexcept;
135 template <typename Func>
136 SEASTAR_CONCEPT( requires std::is_nothrow_move_constructible_v<Func> )
137 static future<> do_with(std::filesystem::path path_template, Func&& func,
138 file_permissions create_permissions = file_permissions::default_dir_permissions) noexcept {
139 static_assert(std::is_nothrow_move_constructible_v<Func>,
140 "Func's move constructor must not throw");
141 return seastar::do_with(tmp_dir(), [func = std::move(func), path_template = std::move(path_template), create_permissions] (tmp_dir& t) mutable {
142 return t.create(std::move(path_template), create_permissions).then([&t, func = std::move(func)] () mutable {
150 template <typename Func>
151 static future<> do_with(Func&& func) noexcept {
152 return do_with(default_tmpdir(), std::move(func));
155 template <typename Func>
157 SEASTAR_CONCEPT( requires std::is_nothrow_move_constructible_v<Func> )
158 static future<> do_with_thread(Func&& func) noexcept {
159 static_assert(std::is_nothrow_move_constructible_v<Func>,
160 "Func's move constructor must not throw");
161 return async([func = std::move(func)] () mutable {
164 futurize_invoke(func, t).finally([&t] {
170 bool has_path() const {
171 return !_path.empty();
174 const std::filesystem::path& get_path() const {
179 /// Returns a future for a tmp_dir exclusively created by the function.
181 /// \param path_template - path where the file is to be created,
182 /// optionally including a template for the file name.
183 /// \param create_permissions - optional permissions for the newly created directory.
186 /// path_template may optionally include a name template in the last component of the path.
187 /// The template is indicated by two or more consecutive XX's.
188 /// Those will be replaced in the result path by a unique string.
190 /// If no name template is found, then path_template is assumed to refer to the directory where
191 /// the temporary dir is to be created at (a.k.a. the parent directory) and `default_tmp_name_template`
192 /// is appended to the path as the name template for the to-be-created directory.
194 /// The parent directory must exist and be writable to the current process.
196 future<tmp_dir> make_tmp_dir(std::filesystem::path path_template = default_tmpdir(),
197 file_permissions create_permissions = file_permissions::default_dir_permissions) noexcept;
199 } // namespace seastar