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 
15 namespace boost { namespace process { namespace detail { namespace windows {
16 
17 struct file_descriptor
18 {
19     enum mode_t
20     {
21         read  = 1,
22         write = 2,
23         read_write = 3
24     };
desired_accessboost::process::detail::windows::file_descriptor25     static ::boost::winapi::DWORD_ desired_access(mode_t mode)
26     {
27         switch(mode)
28         {
29         case read:
30             return ::boost::winapi::GENERIC_READ_;
31         case write:
32             return ::boost::winapi::GENERIC_WRITE_;
33         case read_write:
34             return ::boost::winapi::GENERIC_READ_
35                  | ::boost::winapi::GENERIC_WRITE_;
36         default:
37             return 0u;
38         }
39     }
40 
41     file_descriptor() = default;
file_descriptorboost::process::detail::windows::file_descriptor42     file_descriptor(const boost::filesystem::path& p, mode_t mode = read_write)
43         : file_descriptor(p.native(), mode)
44     {
45     }
46 
file_descriptorboost::process::detail::windows::file_descriptor47     file_descriptor(const std::string & path , mode_t mode = read_write)
48 #if defined(BOOST_NO_ANSI_APIS)
49         : file_descriptor(::boost::process::detail::convert(path), mode)
50 #else
51         : file_descriptor(path.c_str(), mode)
52 #endif
53     {}
file_descriptorboost::process::detail::windows::file_descriptor54     file_descriptor(const std::wstring & path, mode_t mode = read_write)
55         : file_descriptor(path.c_str(), mode) {}
56 
file_descriptorboost::process::detail::windows::file_descriptor57     file_descriptor(const char*    path, mode_t mode = read_write)
58 #if defined(BOOST_NO_ANSI_APIS)
59         : file_descriptor(std::string(path), mode)
60 #else
61         : _handle(
62                 ::boost::winapi::create_file(
63                         path,
64                         desired_access(mode),
65                         ::boost::winapi::FILE_SHARE_READ_ |
66                         ::boost::winapi::FILE_SHARE_WRITE_,
67                         nullptr,
68                         ::boost::winapi::OPEN_ALWAYS_,
69 
70                         ::boost::winapi::FILE_ATTRIBUTE_NORMAL_,
71                         nullptr
72                 ))
73 #endif
74     {
75     }
file_descriptorboost::process::detail::windows::file_descriptor76     file_descriptor(const wchar_t * path, mode_t mode = read_write)
77         : _handle(
78             ::boost::winapi::create_file(
79                     path,
80                     desired_access(mode),
81                     ::boost::winapi::FILE_SHARE_READ_ |
82                     ::boost::winapi::FILE_SHARE_WRITE_,
83                     nullptr,
84                     ::boost::winapi::OPEN_ALWAYS_,
85 
86                     ::boost::winapi::FILE_ATTRIBUTE_NORMAL_,
87                     nullptr
88             ))
89 {
90 
91 }
92     file_descriptor(const file_descriptor & ) = delete;
93     file_descriptor(file_descriptor && ) = default;
94 
95     file_descriptor& operator=(const file_descriptor & ) = delete;
96     file_descriptor& operator=(file_descriptor && ) = default;
97 
~file_descriptorboost::process::detail::windows::file_descriptor98     ~file_descriptor()
99     {
100         if (_handle != ::boost::winapi::INVALID_HANDLE_VALUE_)
101             ::boost::winapi::CloseHandle(_handle);
102     }
103 
handleboost::process::detail::windows::file_descriptor104     ::boost::winapi::HANDLE_ handle() const { return _handle;}
105 
106 private:
107     ::boost::winapi::HANDLE_ _handle = ::boost::winapi::INVALID_HANDLE_VALUE_;
108 };
109 
110 }}}}
111 
112 #endif /* BOOST_PROCESS_DETAIL_WINDOWS_FILE_DESCRIPTOR_HPP_ */
113