266 JNIEnv *env, 267 const jchar *pcmd, 268 const jchar *penvBlock, 269 const jchar *pdir, 270 jlong *handles, 271 jboolean redirectErrorStream) 272 { 273 jlong ret = 0L; 274 STARTUPINFOW si = {sizeof(si)}; 275 276 /* Handles for which the inheritance flag must be restored. */ 277 HANDLE stdIOE[HANDLE_STORAGE_SIZE] = { 278 /* Current process standard IOE handles: JDK-7147084 */ 279 INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 280 /* Child process IOE handles: JDK-6921885 */ 281 (HANDLE)handles[0], (HANDLE)handles[1], (HANDLE)handles[2]}; 282 BOOL inherit[HANDLE_STORAGE_SIZE] = { 283 FALSE, FALSE, FALSE, 284 FALSE, FALSE, FALSE}; 285 286 { 287 /* Extraction of current process standard IOE handles */ 288 DWORD idsIOE[3] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, STD_ERROR_HANDLE}; 289 int i; 290 for (i = 0; i < 3; ++i) 291 /* Should not be closed by CloseHandle! */ 292 stdIOE[i] = GetStdHandle(idsIOE[i]); 293 } 294 295 prepareIOEHandleState(stdIOE, inherit); 296 { 297 /* Input */ 298 STDHOLDER holderIn = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_READ}; 299 if (initHolder(env, &handles[0], &holderIn, &si.hStdInput)) { 300 301 /* Output */ 302 STDHOLDER holderOut = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE}; 303 if (initHolder(env, &handles[1], &holderOut, &si.hStdOutput)) { 304 305 /* Error */ 306 STDHOLDER holderErr = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE}; 307 BOOL success; 308 if (redirectErrorStream) { 309 si.hStdError = si.hStdOutput; 310 /* Here we set the error stream to [ProcessBuilder.NullInputStream.INSTANCE] 311 value. That is in accordance with Java Doc for the redirection case. 312 The Java file for the [ handles[2] ] will be closed in ANY case. It is not 313 a handle leak. */ 314 handles[2] = JAVA_INVALID_HANDLE_VALUE; 315 success = TRUE; 316 } else { 317 success = initHolder(env, &handles[2], &holderErr, &si.hStdError); 318 } 319 320 if (success) { 321 PROCESS_INFORMATION pi; 322 DWORD processFlag = CREATE_UNICODE_ENVIRONMENT; 323 324 /* Suppress popping-up of a console window for non-console applications */ 325 if (GetConsoleWindow() == NULL) 326 processFlag |= CREATE_NO_WINDOW; 327 328 si.dwFlags = STARTF_USESTDHANDLES; 329 if (!CreateProcessW( 330 NULL, /* executable name */ 331 (LPWSTR)pcmd, /* command line */ 332 NULL, /* process security attribute */ 333 NULL, /* thread security attribute */ 334 TRUE, /* inherits system handles */ 335 processFlag, /* selected based on exe type */ 336 (LPVOID)penvBlock,/* environment block */ 337 (LPCWSTR)pdir, /* change to the new current directory */ 338 &si, /* (in) startup information */ 339 &pi)) /* (out) process information */ 340 { 341 win32Error(env, L"CreateProcess"); 342 } else { 343 closeSafely(pi.hThread); 344 ret = (jlong)pi.hProcess; 345 } 346 } | 266 JNIEnv *env, 267 const jchar *pcmd, 268 const jchar *penvBlock, 269 const jchar *pdir, 270 jlong *handles, 271 jboolean redirectErrorStream) 272 { 273 jlong ret = 0L; 274 STARTUPINFOW si = {sizeof(si)}; 275 276 /* Handles for which the inheritance flag must be restored. */ 277 HANDLE stdIOE[HANDLE_STORAGE_SIZE] = { 278 /* Current process standard IOE handles: JDK-7147084 */ 279 INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 280 /* Child process IOE handles: JDK-6921885 */ 281 (HANDLE)handles[0], (HANDLE)handles[1], (HANDLE)handles[2]}; 282 BOOL inherit[HANDLE_STORAGE_SIZE] = { 283 FALSE, FALSE, FALSE, 284 FALSE, FALSE, FALSE}; 285 286 /* These three should not be closed by CloseHandle! */ 287 stdIOE[0] = GetStdHandle(STD_INPUT_HANDLE); 288 stdIOE[1] = GetStdHandle(STD_OUTPUT_HANDLE); 289 stdIOE[2] = GetStdHandle(STD_ERROR_HANDLE); 290 291 prepareIOEHandleState(stdIOE, inherit); 292 { 293 /* Input */ 294 STDHOLDER holderIn = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_READ}; 295 if (initHolder(env, &handles[0], &holderIn, &si.hStdInput)) { 296 297 /* Output */ 298 STDHOLDER holderOut = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE}; 299 if (initHolder(env, &handles[1], &holderOut, &si.hStdOutput)) { 300 301 /* Error */ 302 STDHOLDER holderErr = {{INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}, OFFSET_WRITE}; 303 BOOL success; 304 if (redirectErrorStream) { 305 si.hStdError = si.hStdOutput; 306 /* Here we set the error stream to [ProcessBuilder.NullInputStream.INSTANCE] 307 value. That is in accordance with Java Doc for the redirection case. 308 The Java file for the [ handles[2] ] will be closed in ANY case. It is not 309 a handle leak. */ 310 handles[2] = JAVA_INVALID_HANDLE_VALUE; 311 success = TRUE; 312 } else { 313 success = initHolder(env, &handles[2], &holderErr, &si.hStdError); 314 } 315 316 if (success) { 317 PROCESS_INFORMATION pi; 318 DWORD processFlag = CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT; 319 320 /* JDK-8023130: 321 If the standard I/O is inherited, CREATE_NO_WINDOW must not be used. */ 322 if (GetConsoleWindow() != NULL && 323 (si.hStdInput == stdIOE[0] || 324 si.hStdOutput == stdIOE[1] || 325 si.hStdError == (redirectErrorStream ? stdIOE[1] : stdIOE[2]))) 326 { 327 processFlag &= ~CREATE_NO_WINDOW; 328 } 329 330 si.dwFlags = STARTF_USESTDHANDLES; 331 if (!CreateProcessW( 332 NULL, /* executable name */ 333 (LPWSTR)pcmd, /* command line */ 334 NULL, /* process security attribute */ 335 NULL, /* thread security attribute */ 336 TRUE, /* inherits system handles */ 337 processFlag, /* selected based on exe type */ 338 (LPVOID)penvBlock,/* environment block */ 339 (LPCWSTR)pdir, /* change to the new current directory */ 340 &si, /* (in) startup information */ 341 &pi)) /* (out) process information */ 342 { 343 win32Error(env, L"CreateProcess"); 344 } else { 345 closeSafely(pi.hThread); 346 ret = (jlong)pi.hProcess; 347 } 348 } |