Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(404)

Side by Side Diff: runtime/bin/process_win.cc

Issue 2480793002: clang-format runtime/bin (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/bin/process_unsupported.cc ('k') | runtime/bin/reference_counting.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #if !defined(DART_IO_DISABLED) 5 #if !defined(DART_IO_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if defined(TARGET_OS_WINDOWS) 8 #if defined(TARGET_OS_WINDOWS)
9 9
10 #include "bin/process.h" 10 #include "bin/process.h"
(...skipping 27 matching lines...) Expand all
38 // ProcessInfoList. 38 // ProcessInfoList.
39 class ProcessInfo { 39 class ProcessInfo {
40 public: 40 public:
41 ProcessInfo(DWORD process_id, 41 ProcessInfo(DWORD process_id,
42 HANDLE process_handle, 42 HANDLE process_handle,
43 HANDLE wait_handle, 43 HANDLE wait_handle,
44 HANDLE exit_pipe) 44 HANDLE exit_pipe)
45 : process_id_(process_id), 45 : process_id_(process_id),
46 process_handle_(process_handle), 46 process_handle_(process_handle),
47 wait_handle_(wait_handle), 47 wait_handle_(wait_handle),
48 exit_pipe_(exit_pipe) { } 48 exit_pipe_(exit_pipe) {}
49 49
50 ~ProcessInfo() { 50 ~ProcessInfo() {
51 BOOL success = CloseHandle(process_handle_); 51 BOOL success = CloseHandle(process_handle_);
52 if (!success) { 52 if (!success) {
53 FATAL("Failed to close process handle"); 53 FATAL("Failed to close process handle");
54 } 54 }
55 success = CloseHandle(exit_pipe_); 55 success = CloseHandle(exit_pipe_);
56 if (!success) { 56 if (!success) {
57 FATAL("Failed to close process exit code pipe"); 57 FATAL("Failed to close process exit code pipe");
58 } 58 }
(...skipping 28 matching lines...) Expand all
87 class ProcessInfoList { 87 class ProcessInfoList {
88 public: 88 public:
89 static void AddProcess(DWORD pid, HANDLE handle, HANDLE pipe) { 89 static void AddProcess(DWORD pid, HANDLE handle, HANDLE pipe) {
90 // Register a callback to extract the exit code, when the process 90 // Register a callback to extract the exit code, when the process
91 // is signaled. The callback runs in a independent thread from the OS pool. 91 // is signaled. The callback runs in a independent thread from the OS pool.
92 // Because the callback depends on the process list containing 92 // Because the callback depends on the process list containing
93 // the process, lock the mutex until the process is added to the list. 93 // the process, lock the mutex until the process is added to the list.
94 MutexLocker locker(mutex_); 94 MutexLocker locker(mutex_);
95 HANDLE wait_handle = INVALID_HANDLE_VALUE; 95 HANDLE wait_handle = INVALID_HANDLE_VALUE;
96 BOOL success = RegisterWaitForSingleObject( 96 BOOL success = RegisterWaitForSingleObject(
97 &wait_handle, 97 &wait_handle, handle, &ExitCodeCallback, reinterpret_cast<void*>(pid),
98 handle, 98 INFINITE, WT_EXECUTEONLYONCE);
99 &ExitCodeCallback,
100 reinterpret_cast<void*>(pid),
101 INFINITE,
102 WT_EXECUTEONLYONCE);
103 if (!success) { 99 if (!success) {
104 FATAL("Failed to register exit code wait operation."); 100 FATAL("Failed to register exit code wait operation.");
105 } 101 }
106 ProcessInfo* info = new ProcessInfo(pid, handle, wait_handle, pipe); 102 ProcessInfo* info = new ProcessInfo(pid, handle, wait_handle, pipe);
107 // Mutate the process list under the mutex. 103 // Mutate the process list under the mutex.
108 info->set_next(active_processes_); 104 info->set_next(active_processes_);
109 active_processes_ = info; 105 active_processes_ = info;
110 } 106 }
111 107
112 static bool LookupProcess(DWORD pid, 108 static bool LookupProcess(DWORD pid,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 int exit_code; 166 int exit_code;
171 ok = GetExitCodeProcess(handle, reinterpret_cast<DWORD*>(&exit_code)); 167 ok = GetExitCodeProcess(handle, reinterpret_cast<DWORD*>(&exit_code));
172 if (!ok) { 168 if (!ok) {
173 FATAL1("GetExitCodeProcess failed %d\n", GetLastError()); 169 FATAL1("GetExitCodeProcess failed %d\n", GetLastError());
174 } 170 }
175 int negative = 0; 171 int negative = 0;
176 if (exit_code < 0) { 172 if (exit_code < 0) {
177 exit_code = abs(exit_code); 173 exit_code = abs(exit_code);
178 negative = 1; 174 negative = 1;
179 } 175 }
180 int message[2] = { exit_code, negative }; 176 int message[2] = {exit_code, negative};
181 DWORD written; 177 DWORD written;
182 ok = WriteFile(exit_pipe, message, sizeof(message), &written, NULL); 178 ok = WriteFile(exit_pipe, message, sizeof(message), &written, NULL);
183 // If the process has been closed, the read end of the exit 179 // If the process has been closed, the read end of the exit
184 // pipe has been closed. It is therefore not a problem that 180 // pipe has been closed. It is therefore not a problem that
185 // WriteFile fails with a closed pipe error 181 // WriteFile fails with a closed pipe error
186 // (ERROR_NO_DATA). Other errors should not happen. 182 // (ERROR_NO_DATA). Other errors should not happen.
187 if (ok && (written != sizeof(message))) { 183 if (ok && (written != sizeof(message))) {
188 FATAL("Failed to write entire process exit message"); 184 FATAL("Failed to write entire process exit message");
189 } else if (!ok && (GetLastError() != ERROR_NO_DATA)) { 185 } else if (!ok && (GetLastError() != ERROR_NO_DATA)) {
190 FATAL1("Failed to write exit code: %d", GetLastError()); 186 FATAL1("Failed to write exit code: %d", GetLastError());
(...skipping 12 matching lines...) Expand all
203 DISALLOW_ALLOCATION(); 199 DISALLOW_ALLOCATION();
204 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList); 200 DISALLOW_IMPLICIT_CONSTRUCTORS(ProcessInfoList);
205 }; 201 };
206 202
207 203
208 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 204 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
209 Mutex* ProcessInfoList::mutex_ = new Mutex(); 205 Mutex* ProcessInfoList::mutex_ = new Mutex();
210 206
211 207
212 // Types of pipes to create. 208 // Types of pipes to create.
213 enum NamedPipeType { 209 enum NamedPipeType { kInheritRead, kInheritWrite, kInheritNone };
214 kInheritRead,
215 kInheritWrite,
216 kInheritNone
217 };
218 210
219 211
220 // Create a pipe for communicating with a new process. The handles array 212 // Create a pipe for communicating with a new process. The handles array
221 // will contain the read and write ends of the pipe. Based on the type 213 // will contain the read and write ends of the pipe. Based on the type
222 // one of the handles will be inheritable. 214 // one of the handles will be inheritable.
223 // NOTE: If this function returns false the handles might have been allocated 215 // NOTE: If this function returns false the handles might have been allocated
224 // and the caller should make sure to close them in case of an error. 216 // and the caller should make sure to close them in case of an error.
225 static bool CreateProcessPipe(HANDLE handles[2], 217 static bool CreateProcessPipe(HANDLE handles[2],
226 wchar_t* pipe_name, 218 wchar_t* pipe_name,
227 NamedPipeType type) { 219 NamedPipeType type) {
228 // Security attributes describing an inheritable handle. 220 // Security attributes describing an inheritable handle.
229 SECURITY_ATTRIBUTES inherit_handle; 221 SECURITY_ATTRIBUTES inherit_handle;
230 inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES); 222 inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES);
231 inherit_handle.bInheritHandle = TRUE; 223 inherit_handle.bInheritHandle = TRUE;
232 inherit_handle.lpSecurityDescriptor = NULL; 224 inherit_handle.lpSecurityDescriptor = NULL;
233 225
234 if (type == kInheritRead) { 226 if (type == kInheritRead) {
235 handles[kWriteHandle] = 227 handles[kWriteHandle] =
236 CreateNamedPipeW(pipe_name, 228 CreateNamedPipeW(pipe_name, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
237 PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
238 PIPE_TYPE_BYTE | PIPE_WAIT, 229 PIPE_TYPE_BYTE | PIPE_WAIT,
239 1, // Number of pipes 230 1, // Number of pipes
240 1024, // Out buffer size 231 1024, // Out buffer size
241 1024, // In buffer size 232 1024, // In buffer size
242 0, // Timeout in ms 233 0, // Timeout in ms
243 NULL); 234 NULL);
244 235
245 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { 236 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
246 Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError()); 237 Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
247 return false; 238 return false;
248 } 239 }
249 240
250 handles[kReadHandle] = 241 handles[kReadHandle] =
251 CreateFileW(pipe_name, 242 CreateFileW(pipe_name, GENERIC_READ, 0, &inherit_handle, OPEN_EXISTING,
252 GENERIC_READ, 243 FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED, NULL);
253 0,
254 &inherit_handle,
255 OPEN_EXISTING,
256 FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
257 NULL);
258 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { 244 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
259 Log::PrintErr("CreateFile failed %d\n", GetLastError()); 245 Log::PrintErr("CreateFile failed %d\n", GetLastError());
260 return false; 246 return false;
261 } 247 }
262 } else { 248 } else {
263 ASSERT((type == kInheritWrite) || (type == kInheritNone)); 249 ASSERT((type == kInheritWrite) || (type == kInheritNone));
264 handles[kReadHandle] = 250 handles[kReadHandle] =
265 CreateNamedPipeW(pipe_name, 251 CreateNamedPipeW(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
266 PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
267 PIPE_TYPE_BYTE | PIPE_WAIT, 252 PIPE_TYPE_BYTE | PIPE_WAIT,
268 1, // Number of pipes 253 1, // Number of pipes
269 1024, // Out buffer size 254 1024, // Out buffer size
270 1024, // In buffer size 255 1024, // In buffer size
271 0, // Timeout in ms 256 0, // Timeout in ms
272 NULL); 257 NULL);
273 258
274 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) { 259 if (handles[kReadHandle] == INVALID_HANDLE_VALUE) {
275 Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError()); 260 Log::PrintErr("CreateNamedPipe failed %d\n", GetLastError());
276 return false; 261 return false;
277 } 262 }
278 263
279 handles[kWriteHandle] = 264 handles[kWriteHandle] = CreateFileW(
280 CreateFileW(pipe_name, 265 pipe_name, GENERIC_WRITE, 0,
281 GENERIC_WRITE, 266 (type == kInheritWrite) ? &inherit_handle : NULL, OPEN_EXISTING,
282 0, 267 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED, NULL);
283 (type == kInheritWrite) ? &inherit_handle : NULL,
284 OPEN_EXISTING,
285 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
286 NULL);
287 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) { 268 if (handles[kWriteHandle] == INVALID_HANDLE_VALUE) {
288 Log::PrintErr("CreateFile failed %d\n", GetLastError()); 269 Log::PrintErr("CreateFile failed %d\n", GetLastError());
289 return false; 270 return false;
290 } 271 }
291 } 272 }
292 return true; 273 return true;
293 } 274 }
294 275
295 276
296 static void CloseProcessPipe(HANDLE handles[2]) { 277 static void CloseProcessPipe(HANDLE handles[2]) {
(...skipping 28 matching lines...) Expand all
325 return error_code; 306 return error_code;
326 } 307 }
327 308
328 309
329 // Open an inheritable handle to NUL. 310 // Open an inheritable handle to NUL.
330 static HANDLE OpenNul() { 311 static HANDLE OpenNul() {
331 SECURITY_ATTRIBUTES inherit_handle; 312 SECURITY_ATTRIBUTES inherit_handle;
332 inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES); 313 inherit_handle.nLength = sizeof(SECURITY_ATTRIBUTES);
333 inherit_handle.bInheritHandle = TRUE; 314 inherit_handle.bInheritHandle = TRUE;
334 inherit_handle.lpSecurityDescriptor = NULL; 315 inherit_handle.lpSecurityDescriptor = NULL;
335 HANDLE nul = CreateFile(L"NUL", 316 HANDLE nul = CreateFile(L"NUL", GENERIC_READ | GENERIC_WRITE, 0,
336 GENERIC_READ | GENERIC_WRITE, 317 &inherit_handle, OPEN_EXISTING, 0, NULL);
337 0,
338 &inherit_handle,
339 OPEN_EXISTING,
340 0,
341 NULL);
342 if (nul == INVALID_HANDLE_VALUE) { 318 if (nul == INVALID_HANDLE_VALUE) {
343 Log::PrintErr("CloseHandle failed %d\n", GetLastError()); 319 Log::PrintErr("CloseHandle failed %d\n", GetLastError());
344 } 320 }
345 return nul; 321 return nul;
346 } 322 }
347 323
348 324
349 typedef BOOL (WINAPI *InitProcThreadAttrListFn)( 325 typedef BOOL(WINAPI* InitProcThreadAttrListFn)(LPPROC_THREAD_ATTRIBUTE_LIST,
350 LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T); 326 DWORD,
327 DWORD,
328 PSIZE_T);
351 329
352 typedef BOOL (WINAPI *UpdateProcThreadAttrFn)( 330 typedef BOOL(WINAPI* UpdateProcThreadAttrFn)(LPPROC_THREAD_ATTRIBUTE_LIST,
353 LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR, 331 DWORD,
354 PVOID, SIZE_T, PVOID, PSIZE_T); 332 DWORD_PTR,
333 PVOID,
334 SIZE_T,
335 PVOID,
336 PSIZE_T);
355 337
356 typedef VOID (WINAPI *DeleteProcThreadAttrListFn)( 338 typedef VOID(WINAPI* DeleteProcThreadAttrListFn)(LPPROC_THREAD_ATTRIBUTE_LIST);
357 LPPROC_THREAD_ATTRIBUTE_LIST);
358 339
359 340
360 static InitProcThreadAttrListFn init_proc_thread_attr_list = NULL; 341 static InitProcThreadAttrListFn init_proc_thread_attr_list = NULL;
361 static UpdateProcThreadAttrFn update_proc_thread_attr = NULL; 342 static UpdateProcThreadAttrFn update_proc_thread_attr = NULL;
362 static DeleteProcThreadAttrListFn delete_proc_thread_attr_list = NULL; 343 static DeleteProcThreadAttrListFn delete_proc_thread_attr_list = NULL;
363 344
364 345
365 static bool EnsureInitialized() { 346 static bool EnsureInitialized() {
366 static bool load_attempted = false; 347 static bool load_attempted = false;
367 static Mutex* mutex = new Mutex(); 348 static Mutex* mutex = new Mutex();
(...skipping 10 matching lines...) Expand all
378 delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>( 359 delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>(
379 GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList")); 360 GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList"));
380 load_attempted = true; 361 load_attempted = true;
381 return (delete_proc_thread_attr_list != NULL); 362 return (delete_proc_thread_attr_list != NULL);
382 } 363 }
383 return (delete_proc_thread_attr_list != NULL); 364 return (delete_proc_thread_attr_list != NULL);
384 } 365 }
385 366
386 367
387 const int kMaxPipeNameSize = 80; 368 const int kMaxPipeNameSize = 80;
388 template<int Count> 369 template <int Count>
389 static int GenerateNames(wchar_t pipe_names[Count][kMaxPipeNameSize]) { 370 static int GenerateNames(wchar_t pipe_names[Count][kMaxPipeNameSize]) {
390 UUID uuid; 371 UUID uuid;
391 RPC_STATUS status = UuidCreateSequential(&uuid); 372 RPC_STATUS status = UuidCreateSequential(&uuid);
392 if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) { 373 if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
393 return status; 374 return status;
394 } 375 }
395 RPC_WSTR uuid_string; 376 RPC_WSTR uuid_string;
396 status = UuidToStringW(&uuid, &uuid_string); 377 status = UuidToStringW(&uuid, &uuid_string);
397 if (status != RPC_S_OK) { 378 if (status != RPC_S_OK) {
398 return status; 379 return status;
399 } 380 }
400 for (int i = 0; i < Count; i++) { 381 for (int i = 0; i < Count; i++) {
401 static const wchar_t* prefix = L"\\\\.\\Pipe\\dart"; 382 static const wchar_t* prefix = L"\\\\.\\Pipe\\dart";
402 _snwprintf(pipe_names[i], 383 _snwprintf(pipe_names[i], kMaxPipeNameSize, L"%s_%s_%d", prefix,
403 kMaxPipeNameSize, 384 uuid_string, i + 1);
404 L"%s_%s_%d", prefix, uuid_string, i + 1);
405 } 385 }
406 status = RpcStringFreeW(&uuid_string); 386 status = RpcStringFreeW(&uuid_string);
407 if (status != RPC_S_OK) { 387 if (status != RPC_S_OK) {
408 return status; 388 return status;
409 } 389 }
410 return 0; 390 return 0;
411 } 391 }
412 392
413 393
414 class ProcessStarter { 394 class ProcessStarter {
(...skipping 28 matching lines...) Expand all
443 stderr_handles_[kWriteHandle] = INVALID_HANDLE_VALUE; 423 stderr_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;
444 exit_handles_[kReadHandle] = INVALID_HANDLE_VALUE; 424 exit_handles_[kReadHandle] = INVALID_HANDLE_VALUE;
445 exit_handles_[kWriteHandle] = INVALID_HANDLE_VALUE; 425 exit_handles_[kWriteHandle] = INVALID_HANDLE_VALUE;
446 426
447 // Transform input strings to system format. 427 // Transform input strings to system format.
448 const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path_); 428 const wchar_t* system_path = StringUtilsWin::Utf8ToWide(path_);
449 wchar_t** system_arguments; 429 wchar_t** system_arguments;
450 system_arguments = reinterpret_cast<wchar_t**>( 430 system_arguments = reinterpret_cast<wchar_t**>(
451 Dart_ScopeAllocate(arguments_length * sizeof(*system_arguments))); 431 Dart_ScopeAllocate(arguments_length * sizeof(*system_arguments)));
452 for (int i = 0; i < arguments_length; i++) { 432 for (int i = 0; i < arguments_length; i++) {
453 system_arguments[i] = StringUtilsWin::Utf8ToWide(arguments[i]); 433 system_arguments[i] = StringUtilsWin::Utf8ToWide(arguments[i]);
454 } 434 }
455 435
456 // Compute command-line length. 436 // Compute command-line length.
457 int command_line_length = wcslen(system_path); 437 int command_line_length = wcslen(system_path);
458 for (int i = 0; i < arguments_length; i++) { 438 for (int i = 0; i < arguments_length; i++) {
459 command_line_length += wcslen(system_arguments[i]); 439 command_line_length += wcslen(system_arguments[i]);
460 } 440 }
461 // Account for null termination and one space per argument. 441 // Account for null termination and one space per argument.
462 command_line_length += arguments_length + 1; 442 command_line_length += arguments_length + 1;
463 443
464 // Put together command-line string. 444 // Put together command-line string.
465 command_line_ = reinterpret_cast<wchar_t*>(Dart_ScopeAllocate( 445 command_line_ = reinterpret_cast<wchar_t*>(
466 command_line_length * sizeof(*command_line_))); 446 Dart_ScopeAllocate(command_line_length * sizeof(*command_line_)));
467 int len = 0; 447 int len = 0;
468 int remaining = command_line_length; 448 int remaining = command_line_length;
469 int written = 449 int written =
470 _snwprintf(command_line_ + len, remaining, L"%s", system_path); 450 _snwprintf(command_line_ + len, remaining, L"%s", system_path);
471 len += written; 451 len += written;
472 remaining -= written; 452 remaining -= written;
473 ASSERT(remaining >= 0); 453 ASSERT(remaining >= 0);
474 for (int i = 0; i < arguments_length; i++) { 454 for (int i = 0; i < arguments_length; i++) {
475 written = _snwprintf( 455 written = _snwprintf(command_line_ + len, remaining, L" %s",
476 command_line_ + len, remaining, L" %s", system_arguments[i]); 456 system_arguments[i]);
477 len += written; 457 len += written;
478 remaining -= written; 458 remaining -= written;
479 ASSERT(remaining >= 0); 459 ASSERT(remaining >= 0);
480 } 460 }
481 461
482 // Create environment block if an environment is supplied. 462 // Create environment block if an environment is supplied.
483 environment_block_ = NULL; 463 environment_block_ = NULL;
484 if (environment != NULL) { 464 if (environment != NULL) {
485 wchar_t** system_environment; 465 wchar_t** system_environment;
486 system_environment = reinterpret_cast<wchar_t**>( 466 system_environment = reinterpret_cast<wchar_t**>(
487 Dart_ScopeAllocate(environment_length * sizeof(*system_environment))); 467 Dart_ScopeAllocate(environment_length * sizeof(*system_environment)));
488 // Convert environment strings to system strings. 468 // Convert environment strings to system strings.
489 for (intptr_t i = 0; i < environment_length; i++) { 469 for (intptr_t i = 0; i < environment_length; i++) {
490 system_environment[i] = StringUtilsWin::Utf8ToWide(environment[i]); 470 system_environment[i] = StringUtilsWin::Utf8ToWide(environment[i]);
491 } 471 }
492 472
493 // An environment block is a sequence of zero-terminated strings 473 // An environment block is a sequence of zero-terminated strings
494 // followed by a block-terminating zero char. 474 // followed by a block-terminating zero char.
495 intptr_t block_size = 1; 475 intptr_t block_size = 1;
496 for (intptr_t i = 0; i < environment_length; i++) { 476 for (intptr_t i = 0; i < environment_length; i++) {
497 block_size += wcslen(system_environment[i]) + 1; 477 block_size += wcslen(system_environment[i]) + 1;
498 } 478 }
499 environment_block_ = reinterpret_cast<wchar_t*>(Dart_ScopeAllocate( 479 environment_block_ = reinterpret_cast<wchar_t*>(
500 block_size * sizeof(*environment_block_))); 480 Dart_ScopeAllocate(block_size * sizeof(*environment_block_)));
501 intptr_t block_index = 0; 481 intptr_t block_index = 0;
502 for (intptr_t i = 0; i < environment_length; i++) { 482 for (intptr_t i = 0; i < environment_length; i++) {
503 intptr_t len = wcslen(system_environment[i]); 483 intptr_t len = wcslen(system_environment[i]);
504 intptr_t result = _snwprintf(environment_block_ + block_index, 484 intptr_t result = _snwprintf(environment_block_ + block_index, len,
505 len, 485 L"%s", system_environment[i]);
506 L"%s",
507 system_environment[i]);
508 ASSERT(result == len); 486 ASSERT(result == len);
509 block_index += len; 487 block_index += len;
510 environment_block_[block_index++] = '\0'; 488 environment_block_[block_index++] = '\0';
511 } 489 }
512 // Block-terminating zero char. 490 // Block-terminating zero char.
513 environment_block_[block_index++] = '\0'; 491 environment_block_[block_index++] = '\0';
514 ASSERT(block_index == block_size); 492 ASSERT(block_index == block_size);
515 } 493 }
516 494
517 system_working_directory_ = NULL; 495 system_working_directory_ = NULL;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { 536 (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
559 return CleanupAndReturnError(); 537 return CleanupAndReturnError();
560 } 538 }
561 attribute_list_ = reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>( 539 attribute_list_ = reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(
562 Dart_ScopeAllocate(size)); 540 Dart_ScopeAllocate(size));
563 ZeroMemory(attribute_list_, size); 541 ZeroMemory(attribute_list_, size);
564 if (!init_proc_thread_attr_list(attribute_list_, 1, 0, &size)) { 542 if (!init_proc_thread_attr_list(attribute_list_, 1, 0, &size)) {
565 return CleanupAndReturnError(); 543 return CleanupAndReturnError();
566 } 544 }
567 static const int kNumInheritedHandles = 3; 545 static const int kNumInheritedHandles = 3;
568 HANDLE inherited_handles[kNumInheritedHandles] = 546 HANDLE inherited_handles[kNumInheritedHandles] = {
569 { stdin_handles_[kReadHandle], 547 stdin_handles_[kReadHandle], stdout_handles_[kWriteHandle],
570 stdout_handles_[kWriteHandle], 548 stderr_handles_[kWriteHandle]};
571 stderr_handles_[kWriteHandle] }; 549 if (!update_proc_thread_attr(
572 if (!update_proc_thread_attr(attribute_list_, 550 attribute_list_, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
573 0, 551 inherited_handles, kNumInheritedHandles * sizeof(HANDLE), NULL,
574 PROC_THREAD_ATTRIBUTE_HANDLE_LIST, 552 NULL)) {
575 inherited_handles,
576 kNumInheritedHandles * sizeof(HANDLE),
577 NULL,
578 NULL)) {
579 return CleanupAndReturnError(); 553 return CleanupAndReturnError();
580 } 554 }
581 startup_info.lpAttributeList = attribute_list_; 555 startup_info.lpAttributeList = attribute_list_;
582 } 556 }
583 557
584 PROCESS_INFORMATION process_info; 558 PROCESS_INFORMATION process_info;
585 ZeroMemory(&process_info, sizeof(process_info)); 559 ZeroMemory(&process_info, sizeof(process_info));
586 560
587 // Create process. 561 // Create process.
588 DWORD creation_flags = 562 DWORD creation_flags =
589 EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT; 563 EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT;
590 if (mode_ != kNormal) { 564 if (mode_ != kNormal) {
591 creation_flags |= DETACHED_PROCESS; 565 creation_flags |= DETACHED_PROCESS;
592 } 566 }
593 BOOL result = CreateProcessW(NULL, // ApplicationName 567 BOOL result = CreateProcessW(
594 command_line_, 568 NULL, // ApplicationName
595 NULL, // ProcessAttributes 569 command_line_,
596 NULL, // ThreadAttributes 570 NULL, // ProcessAttributes
597 TRUE, // InheritHandles 571 NULL, // ThreadAttributes
598 creation_flags, 572 TRUE, // InheritHandles
599 environment_block_, 573 creation_flags, environment_block_, system_working_directory_,
600 system_working_directory_, 574 reinterpret_cast<STARTUPINFOW*>(&startup_info), &process_info);
601 reinterpret_cast<STARTUPINFOW*>(&startup_info),
602 &process_info);
603 575
604 if (result == 0) { 576 if (result == 0) {
605 return CleanupAndReturnError(); 577 return CleanupAndReturnError();
606 } 578 }
607 579
608 CloseHandle(stdin_handles_[kReadHandle]); 580 CloseHandle(stdin_handles_[kReadHandle]);
609 CloseHandle(stdout_handles_[kWriteHandle]); 581 CloseHandle(stdout_handles_[kWriteHandle]);
610 CloseHandle(stderr_handles_[kWriteHandle]); 582 CloseHandle(stderr_handles_[kWriteHandle]);
611 if (mode_ == kNormal) { 583 if (mode_ == kNormal) {
612 ProcessInfoList::AddProcess(process_info.dwProcessId, 584 ProcessInfoList::AddProcess(process_info.dwProcessId,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 if (stderr_handles_[kWriteHandle] == INVALID_HANDLE_VALUE) { 647 if (stderr_handles_[kWriteHandle] == INVALID_HANDLE_VALUE) {
676 return CleanupAndReturnError(); 648 return CleanupAndReturnError();
677 } 649 }
678 } 650 }
679 return 0; 651 return 0;
680 } 652 }
681 653
682 654
683 int CleanupAndReturnError() { 655 int CleanupAndReturnError() {
684 int error_code = SetOsErrorMessage(os_error_message_); 656 int error_code = SetOsErrorMessage(os_error_message_);
685 CloseProcessPipes( 657 CloseProcessPipes(stdin_handles_, stdout_handles_, stderr_handles_,
686 stdin_handles_, stdout_handles_, stderr_handles_, exit_handles_); 658 exit_handles_);
687 return error_code; 659 return error_code;
688 } 660 }
689 661
690 662
691 HANDLE stdin_handles_[2]; 663 HANDLE stdin_handles_[2];
692 HANDLE stdout_handles_[2]; 664 HANDLE stdout_handles_[2];
693 HANDLE stderr_handles_[2]; 665 HANDLE stderr_handles_[2];
694 HANDLE exit_handles_[2]; 666 HANDLE exit_handles_[2];
695 667
696 const wchar_t* system_working_directory_; 668 const wchar_t* system_working_directory_;
(...skipping 23 matching lines...) Expand all
720 const char* working_directory, 692 const char* working_directory,
721 char* environment[], 693 char* environment[],
722 intptr_t environment_length, 694 intptr_t environment_length,
723 ProcessStartMode mode, 695 ProcessStartMode mode,
724 intptr_t* in, 696 intptr_t* in,
725 intptr_t* out, 697 intptr_t* out,
726 intptr_t* err, 698 intptr_t* err,
727 intptr_t* id, 699 intptr_t* id,
728 intptr_t* exit_handler, 700 intptr_t* exit_handler,
729 char** os_error_message) { 701 char** os_error_message) {
730 ProcessStarter starter(path, 702 ProcessStarter starter(path, arguments, arguments_length, working_directory,
731 arguments, 703 environment, environment_length, mode, in, out, err,
732 arguments_length, 704 id, exit_handler, os_error_message);
733 working_directory,
734 environment,
735 environment_length,
736 mode,
737 in,
738 out,
739 err,
740 id,
741 exit_handler,
742 os_error_message);
743 return starter.Start(); 705 return starter.Start();
744 } 706 }
745 707
746 708
747 class BufferList: public BufferListBase { 709 class BufferList : public BufferListBase {
748 public: 710 public:
749 BufferList() : read_pending_(true) { } 711 BufferList() : read_pending_(true) {}
750 712
751 // Indicate that data has been read into the buffer provided to 713 // Indicate that data has been read into the buffer provided to
752 // overlapped read. 714 // overlapped read.
753 void DataIsRead(intptr_t size) { 715 void DataIsRead(intptr_t size) {
754 ASSERT(read_pending_ == true); 716 ASSERT(read_pending_ == true);
755 data_size_ += size; 717 data_size_ += size;
756 free_size_ -= size; 718 free_size_ -= size;
757 ASSERT(free_size_ >= 0); 719 ASSERT(free_size_ >= 0);
758 read_pending_ = false; 720 read_pending_ = false;
759 } 721 }
760 722
761 // The access to the read buffer for overlapped read. 723 // The access to the read buffer for overlapped read.
762 void GetReadBuffer(uint8_t** buffer, intptr_t* size) { 724 void GetReadBuffer(uint8_t** buffer, intptr_t* size) {
763 ASSERT(!read_pending_); 725 ASSERT(!read_pending_);
764 if (free_size_ == 0) { 726 if (free_size_ == 0) {
765 Allocate(); 727 Allocate();
766 } 728 }
767 ASSERT(free_size_ > 0); 729 ASSERT(free_size_ > 0);
768 ASSERT(free_size_ <= kBufferSize); 730 ASSERT(free_size_ <= kBufferSize);
769 *buffer = FreeSpaceAddress(); 731 *buffer = FreeSpaceAddress();
770 *size = free_size_; 732 *size = free_size_;
771 read_pending_ = true; 733 read_pending_ = true;
772 } 734 }
773 735
774 intptr_t GetDataSize() { 736 intptr_t GetDataSize() { return data_size_; }
775 return data_size_;
776 }
777 737
778 uint8_t* GetFirstDataBuffer() { 738 uint8_t* GetFirstDataBuffer() {
779 ASSERT(head_ != NULL); 739 ASSERT(head_ != NULL);
780 ASSERT(head_ == tail_); 740 ASSERT(head_ == tail_);
781 ASSERT(data_size_ <= kBufferSize); 741 ASSERT(data_size_ <= kBufferSize);
782 return head_->data_; 742 return head_->data_;
783 } 743 }
784 744
785 void FreeDataBuffer() { 745 void FreeDataBuffer() { Free(); }
786 Free();
787 }
788 746
789 private: 747 private:
790 bool read_pending_; 748 bool read_pending_;
791 749
792 DISALLOW_COPY_AND_ASSIGN(BufferList); 750 DISALLOW_COPY_AND_ASSIGN(BufferList);
793 }; 751 };
794 752
795 753
796 class OverlappedHandle { 754 class OverlappedHandle {
797 public: 755 public:
798 OverlappedHandle() {} 756 OverlappedHandle() {}
799 757
800 void Init(HANDLE handle, HANDLE event) { 758 void Init(HANDLE handle, HANDLE event) {
801 handle_ = handle; 759 handle_ = handle;
802 event_ = event; 760 event_ = event;
803 ClearOverlapped(); 761 ClearOverlapped();
804 } 762 }
805 763
806 bool HasEvent(HANDLE event) { 764 bool HasEvent(HANDLE event) { return (event_ == event); }
807 return (event_ == event);
808 }
809 765
810 bool Read() { 766 bool Read() {
811 // Get the data read as a result of a completed overlapped operation. 767 // Get the data read as a result of a completed overlapped operation.
812 if (overlapped_.InternalHigh > 0) { 768 if (overlapped_.InternalHigh > 0) {
813 buffer_.DataIsRead(overlapped_.InternalHigh); 769 buffer_.DataIsRead(overlapped_.InternalHigh);
814 } else { 770 } else {
815 buffer_.DataIsRead(0); 771 buffer_.DataIsRead(0);
816 } 772 }
817 773
818 // Keep reading until error or pending operation. 774 // Keep reading until error or pending operation.
819 while (true) { 775 while (true) {
820 ClearOverlapped(); 776 ClearOverlapped();
821 uint8_t* buffer; 777 uint8_t* buffer;
822 intptr_t buffer_size; 778 intptr_t buffer_size;
823 buffer_.GetReadBuffer(&buffer, &buffer_size); 779 buffer_.GetReadBuffer(&buffer, &buffer_size);
824 BOOL ok = ReadFile(handle_, buffer, buffer_size, NULL, &overlapped_); 780 BOOL ok = ReadFile(handle_, buffer, buffer_size, NULL, &overlapped_);
825 if (!ok) { 781 if (!ok) {
826 return (GetLastError() == ERROR_IO_PENDING); 782 return (GetLastError() == ERROR_IO_PENDING);
827 } 783 }
828 buffer_.DataIsRead(overlapped_.InternalHigh); 784 buffer_.DataIsRead(overlapped_.InternalHigh);
829 } 785 }
830 } 786 }
831 787
832 Dart_Handle GetData() { 788 Dart_Handle GetData() { return buffer_.GetData(); }
833 return buffer_.GetData();
834 }
835 789
836 intptr_t GetDataSize() { 790 intptr_t GetDataSize() { return buffer_.GetDataSize(); }
837 return buffer_.GetDataSize();
838 }
839 791
840 uint8_t* GetFirstDataBuffer() { 792 uint8_t* GetFirstDataBuffer() { return buffer_.GetFirstDataBuffer(); }
841 return buffer_.GetFirstDataBuffer();
842 }
843 793
844 void FreeDataBuffer() { 794 void FreeDataBuffer() { return buffer_.FreeDataBuffer(); }
845 return buffer_.FreeDataBuffer();
846 }
847 795
848 void Close() { 796 void Close() {
849 CloseHandle(handle_); 797 CloseHandle(handle_);
850 CloseHandle(event_); 798 CloseHandle(event_);
851 handle_ = INVALID_HANDLE_VALUE; 799 handle_ = INVALID_HANDLE_VALUE;
852 overlapped_.hEvent = INVALID_HANDLE_VALUE; 800 overlapped_.hEvent = INVALID_HANDLE_VALUE;
853 } 801 }
854 802
855 private: 803 private:
856 void ClearOverlapped() { 804 void ClearOverlapped() {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 return true; 897 return true;
950 } 898 }
951 899
952 900
953 bool Process::Kill(intptr_t id, int signal) { 901 bool Process::Kill(intptr_t id, int signal) {
954 USE(signal); // signal is not used on Windows. 902 USE(signal); // signal is not used on Windows.
955 HANDLE process_handle; 903 HANDLE process_handle;
956 HANDLE wait_handle; 904 HANDLE wait_handle;
957 HANDLE exit_pipe; 905 HANDLE exit_pipe;
958 // First check the process info list for the process to get a handle to it. 906 // First check the process info list for the process to get a handle to it.
959 bool success = ProcessInfoList::LookupProcess(id, 907 bool success = ProcessInfoList::LookupProcess(id, &process_handle,
960 &process_handle, 908 &wait_handle, &exit_pipe);
961 &wait_handle,
962 &exit_pipe);
963 // For detached processes we don't have the process registered in the 909 // For detached processes we don't have the process registered in the
964 // process info list. Try to look it up through the OS. 910 // process info list. Try to look it up through the OS.
965 if (!success) { 911 if (!success) {
966 process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, id); 912 process_handle = OpenProcess(PROCESS_TERMINATE, FALSE, id);
967 // The process is already dead. 913 // The process is already dead.
968 if (process_handle == INVALID_HANDLE_VALUE) { 914 if (process_handle == INVALID_HANDLE_VALUE) {
969 return false; 915 return false;
970 } 916 }
971 } 917 }
972 BOOL result = TerminateProcess(process_handle, -1); 918 BOOL result = TerminateProcess(process_handle, -1);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 handled = true; 950 handled = true;
1005 } 951 }
1006 handler = handler->next(); 952 handler = handler->next();
1007 } 953 }
1008 return handled; 954 return handled;
1009 } 955 }
1010 956
1011 957
1012 intptr_t GetWinSignal(intptr_t signal) { 958 intptr_t GetWinSignal(intptr_t signal) {
1013 switch (signal) { 959 switch (signal) {
1014 case kSighup: return CTRL_CLOSE_EVENT; 960 case kSighup:
1015 case kSigint: return CTRL_C_EVENT; 961 return CTRL_CLOSE_EVENT;
962 case kSigint:
963 return CTRL_C_EVENT;
1016 default: 964 default:
1017 return -1; 965 return -1;
1018 } 966 }
1019 } 967 }
1020 968
1021 969
1022 intptr_t Process::SetSignalHandler(intptr_t signal) { 970 intptr_t Process::SetSignalHandler(intptr_t signal) {
1023 signal = GetWinSignal(signal); 971 signal = GetWinSignal(signal);
1024 if (signal == -1) { 972 if (signal == -1) {
1025 return -1; 973 return -1;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1030 }
1083 delete handler; 1031 delete handler;
1084 } 1032 }
1085 1033
1086 } // namespace bin 1034 } // namespace bin
1087 } // namespace dart 1035 } // namespace dart
1088 1036
1089 #endif // defined(TARGET_OS_WINDOWS) 1037 #endif // defined(TARGET_OS_WINDOWS)
1090 1038
1091 #endif // !defined(DART_IO_DISABLED) 1039 #endif // !defined(DART_IO_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/process_unsupported.cc ('k') | runtime/bin/reference_counting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698