Apache Mesos
subprocess_windows.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 __PROCESS_WINDOWS_SUBPROCESS_HPP__
14 #define __PROCESS_WINDOWS_SUBPROCESS_HPP__
15 
16 #include <signal.h>
17 
18 #include <string>
19 #include <tuple>
20 
21 #include <glog/logging.h>
22 
23 #include <process/subprocess.hpp>
24 
25 #include <stout/error.hpp>
26 #include <stout/foreach.hpp>
27 #include <stout/hashset.hpp>
28 #include <stout/option.hpp>
29 #include <stout/os.hpp>
30 #include <stout/os/shell.hpp>
31 #include <stout/try.hpp>
32 #include <stout/windows.hpp>
33 
34 #include <stout/os/close.hpp>
35 #include <stout/os/environment.hpp>
36 
37 #include <userEnv.h>
38 
39 namespace process {
40 namespace internal {
41 
42 // NOTE: We are expecting that components of `argv` that need to be quoted
43 // (for example, paths with spaces in them like `C:\"Program Files"\foo.exe`)
44 // to have been already quoted correctly before we generate `command`.
45 // Incorrectly-quoted command arguments will probably lead the child process
46 // to terminate with an error. See also NOTE on `process::subprocess`.
48  const std::string& path,
49  const std::vector<std::string>& argv,
50  const Option<std::map<std::string, std::string>>& environment,
51  const std::vector<Subprocess::ParentHook>& parent_hooks,
52  const InputFileDescriptors stdinfds,
53  const OutputFileDescriptors stdoutfds,
54  const OutputFileDescriptors stderrfds)
55 {
58  path,
59  argv,
61  true, // Create suspended.
62  std::make_tuple(stdinfds.read, stdoutfds.write, stderrfds.write));
63 
64  if (process_data.isError()) {
65  return process_data;
66  }
67 
68  // Run the parent hooks.
69  const pid_t pid = process_data.get().pid;
70  foreach (const Subprocess::ParentHook& hook, parent_hooks) {
71  Try<Nothing> parentSetup = hook.parent_setup(pid);
72 
73  // If the hook callback fails, we shouldn't proceed with the
74  // execution and hence the child process should be killed.
75  if (parentSetup.isError()) {
76  // Attempt to kill the process. Since it is still in suspended state, we
77  // do not need to kill any descendents. We also can't use `os::kill_job`
78  // because this process is not in a Job Object unless one of the parent
79  // hooks added it.
80  ::TerminateProcess(process_data.get().process_handle.get_handle(), 1);
81 
82  return Error(
83  "Failed to execute Parent Hook in child '" + stringify(pid) +
84  "' with command '" + stringify(argv) + "': " +
85  parentSetup.error());
86  }
87  }
88 
89  // Start child process.
90  if (::ResumeThread(process_data.get().thread_handle.get_handle()) == -1) {
91  return WindowsError(
92  "Failed to resume child process with command '" +
93  stringify(argv) + "'");
94  }
95 
96  return process_data;
97 }
98 
99 } // namespace internal {
100 } // namespace process {
101 
102 #endif // __PROCESS_WINDOWS_SUBPROCESS_HPP__
Definition: errorbase.hpp:35
Definition: option.hpp:28
HANDLE get_handle() const
Definition: windows.hpp:96
Definition: try.hpp:34
Definition: error.hpp:106
int_fd read
Definition: subprocess.hpp:75
For output file descriptors a child writes to the write file descriptor and a parent may read from th...
Definition: subprocess.hpp:88
Try<::internal::windows::ProcessData > createChildProcess(const std::string &path, const std::vector< std::string > &argv, const Option< std::map< std::string, std::string >> &environment, const std::vector< Subprocess::ParentHook > &parent_hooks, const InputFileDescriptors stdinfds, const OutputFileDescriptors stdoutfds, const OutputFileDescriptors stderrfds)
Definition: subprocess_windows.hpp:47
Environment * environment
DWORD pid_t
Definition: windows.hpp:187
int_fd write
Definition: subprocess.hpp:91
SharedHandle process_handle
Definition: shell.hpp:212
SharedHandle thread_handle
Definition: shell.hpp:213
For input file descriptors a child reads from the read file descriptor and a parent may write to the ...
Definition: subprocess.hpp:73
static Try error(const E &e)
Definition: try.hpp:42
const lambda::function< Try< Nothing >pid_t)> parent_setup
The callback that must be specified for execution after the child has been cloned, but before it starts executing the new process.
Definition: subprocess.hpp:162
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
bool isError() const
Definition: try.hpp:71
pid_t pid
Definition: shell.hpp:214
A hook can be passed to a subprocess call.
Definition: subprocess.hpp:151
std::string stringify(int flags)
const T & get() const
Definition: try.hpp:73
Try< ProcessData > create_process(const std::string &command, const std::vector< std::string > &argv, const Option< std::map< std::string, std::string >> &environment, const bool create_suspended=false, const Option< std::tuple< int_fd, int_fd, int_fd >> pipes=None())
Definition: shell.hpp:233