1 // Copyright (c) 2016 Klemens D. Morgenstern 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #ifndef BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ 7 #define BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ 8 9 #include <boost/winapi/basic_types.hpp> 10 #include <boost/winapi/handles.hpp> 11 #include <boost/winapi/file_management.hpp> 12 #include <string> 13 #include <boost/filesystem/path.hpp> 14 #include <boost/core/exchange.hpp> 15 16 namespace boost { namespace process { namespace detail { namespace windows { 17 18 struct file_descriptor 19 { 20 enum mode_t 21 { 22 read = 1, 23 write = 2, 24 read_write = 3 25 }; desired_accessboost::process::detail::windows::file_descriptor26 static ::boost::winapi::DWORD_ desired_access(mode_t mode) 27 { 28 switch(mode) 29 { 30 case read: 31 return ::boost::winapi::GENERIC_READ_; 32 case write: 33 return ::boost::winapi::GENERIC_WRITE_; 34 case read_write: 35 return ::boost::winapi::GENERIC_READ_ 36 | ::boost::winapi::GENERIC_WRITE_; 37 default: 38 return 0u; 39 } 40 } 41 42 file_descriptor() = default; file_descriptorboost::process::detail::windows::file_descriptor43 file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write) 44 : file_descriptor(p.native(), mode) 45 { 46 } 47 file_descriptorboost::process::detail::windows::file_descriptor48 file_descriptor(const std::string & path , mode_t mode = read_write) 49 #if defined(BOOST_NO_ANSI_APIS) 50 : file_descriptor(::boost::process::detail::convert(path), mode) 51 #else 52 : file_descriptor(path.c_str(), mode) 53 #endif 54 {} file_descriptorboost::process::detail::windows::file_descriptor55 file_descriptor(const std::wstring & path, mode_t mode = read_write) 56 : file_descriptor(path.c_str(), mode) {} 57 file_descriptorboost::process::detail::windows::file_descriptor58 file_descriptor(const char* path, mode_t mode = read_write) 59 #if defined(BOOST_NO_ANSI_APIS) 60 : file_descriptor(std::string(path), mode) 61 #else 62 : _handle( 63 ::boost::winapi::create_file( 64 path, 65 desired_access(mode), 66 ::boost::winapi::FILE_SHARE_READ_ | 67 ::boost::winapi::FILE_SHARE_WRITE_, 68 nullptr, 69 ::boost::winapi::OPEN_ALWAYS_, 70 71 ::boost::winapi::FILE_ATTRIBUTE_NORMAL_, 72 nullptr 73 )) 74 #endif 75 { 76 } file_descriptorboost::process::detail::windows::file_descriptor77 file_descriptor(const wchar_t * path, mode_t mode = read_write) 78 : _handle( 79 ::boost::winapi::create_file( 80 path, 81 desired_access(mode), 82 ::boost::winapi::FILE_SHARE_READ_ | 83 ::boost::winapi::FILE_SHARE_WRITE_, 84 nullptr, 85 ::boost::winapi::OPEN_ALWAYS_, 86 87 ::boost::winapi::FILE_ATTRIBUTE_NORMAL_, 88 nullptr 89 )) 90 { 91 92 } 93 file_descriptor(const file_descriptor & ) = delete; file_descriptorboost::process::detail::windows::file_descriptor94 file_descriptor(file_descriptor &&other) 95 : _handle( boost::exchange(other._handle, ::boost::winapi::INVALID_HANDLE_VALUE_) ) 96 { 97 } 98 99 file_descriptor& operator=(const file_descriptor & ) = delete; operator =boost::process::detail::windows::file_descriptor100 file_descriptor& operator=(file_descriptor &&other) 101 { 102 if (_handle != ::boost::winapi::INVALID_HANDLE_VALUE_) 103 ::boost::winapi::CloseHandle(_handle); 104 _handle = boost::exchange(other._handle, ::boost::winapi::INVALID_HANDLE_VALUE_); 105 } 106 ~file_descriptorboost::process::detail::windows::file_descriptor107 ~file_descriptor() 108 { 109 if (_handle != ::boost::winapi::INVALID_HANDLE_VALUE_) 110 ::boost::winapi::CloseHandle(_handle); 111 } 112 handleboost::process::detail::windows::file_descriptor113 ::boost::winapi::HANDLE_ handle() const { return _handle;} 114 115 private: 116 ::boost::winapi::HANDLE_ _handle = ::boost::winapi::INVALID_HANDLE_VALUE_; 117 }; 118 119 }}}} 120 121 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */ 122