OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <process.h> | 5 #include <process.h> |
6 | 6 |
7 #include "bin/builtin.h" | 7 #include "bin/builtin.h" |
8 #include "bin/globals.h" | 8 #include "bin/globals.h" |
9 #include "bin/process.h" | 9 #include "bin/process.h" |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 } | 66 } |
67 delete current; | 67 delete current; |
68 return; | 68 return; |
69 } | 69 } |
70 prev = current; | 70 prev = current; |
71 current = current->next(); | 71 current = current->next(); |
72 } | 72 } |
73 } | 73 } |
74 | 74 |
75 | 75 |
76 // Types of pipes to create. | |
77 enum NamedPipeType { | |
78 kInheritRead, | |
79 kInheritWrite, | |
80 kInheritNone | |
81 }; | |
82 | |
83 | |
76 // Create a pipe for communicating with a new process. The handles array | 84 // Create a pipe for communicating with a new process. The handles array |
77 // will contain the read and write ends of the pipe. Based on the is_input | 85 // will contain the read and write ends of the pipe. Based on the type |
78 // argument either the read or the write end of the handle will be | 86 // one of the handles will be inheritable. |
79 // non-inherited. | 87 // NOTE: If this function returns false the handled might have been allocated |
Mads Ager (google)
2011/10/13 12:40:35
handled -> handles
Søren Gjesse
2011/10/13 13:33:10
Done.
| |
88 // and the caller should make sure to close then in case of an error. | |
Mads Ager (google)
2011/10/13 12:40:35
then -> them
Søren Gjesse
2011/10/13 13:33:10
Done.
| |
80 static bool CreateProcessPipe(HANDLE handles[2], | 89 static bool CreateProcessPipe(HANDLE handles[2], |
81 char* pipe_name, | 90 char* pipe_name, |
82 bool is_input) { | 91 NamedPipeType type) { |
92 // Security attributes describing an inheritable handle. | |
83 SECURITY_ATTRIBUTES security_attributes; | 93 SECURITY_ATTRIBUTES security_attributes; |
84 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); | 94 security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); |
85 security_attributes.bInheritHandle = TRUE; | 95 security_attributes.bInheritHandle = TRUE; |
86 security_attributes.lpSecurityDescriptor = NULL; | 96 security_attributes.lpSecurityDescriptor = NULL; |
87 if (is_input) { | 97 |
98 if (type == kInheritRead) { | |
88 handles[kWriteHandle] = | 99 handles[kWriteHandle] = |
89 CreateNamedPipe(pipe_name, | 100 CreateNamedPipe(pipe_name, |
90 PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED, | 101 PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED, |
91 PIPE_TYPE_BYTE | PIPE_WAIT, | 102 PIPE_TYPE_BYTE | PIPE_WAIT, |
92 1, // Number of pipes | 103 1, // Number of pipes |
93 1024, // Out buffer size | 104 1024, // Out buffer size |
94 1024, // In buffer size | 105 1024, // In buffer size |
95 0, // Timeout in ms | 106 0, // Timeout in ms |
96 NULL); | 107 NULL); |
97 | 108 |
98 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { | 109 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { |
99 fprintf(stderr, "CreateNamedPipe failed %d\n", GetLastError()); | 110 fprintf(stderr, "CreateNamedPipe failed %d\n", GetLastError()); |
100 return false; | 111 return false; |
101 } | 112 } |
102 | 113 |
103 handles[kReadHandle] = | 114 handles[kReadHandle] = |
104 CreateFile(pipe_name, | 115 CreateFile(pipe_name, |
105 GENERIC_READ, | 116 GENERIC_READ, |
106 0, | 117 0, |
107 &security_attributes, | 118 &security_attributes, |
108 OPEN_EXISTING, | 119 OPEN_EXISTING, |
109 FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED, | 120 FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED, |
110 NULL); | 121 NULL); |
111 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { | 122 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { |
112 fprintf(stderr, "CreateFile failed %d\n", GetLastError()); | 123 fprintf(stderr, "CreateFile failed %d\n", GetLastError()); |
113 return false; | 124 return false; |
114 } | 125 } |
115 } else { | 126 } else if (type == kInheritWrite) { |
Mads Ager (google)
2011/10/13 12:40:35
InheritWrite and InheritNone are identical except
Søren Gjesse
2011/10/13 13:33:10
Combined the two and used a conditional for the se
| |
116 handles[kReadHandle] = | 127 handles[kReadHandle] = |
117 CreateNamedPipe(pipe_name, | 128 CreateNamedPipe(pipe_name, |
118 PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, | 129 PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, |
119 PIPE_TYPE_BYTE | PIPE_WAIT, | 130 PIPE_TYPE_BYTE | PIPE_WAIT, |
120 1, // Number of pipes | 131 1, // Number of pipes |
121 1024, // Out buffer size | 132 1024, // Out buffer size |
122 1024, // In buffer size | 133 1024, // In buffer size |
123 0, // Timeout in ms | 134 0, // Timeout in ms |
124 NULL); | 135 NULL); |
125 | 136 |
126 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { | 137 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { |
127 fprintf(stderr, "CreateNamedPipe failed %d\n", GetLastError()); | 138 fprintf(stderr, "CreateNamedPipe failed %d\n", GetLastError()); |
128 return false; | 139 return false; |
129 } | 140 } |
130 | 141 |
131 handles[kWriteHandle] = | 142 handles[kWriteHandle] = |
132 CreateFile(pipe_name, | 143 CreateFile(pipe_name, |
133 GENERIC_WRITE, | 144 GENERIC_WRITE, |
134 0, | 145 0, |
135 &security_attributes, | 146 &security_attributes, |
136 OPEN_EXISTING, | 147 OPEN_EXISTING, |
137 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED, | 148 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED, |
138 NULL); | 149 NULL); |
139 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { | 150 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { |
140 fprintf(stderr, "CreateFile failed %d\n", GetLastError()); | 151 fprintf(stderr, "CreateFile failed %d\n", GetLastError()); |
141 return false; | 152 return false; |
142 } | 153 } |
154 } else { | |
155 ASSERT(type == kInheritNone); | |
156 handles[kReadHandle] = | |
157 CreateNamedPipe(pipe_name, | |
158 PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, | |
159 PIPE_TYPE_BYTE | PIPE_WAIT, | |
160 1, // Number of pipes | |
161 1024, // Out buffer size | |
162 1024, // In buffer size | |
163 0, // Timeout in ms | |
164 NULL); | |
165 | |
166 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { | |
167 fprintf(stderr, "CreateNamedPipe failed %d\n", GetLastError()); | |
168 return false; | |
169 } | |
170 | |
171 handles[kWriteHandle] = | |
172 CreateFile(pipe_name, | |
173 GENERIC_WRITE, | |
174 0, | |
175 NULL, | |
176 OPEN_EXISTING, | |
177 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED, | |
178 NULL); | |
179 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { | |
180 fprintf(stderr, "CreateFile failed %d\n", GetLastError()); | |
181 return false; | |
182 } | |
143 } | 183 } |
144 return true; | 184 return true; |
145 } | 185 } |
146 | 186 |
147 | 187 |
148 static void CloseProcessPipe(HANDLE handles[2]) { | 188 static void CloseProcessPipe(HANDLE handles[2]) { |
149 for (int i = kReadHandle; i < kWriteHandle; i++) { | 189 for (int i = kReadHandle; i < kWriteHandle; i++) { |
150 if (handles[i] != INVALID_HANDLE_VALUE) { | 190 if (handles[i] != INVALID_HANDLE_VALUE) { |
151 if (!CloseHandle(handles[i])) { | 191 if (!CloseHandle(handles[i])) { |
152 fprintf(stderr, "CloseHandle failed %d\n", GetLastError()); | 192 fprintf(stderr, "CloseHandle failed %d\n", GetLastError()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 241 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
202 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; | 242 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; |
203 // TODO(sgjesse): Find a better way of generating unique pipe names | 243 // TODO(sgjesse): Find a better way of generating unique pipe names |
204 // (e.g. UUID). | 244 // (e.g. UUID). |
205 DWORD current_pid = GetCurrentProcessId(); | 245 DWORD current_pid = GetCurrentProcessId(); |
206 static int pipe_id = 0; | 246 static int pipe_id = 0; |
207 char pipe_name[80]; | 247 char pipe_name[80]; |
208 pipe_id++; | 248 pipe_id++; |
209 snprintf(pipe_name, sizeof(pipe_name), | 249 snprintf(pipe_name, sizeof(pipe_name), |
210 "\\\\.\\Pipe\\dart%d_%d_1", current_pid, pipe_id); | 250 "\\\\.\\Pipe\\dart%d_%d_1", current_pid, pipe_id); |
211 if (!CreateProcessPipe(stdin_handles, pipe_name, true)) { | 251 if (!CreateProcessPipe(stdin_handles, pipe_name, kInheritRead)) { |
212 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 252 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
213 CloseProcessPipe(stdin_handles); | 253 CloseProcessPipe(stdin_handles); |
Mads Ager (google)
2011/10/13 12:40:35
Can't you abstract all of these closing parts into
Søren Gjesse
2011/10/13 13:33:10
Done.
| |
214 return error_code; | 254 return error_code; |
215 } | 255 } |
216 snprintf(pipe_name, sizeof(pipe_name), | 256 snprintf(pipe_name, sizeof(pipe_name), |
217 "\\\\.\\Pipe\\dart%d_%d_2", current_pid, pipe_id); | 257 "\\\\.\\Pipe\\dart%d_%d_2", current_pid, pipe_id); |
218 if (!CreateProcessPipe(stdout_handles, pipe_name, false)) { | 258 if (!CreateProcessPipe(stdout_handles, pipe_name, kInheritWrite)) { |
219 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 259 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
220 CloseProcessPipe(stdin_handles); | 260 CloseProcessPipe(stdin_handles); |
221 CloseProcessPipe(stdout_handles); | 261 CloseProcessPipe(stdout_handles); |
222 return error_code; | 262 return error_code; |
223 } | 263 } |
224 snprintf(pipe_name, sizeof(pipe_name), | 264 snprintf(pipe_name, sizeof(pipe_name), |
225 "\\\\.\\Pipe\\dart%d_%d_3", current_pid, pipe_id); | 265 "\\\\.\\Pipe\\dart%d_%d_3", current_pid, pipe_id); |
226 if (!CreateProcessPipe(stderr_handles, pipe_name, false)) { | 266 if (!CreateProcessPipe(stderr_handles, pipe_name, kInheritWrite)) { |
227 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 267 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
228 CloseProcessPipe(stdin_handles); | 268 CloseProcessPipe(stdin_handles); |
229 CloseProcessPipe(stdout_handles); | 269 CloseProcessPipe(stdout_handles); |
230 CloseProcessPipe(stderr_handles); | 270 CloseProcessPipe(stderr_handles); |
231 return error_code; | 271 return error_code; |
232 } | 272 } |
233 snprintf(pipe_name, sizeof(pipe_name), | 273 snprintf(pipe_name, sizeof(pipe_name), |
234 "\\\\.\\Pipe\\dart%d_%d_4", current_pid, pipe_id); | 274 "\\\\.\\Pipe\\dart%d_%d_4", current_pid, pipe_id); |
235 if (!CreateProcessPipe(exit_handles, pipe_name, false)) { | 275 if (!CreateProcessPipe(exit_handles, pipe_name, kInheritNone)) { |
Mads Ager (google)
2011/10/13 12:40:35
kDontInheritWrite?
Or maybe kReadInherit, kWriteI
Søren Gjesse
2011/10/13 13:33:10
The pipe is always created with both read and writ
| |
236 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); | 276 int error_code = SetOsErrorMessage(os_error_message, os_error_message_len); |
237 CloseProcessPipe(stdin_handles); | 277 CloseProcessPipe(stdin_handles); |
238 CloseProcessPipe(stdout_handles); | 278 CloseProcessPipe(stdout_handles); |
239 CloseProcessPipe(stderr_handles); | 279 CloseProcessPipe(stderr_handles); |
240 CloseProcessPipe(exit_handles); | 280 CloseProcessPipe(exit_handles); |
241 return error_code; | 281 return error_code; |
242 } | 282 } |
243 | 283 |
244 // Setup info structures. | 284 // Setup info structures. |
245 STARTUPINFO startup_info; | 285 STARTUPINFO startup_info; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 return false; | 395 return false; |
356 } | 396 } |
357 } | 397 } |
358 return true; | 398 return true; |
359 } | 399 } |
360 | 400 |
361 | 401 |
362 void Process::Exit(intptr_t id) { | 402 void Process::Exit(intptr_t id) { |
363 RemoveProcess(id); | 403 RemoveProcess(id); |
364 } | 404 } |
OLD | NEW |