OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 #ifndef CRASHPAD_TEST_WIN_WIN_CHILD_PROCESS_H_ | |
16 #define CRASHPAD_TEST_WIN_WIN_CHILD_PROCESS_H_ | |
17 | |
18 #include "base/basictypes.h" | |
19 #include "base/memory/scoped_ptr.h" | |
20 #include "util/file/file_io.h" | |
21 #include "util/win/scoped_handle.h" | |
22 | |
23 namespace crashpad { | |
24 namespace test { | |
25 | |
26 //! \brief Facilitates the launching of child processes from unit tests. | |
27 class WinChildProcess { | |
28 public: | |
29 //! \brief Groups handles used to communicate with, observe, and manage a | |
30 //! child process. | |
31 struct Handles { | |
32 //! \brief A handle to read from an anonymous pipe shared with the child | |
33 //! process. | |
34 ScopedFileHANDLE read; | |
35 //! \brief A handle to write to an anonymous pipe shared with the child | |
36 //! process. | |
37 ScopedFileHANDLE write; | |
38 //! \brief A handle to the child process. | |
39 ScopedKernelHANDLE process; | |
40 }; | |
41 | |
42 WinChildProcess(); | |
43 virtual ~WinChildProcess() {} | |
44 | |
45 //! \brief Returns true if the current process is a child process. | |
46 static bool IsChildProcess(); | |
47 | |
48 //! \brief Runs the child process defined by T if the current process is a | |
49 //! child process; does not return in that case. Otherwise, returns. | |
50 template <class T> | |
51 static void EntryPoint() { | |
52 if (IsChildProcess()) { | |
53 T child_process; | |
54 // TODO(erikwright) force the client to subclass ChildProcess. Otherwise | |
scottmg
2015/06/25 04:13:24
It's going to have to implement Run(), right? I do
erikwright (departed)
2015/06/25 14:36:02
The TODO was out-of-date, sorry.
The point is tha
| |
55 // the pipe handshake might not occur, leading to a hang. | |
56 // TODO(erikwright): Use some form of static assert that gives a clear | |
scottmg
2015/06/25 04:13:24
This second TODO isn't really actionable, so just
erikwright (departed)
2015/06/25 14:36:02
Done.
| |
57 // error message. | |
58 static_cast<WinChildProcess*>(&child_process)->Run(); | |
59 exit(0); | |
scottmg
2015/06/25 04:13:24
The existing children (mostly?) do an exit(somethi
erikwright (departed)
2015/06/25 14:36:02
I would be more inclined to have Run() return an i
| |
60 } | |
61 } | |
62 | |
63 //! \brief Launches a child process and returns the Handles for that process. | |
64 //! The process is guaranteed to be executing by the time this method | |
65 //! returns. Returns null and logs a GTest failure in case of failure. | |
66 static scoped_ptr<Handles> Launch(); | |
67 | |
68 protected: | |
69 //! \brief Returns a handle to read from an anonymous pipe shared with the | |
70 //! parent process. | |
71 //! | |
72 //! It is an error to call this after CloseReadPipe() has been called. | |
73 //! | |
74 //! \return The read pipe's file handle. | |
75 FileHandle ReadPipeHandle() const; | |
76 | |
77 //! \brief Returns a handle to write to an anonymous pipe shared with the | |
78 //! parent process. | |
79 //! | |
80 //! It is an error to call this after CloseWritePipe() has been called. | |
81 //! | |
82 //! \return The write pipe's file handle. | |
83 FileHandle WritePipeHandle() const; | |
84 | |
85 //! \brief Closes the read pipe. | |
86 //! | |
87 //! ReadPipeHandle() must not be called after this. | |
88 void CloseReadPipe(); | |
89 | |
90 //! \brief Closes the write pipe. | |
91 //! | |
92 //! An attempt to read from the read pipe in the parent process will indicate | |
93 //! end-of-file. WritePipeHandle() must not be called after this. | |
94 void CloseWritePipe(); | |
95 | |
96 private: | |
97 //! \brief The subclass-provided child routine. | |
98 //! | |
99 //! Subclasses must implement this method to define how the child operates. | |
100 //! Subclasses may exit with a failure status by using `LOG(FATAL)`, | |
101 //! `abort()`, or similar. They may exit cleanly by returning from this | |
102 //! method. It is up to the client to observe and interpret the child's exit | |
103 //! code. | |
104 virtual void Run() = 0; | |
105 | |
106 ScopedFileHANDLE pipe_read_; | |
107 ScopedFileHANDLE pipe_write_; | |
108 | |
109 DISALLOW_COPY_AND_ASSIGN(WinChildProcess); | |
110 }; | |
111 | |
112 } // namespace test | |
113 } // namespace crashpad | |
114 | |
115 #endif // CRASHPAD_TEST_WIN_WIN_CHILD_PROCESS_H_ | |
OLD | NEW |