| 291 | } |
| 292 | |
| 293 | bool |
| 294 | create_directories(const path &p, std::error_code &ec, mode_t mode) noexcept { |
| 295 | TextView text(p.string()); |
| 296 | |
| 297 | if (text.empty()) { |
| 298 | ec = std::error_code(EINVAL, std::system_category()); |
| 299 | return false; |
| 300 | } |
| 301 | |
| 302 | path path; |
| 303 | |
| 304 | if (text.front() == path::SEPARATOR) { |
| 305 | path = text.prefix(1); // copy leading separator. |
| 306 | ++text; |
| 307 | if (!text) { |
| 308 | ec.clear(); |
| 309 | return true; // Tried to create root directory, it's already tehre. |
| 310 | } |
| 311 | } |
| 312 | |
| 313 | path.reserve(p.string().size()); |
| 314 | |
| 315 | while (text) { |
| 316 | auto elt = text.take_prefix_at(path::SEPARATOR); |
| 317 | path /= elt; |
| 318 | if (!create_directory(path, ec, mode)) { |
| 319 | return false; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | return true; |
| 324 | } |
| 325 | |
| 326 | bool |
| 327 | copy(const path &from, const path &to, std::error_code &ec) { |