diff --git a/bootimgtool/bootimgtool.cpp b/bootimgtool/bootimgtool.cpp index b42747048..cace58fd2 100644 --- a/bootimgtool/bootimgtool.cpp +++ b/bootimgtool/bootimgtool.cpp @@ -53,7 +53,6 @@ // libmbpio #include -#include #include #define FIELD_CMDLINE "cmdline" @@ -863,9 +862,9 @@ static bool unpack_main(int argc, char *argv[]) prepend_if_empty(paths, output_dir, prefix); - if (!mb::io::create_directories(output_dir)) { + if (auto r = mb::io::create_directories(output_dir); !r) { fprintf(stderr, "%s: Failed to create directory: %s\n", - output_dir.c_str(), mb::io::last_error_string().c_str()); + output_dir.c_str(), r.error().message().c_str()); return false; } diff --git a/libmbpatcher/src/patchers/zippatcher.cpp b/libmbpatcher/src/patchers/zippatcher.cpp index 76ffeb3cf..1b2167555 100644 --- a/libmbpatcher/src/patchers/zippatcher.cpp +++ b/libmbpatcher/src/patchers/zippatcher.cpp @@ -235,7 +235,7 @@ bool ZipPatcher::patch_zip() FileUtils::create_temporary_dir(m_pc.temp_directory()); if (!pass1(temp_dir, exclude_from_pass1)) { - io::delete_recursively(temp_dir); + (void) io::delete_recursively(temp_dir); return false; } @@ -244,11 +244,11 @@ bool ZipPatcher::patch_zip() // On the second pass, run the autopatchers on the rest of the files if (!pass2(temp_dir, exclude_from_pass1)) { - io::delete_recursively(temp_dir); + (void) io::delete_recursively(temp_dir); return false; } - io::delete_recursively(temp_dir); + (void) io::delete_recursively(temp_dir); for (const CopySpec &spec : to_copy) { if (m_cancelled) return false; diff --git a/libmbpatcher/src/private/miniziputils.cpp b/libmbpatcher/src/private/miniziputils.cpp index 087738c69..3ba7444da 100644 --- a/libmbpatcher/src/private/miniziputils.cpp +++ b/libmbpatcher/src/private/miniziputils.cpp @@ -38,7 +38,6 @@ #include "mblog/logging.h" #include "mbpio/directory.h" -#include "mbpio/error.h" #include "mbpio/path.h" #include "mz_os.h" @@ -374,9 +373,9 @@ bool MinizipUtils::extract_file(void *handle, const std::string &directory) full_path += std::string{file_info->filename, file_info->filename_size}; std::string parent_path = io::dir_name(full_path); - if (!io::create_directories(parent_path)) { + if (auto r = io::create_directories(parent_path); !r) { LOGW("%s: Failed to create directory: %s", - parent_path.c_str(), io::last_error_string().c_str()); + parent_path.c_str(), r.error().message().c_str()); } StandardFile file; diff --git a/libmbpio/CMakeLists.txt b/libmbpio/CMakeLists.txt index 88f85d4ef..e4f646bed 100644 --- a/libmbpio/CMakeLists.txt +++ b/libmbpio/CMakeLists.txt @@ -20,7 +20,6 @@ foreach(variant ${variants}) ${uvariant} src/delete.cpp src/directory.cpp - src/error.cpp src/path.cpp ) diff --git a/libmbpio/include/mbpio/delete.h b/libmbpio/include/mbpio/delete.h index c237b681f..5db208d2d 100644 --- a/libmbpio/include/mbpio/delete.h +++ b/libmbpio/include/mbpio/delete.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -22,10 +22,11 @@ #include #include "mbcommon/common.h" +#include "mbcommon/outcome.h" namespace mb::io { -MB_EXPORT bool delete_recursively(const std::string &path); +MB_EXPORT oc::result delete_recursively(const std::string &path); } diff --git a/libmbpio/include/mbpio/directory.h b/libmbpio/include/mbpio/directory.h index 7233464b5..c36f1197a 100644 --- a/libmbpio/include/mbpio/directory.h +++ b/libmbpio/include/mbpio/directory.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -22,10 +22,11 @@ #include #include "mbcommon/common.h" +#include "mbcommon/outcome.h" namespace mb::io { -MB_EXPORT bool create_directories(const std::string &path); +MB_EXPORT oc::result create_directories(const std::string &path); } diff --git a/libmbpio/include/mbpio/error.h b/libmbpio/include/mbpio/error.h deleted file mode 100644 index 1862f4e72..000000000 --- a/libmbpio/include/mbpio/error.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015-2017 Andrew Gunnerson - * - * This file is part of DualBootPatcher - * - * DualBootPatcher is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * DualBootPatcher is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with DualBootPatcher. If not, see . - */ - -#pragma once - -#include - -#include "mbcommon/common.h" - -namespace mb::io -{ - -enum class Error -{ - NoError, - InvalidArguments, - PlatformError -}; - -MB_EXPORT Error last_error(); -MB_EXPORT std::string last_error_string(); - -// TODO: Put in private header -MB_EXPORT void set_last_error(Error error, std::string error_string); - -} diff --git a/libmbpio/include/mbpio/posix/delete.h b/libmbpio/include/mbpio/posix/delete.h index ff3563048..7a3106291 100644 --- a/libmbpio/include/mbpio/posix/delete.h +++ b/libmbpio/include/mbpio/posix/delete.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -22,10 +22,11 @@ #include #include "mbcommon/common.h" +#include "mbcommon/outcome.h" namespace mb::io::posix { -MB_EXPORT bool delete_recursively(const std::string &path); +MB_EXPORT oc::result delete_recursively(const std::string &path); } diff --git a/libmbpio/include/mbpio/win32/delete.h b/libmbpio/include/mbpio/win32/delete.h index d38faf7cd..684497ddd 100644 --- a/libmbpio/include/mbpio/win32/delete.h +++ b/libmbpio/include/mbpio/win32/delete.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -22,10 +22,11 @@ #include #include "mbcommon/common.h" +#include "mbcommon/outcome.h" namespace mb::io::win32 { -MB_EXPORT bool delete_recursively(const std::string &path); +MB_EXPORT oc::result delete_recursively(const std::string &path); } diff --git a/libmbpio/src/delete.cpp b/libmbpio/src/delete.cpp index 35ca8ef31..1fba2fb44 100644 --- a/libmbpio/src/delete.cpp +++ b/libmbpio/src/delete.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -28,7 +28,7 @@ namespace mb::io { -bool delete_recursively(const std::string &path) +oc::result delete_recursively(const std::string &path) { #ifdef _WIN32 return win32::delete_recursively(path); diff --git a/libmbpio/src/directory.cpp b/libmbpio/src/directory.cpp index 903d9df94..79d1e3cbc 100644 --- a/libmbpio/src/directory.cpp +++ b/libmbpio/src/directory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -23,9 +23,6 @@ #include "mbcommon/error_code.h" #include "mbcommon/locale.h" -#include "mbcommon/string.h" - -#include "mbpio/error.h" #ifdef _WIN32 # include @@ -37,7 +34,7 @@ namespace mb::io { -bool create_directories(const std::string &path) +oc::result create_directories(const std::string &path) { #ifdef _WIN32 constexpr char delim[] = "/\\"; @@ -55,8 +52,7 @@ bool create_directories(const std::string &path) #endif if (path.empty()) { - set_last_error(Error::InvalidArguments, "Path cannot be empty"); - return false; + return std::errc::invalid_argument; } // Add leading separator if needed @@ -70,37 +66,25 @@ bool create_directories(const std::string &path) temp += pathsep; #ifdef _WIN32 - auto w_temp = mb::utf8_to_wcs(temp); - if (!w_temp) { - set_last_error(Error::PlatformError, mb::format( - "%s: Failed to convert UTF-16 to UTF-8: %s", - temp.c_str(), w_temp.error().message().c_str())); - return false; - } + OUTCOME_TRY(w_temp, mb::utf8_to_wcs(temp)); - DWORD dw_attrib = GetFileAttributesW(w_temp.value().c_str()); + DWORD dw_attrib = GetFileAttributesW(w_temp.c_str()); bool exists = (dw_attrib != INVALID_FILE_ATTRIBUTES) && (dw_attrib & FILE_ATTRIBUTE_DIRECTORY); - if (!exists && !CreateDirectoryW(w_temp.value().c_str(), nullptr) + if (!exists && !CreateDirectoryW(w_temp.c_str(), nullptr) && GetLastError() != ERROR_ALREADY_EXISTS) { - set_last_error(Error::PlatformError, mb::format( - "%s: Failed to create directory: %s", - temp.c_str(), mb::ec_from_win32().message().c_str())); - return false; + return ec_from_win32(); } #else if (mkdir(temp.c_str(), 0755) < 0 && errno != EEXIST) { - set_last_error(Error::PlatformError, mb::format( - "%s: Failed to create directory: %s", - temp.c_str(), strerror(errno))); - return false; + return ec_from_errno(); } #endif p = strtok_r(nullptr, delim, &save_ptr); } - return true; + return oc::success(); } } diff --git a/libmbpio/src/error.cpp b/libmbpio/src/error.cpp deleted file mode 100644 index 5dc82504e..000000000 --- a/libmbpio/src/error.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2015-2017 Andrew Gunnerson - * - * This file is part of DualBootPatcher - * - * DualBootPatcher is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * DualBootPatcher is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with DualBootPatcher. If not, see . - */ - -#include "mbpio/error.h" - -#ifdef __ANDROID__ -# include -#endif - -namespace mb::io -{ - -#ifdef __ANDROID__ -// The NDK doesn't support TLS -static pthread_once_t g_tls_once = PTHREAD_ONCE_INIT; -static pthread_key_t g_tls_key_error = 0; -static pthread_key_t g_tls_key_error_string = 0; -#else -thread_local Error g_error; -thread_local std::string g_error_string; -#endif - -#ifdef __ANDROID__ -static void _destroy_error(void *st) -{ - delete static_cast(st); -} - -static void _destroy_error_string(void *st) -{ - delete static_cast(st); -} - -static void _init_tls_keys() -{ - pthread_key_create(&g_tls_key_error, _destroy_error); - pthread_key_create(&g_tls_key_error_string, _destroy_error_string); - pthread_setspecific(g_tls_key_error, new int()); - pthread_setspecific(g_tls_key_error_string, new std::string()); -} -#endif - -Error last_error() -{ -#ifdef __ANDROID__ - if (pthread_once(&g_tls_once, _init_tls_keys) == 0) { - Error *ptr = static_cast(pthread_getspecific(g_tls_key_error)); - if (ptr) { - return *ptr; - } - } - return Error::NoError; -#else - return g_error; -#endif -} - -std::string last_error_string() -{ -#ifdef __ANDROID__ - if (pthread_once(&g_tls_once, _init_tls_keys) == 0) { - std::string *ptr = static_cast( - pthread_getspecific(g_tls_key_error_string)); - if (ptr) { - return *ptr; - } - } - return {}; -#else - return g_error_string; -#endif -} - -void set_last_error(Error error, std::string error_string) -{ -#ifdef __ANDROID__ - if (pthread_once(&g_tls_once, _init_tls_keys) == 0) { - Error *tls_error = static_cast( - pthread_getspecific(g_tls_key_error)); - if (tls_error) { - *tls_error = error; - } - std::string *tls_error_string = static_cast( - pthread_getspecific(g_tls_key_error_string)); - if (tls_error_string) { - *tls_error_string = std::move(error_string); - } - } -#else - g_error = error; - g_error_string = std::move(error_string); -#endif -} - -} diff --git a/libmbpio/src/posix/delete.cpp b/libmbpio/src/posix/delete.cpp index d39e5b3f7..17e3e5050 100644 --- a/libmbpio/src/posix/delete.cpp +++ b/libmbpio/src/posix/delete.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -19,36 +19,30 @@ #include "mbpio/posix/delete.h" -#include -#include - #include -#include "mbcommon/string.h" - -#include "mbpio/error.h" +#include "mbcommon/error_code.h" namespace mb::io::posix { static int _delete_cb(const char *fpath, const struct stat *sb, - int typeflag, struct FTW *ftwbuf) + int typeflag, FTW *ftwbuf) { (void) sb; (void) typeflag; (void) ftwbuf; - int ret = remove(fpath); - if (ret < 0) { - set_last_error(Error::PlatformError, mb::format( - "%s: Failed to remove: %s", fpath, strerror(errno))); - } - return ret; + return remove(fpath); } -bool delete_recursively(const std::string &path) +oc::result delete_recursively(const std::string &path) { - return nftw(path.c_str(), _delete_cb, 64, FTW_DEPTH | FTW_PHYS) == 0; + if (nftw(path.c_str(), _delete_cb, 64, FTW_DEPTH | FTW_PHYS) < 0) { + return ec_from_errno(); + } + + return oc::success(); } } diff --git a/libmbpio/src/win32/delete.cpp b/libmbpio/src/win32/delete.cpp index 47eb3bc67..c917775ff 100644 --- a/libmbpio/src/win32/delete.cpp +++ b/libmbpio/src/win32/delete.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2017 Andrew Gunnerson + * Copyright (C) 2015-2018 Andrew Gunnerson * * This file is part of DualBootPatcher * @@ -26,16 +26,13 @@ #include "mbcommon/error_code.h" #include "mbcommon/locale.h" -#include "mbcommon/string.h" - -#include "mbpio/error.h" namespace mb::io::win32 { using ScopedFindHandle = std::unique_ptr, decltype(FindClose) *>; -static bool _win32_recursive_delete(const std::wstring &path) +static oc::result _win32_recursive_delete(const std::wstring &path) { std::wstring mask(path); mask += L"\\*"; @@ -52,12 +49,8 @@ static bool _win32_recursive_delete(const std::wstring &path) 0 // dwAdditionalFlags ); if (_search_handle == INVALID_HANDLE_VALUE) { - DWORD error = GetLastError(); - if (error != ERROR_FILE_NOT_FOUND) { - set_last_error(Error::PlatformError, mb::format( - "FindFirstFileExW() failed: %s", - mb::ec_from_win32(error).message().c_str())); - return false; + if (auto error = GetLastError(); error != ERROR_FILE_NOT_FOUND) { + return ec_from_win32(error); } } else { ScopedFindHandle search_handle(_search_handle, &FindClose); @@ -72,28 +65,18 @@ static bool _win32_recursive_delete(const std::wstring &path) child_path += find_data.cFileName; if (is_directory) { - if (!_win32_recursive_delete(child_path)) { - return false; - } + OUTCOME_TRYV(_win32_recursive_delete(child_path)); } else { if (!DeleteFileW(child_path.c_str())) { - DWORD error = GetLastError(); - set_last_error(Error::PlatformError, mb::format( - "DeleteFileW() failed: %s", - mb::ec_from_win32(error).message().c_str())); - return false; + return ec_from_win32(); } } } // Advance to the next file in the directory if (!FindNextFileW(search_handle.get(), &find_data)) { - DWORD error = GetLastError(); - if (error != ERROR_NO_MORE_FILES) { - set_last_error(Error::PlatformError, mb::format( - "FindNextFileW() failed: %s", - mb::ec_from_win32(error).message().c_str())); - return false; + if (auto error = GetLastError(); error != ERROR_NO_MORE_FILES) { + return ec_from_win32(error); } break; } @@ -101,25 +84,17 @@ static bool _win32_recursive_delete(const std::wstring &path) } if (!RemoveDirectoryW(path.c_str())) { - DWORD error = GetLastError(); - set_last_error(Error::PlatformError, mb::format( - "RemoveDirectoryW() failed: %s", - mb::ec_from_win32(error).message().c_str())); - return false; + return ec_from_win32(); } - return true; + return oc::success(); } -bool delete_recursively(const std::string &path) +oc::result delete_recursively(const std::string &path) { - auto w_path = mb::utf8_to_wcs(path); - - if (!w_path) { - return false; - } + OUTCOME_TRY(w_path, mb::utf8_to_wcs(path)); - return _win32_recursive_delete(w_path.value()); + return _win32_recursive_delete(w_path); } }