diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2020-03-07 14:07:28 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2020-03-09 14:18:20 +0300 |
commit | dcccba655fe848564e961b3f285ce3a82d3ac73a (patch) | |
tree | 598ced3b406d80c23798672930e1a17cfe112b75 /libbutl/win32-utility.hxx | |
parent | 63b2988e4f2630cc688ff43b7e5f0d4f977896cd (diff) |
Add more support for symlinks on Windows
See mksymlink() for details of the symlinks support on Windows.
Diffstat (limited to 'libbutl/win32-utility.hxx')
-rw-r--r-- | libbutl/win32-utility.hxx | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/libbutl/win32-utility.hxx b/libbutl/win32-utility.hxx index 70aafc4..b71eb1a 100644 --- a/libbutl/win32-utility.hxx +++ b/libbutl/win32-utility.hxx @@ -43,6 +43,86 @@ namespace butl { namespace win32 { + // RAII type for handles. Note that failure to close the handle is + // silently ignored by both the destructor and reset(). + // + // The handle can be INVALID_HANDLE_VALUE. Such a handle is treated as + // unopened and is not closed. + // + struct nullhandle_t + { + constexpr explicit nullhandle_t (HANDLE) {} + operator HANDLE () const {return INVALID_HANDLE_VALUE;} + }; + + LIBBUTL_SYMEXPORT extern const nullhandle_t nullhandle; + + class LIBBUTL_SYMEXPORT auto_handle + { + public: + auto_handle (nullhandle_t = nullhandle) noexcept + : handle_ (INVALID_HANDLE_VALUE) {} + + explicit + auto_handle (HANDLE h) noexcept: handle_ (h) {} + + auto_handle (auto_handle&& h) noexcept: handle_ (h.release ()) {} + auto_handle& operator= (auto_handle&&) noexcept; + + auto_handle (const auto_handle&) = delete; + auto_handle& operator= (const auto_handle&) = delete; + + ~auto_handle () noexcept; + + HANDLE + get () const noexcept {return handle_;} + + void + reset (HANDLE h = INVALID_HANDLE_VALUE) noexcept; + + HANDLE + release () noexcept + { + HANDLE r (handle_); + handle_ = INVALID_HANDLE_VALUE; + return r; + } + + // Close an open handle. Throw std::system_error on the underlying OS + // error. Reset the descriptor to INVALID_HANDLE_VALUE whether the + // exception is thrown or not. + // + void + close (); + + private: + HANDLE handle_; + }; + + inline bool + operator== (const auto_handle& x, const auto_handle& y) + { + return x.get () == y.get (); + } + + inline bool + operator!= (const auto_handle& x, const auto_handle& y) + { + return !(x == y); + } + + inline bool + operator== (const auto_handle& x, nullhandle_t) + { + return x.get () == INVALID_HANDLE_VALUE; + } + + inline bool + operator!= (const auto_handle& x, nullhandle_t y) + { + return !(x == y); + } + LIBBUTL_SYMEXPORT std::string error_msg (DWORD code); @@ -51,4 +131,5 @@ namespace butl } }; +#include <libbutl/win32-utility.ixx> #endif // _WIN32 |