Index: base/process_util_win.cc |
=================================================================== |
--- base/process_util_win.cc (revision 99780) |
+++ base/process_util_win.cc (working copy) |
@@ -237,8 +237,35 @@ |
startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW; |
PROCESS_INFORMATION process_info; |
+ DWORD flags = 0; |
+ |
+ win::ScopedHandle job_handle; |
+ if (options.job_handle) { |
+ job_handle.Set(CreateJobObject(NULL, NULL)); |
cpu_(ooo_6.6-7.5)
2011/09/07 20:07:22
so why do we create a job object if there is one a
Paweł Hajdan Jr.
2011/09/07 20:16:22
I create a job object because what's passed in the
|
+ if (!job_handle.IsValid()) { |
+ LOG(ERROR) << "Could not create JobObject."; |
+ return false; |
+ } |
+ |
+ JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; |
+ limit_info.BasicLimitInformation.LimitFlags = |
+ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; |
+ if (0 == SetInformationJobObject(job_handle.Get(), |
+ JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info))) { |
+ LOG(ERROR) << "Could not SetInformationJobObject."; |
+ return false; |
+ } |
+ |
+ flags |= CREATE_SUSPENDED; |
+ |
+ // If this code is run under a debugger, the launched process is |
+ // automatically associated with a job object created by the debugger. |
+ // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this. |
+ flags |= CREATE_BREAKAWAY_FROM_JOB; |
+ } |
+ |
if (options.as_user) { |
- DWORD flags = CREATE_UNICODE_ENVIRONMENT; |
+ flags |= CREATE_UNICODE_ENVIRONMENT; |
void* enviroment_block = NULL; |
if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) |
@@ -256,12 +283,25 @@ |
} else { |
if (!CreateProcess(NULL, |
const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, |
- options.inherit_handles, 0, NULL, NULL, |
+ options.inherit_handles, flags, NULL, NULL, |
&startup_info, &process_info)) { |
return false; |
} |
} |
+ if (options.job_handle) { |
+ if (0 == AssignProcessToJobObject(job_handle.Get(), |
+ process_info.hProcess)) { |
+ LOG(ERROR) << "Could not AssignProcessToObject."; |
+ KillProcess(process_info.hProcess, 1, true); |
+ return false; |
+ } |
+ |
+ options.job_handle->Set(job_handle.Take()); |
+ |
+ ResumeThread(process_info.hThread); |
+ } |
+ |
// Handles must be closed or they will leak. |
CloseHandle(process_info.hThread); |