Apache Mesos
inherit.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_INTERNAL_WINDOWS_INHERIT_HPP__
14 #define __STOUT_INTERNAL_WINDOWS_INHERIT_HPP__
15 
16 #include <stout/error.hpp>
17 #include <stout/nothing.hpp>
18 #include <stout/try.hpp>
19 #include <stout/windows.hpp>
20 
21 #include <stout/os/int_fd.hpp>
22 
23 #include <processthreadsapi.h>
24 
25 namespace internal {
26 namespace windows {
27 
28 // This function creates `LPPROC_THREAD_ATTRIBUTE_LIST`, which is used
29 // to whitelist handles sent to a child process.
30 typedef _PROC_THREAD_ATTRIBUTE_LIST AttributeList;
32 create_attributes_list_for_handles(const std::vector<HANDLE>& handles)
33 {
34  if (handles.empty()) {
35  return None();
36  }
37 
38  SIZE_T size = 0;
39  BOOL result = ::InitializeProcThreadAttributeList(
40  nullptr, // Pointer to _PROC_THREAD_ATTRIBUTE_LIST. This
41  // parameter can be `nullptr` to determine the buffer
42  // size required to support the specified number of
43  // attributes.
44  1, // Count of attributes to be added to the list.
45  0, // Reserved and must be zero.
46  &size); // Size in bytes required for the attribute list.
47 
48  if (result == FALSE) {
49  if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
50  return WindowsError();
51  }
52  }
53 
54  std::shared_ptr<AttributeList> attribute_list(
55  reinterpret_cast<AttributeList*>(std::malloc(size)),
56  [](AttributeList* p) {
57  // NOTE: This delete API does not return anything, nor can it
58  // fail, so it is safe to call it regardless of the
59  // initialization state of `p`.
60  ::DeleteProcThreadAttributeList(p);
61  std::free(p);
62  });
63 
64  if (attribute_list == nullptr) {
65  // `std::malloc` failed.
66  return WindowsError(ERROR_OUTOFMEMORY);
67  }
68 
69  result =
70  ::InitializeProcThreadAttributeList(attribute_list.get(), 1, 0, &size);
71 
72  if (result == FALSE) {
73  return WindowsError();
74  }
75 
76  result = ::UpdateProcThreadAttribute(
77  attribute_list.get(), // Pointer to list structure.
78  0, // Reserved and must be 0.
79  PROC_THREAD_ATTRIBUTE_HANDLE_LIST, // The attribute key to update in the
80  // attribute list.
81  const_cast<PVOID*>(handles.data()), // Pointer to the attribute value.
82  handles.size() * sizeof(HANDLE), // Size of the attribute value.
83  nullptr, // Reserved and must be `nullptr`.
84  nullptr); // Reserved and must be `nullptr`.
85 
86  if (result == FALSE) {
87  return WindowsError();
88  }
89 
90  return attribute_list;
91 }
92 
93 // This function enables or disables inheritance for a Windows file handle.
94 //
95 // NOTE: By default, handles on Windows are not inheritable, so this is
96 // primarily used to enable inheritance when passing handles to child processes,
97 // and subsequently disable inheritance.
98 inline Try<Nothing> set_inherit(const int_fd& fd, const bool inherit)
99 {
100  const BOOL result = ::SetHandleInformation(
101  fd, HANDLE_FLAG_INHERIT, inherit ? HANDLE_FLAG_INHERIT : 0);
102 
103  if (result == FALSE) {
104  return WindowsError();
105  }
106 
107  return Nothing();
108 }
109 
110 } // namespace windows {
111 } // namespace internal {
112 
113 #endif // __STOUT_INTERNAL_WINDOWS_INHERIT_HPP__
Result< std::shared_ptr< AttributeList > > create_attributes_list_for_handles(const std::vector< HANDLE > &handles)
Definition: inherit.hpp:32
Definition: nothing.hpp:16
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:130
Definition: check.hpp:33
Definition: error.hpp:108
Try< Nothing > set_inherit(const int_fd &fd, const bool inherit)
Definition: inherit.hpp:98
Definition: check.hpp:30
constexpr Handle HANDLE
Definition: ingress.hpp:37
Definition: none.hpp:27
Definition: attributes.hpp:24
_PROC_THREAD_ATTRIBUTE_LIST AttributeList
Definition: inherit.hpp:30
int int_fd
Definition: int_fd.hpp:35