Chromium Code Reviews| 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 |