| 377 | } |
| 378 | |
| 379 | extern "C" JNIEXPORT void JNICALL |
| 380 | Java_java_lang_Runtime_exec(JNIEnv* e, |
| 381 | jclass, |
| 382 | jobjectArray command, |
| 383 | jlongArray process) |
| 384 | { |
| 385 | #if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) |
| 386 | int size = 0; |
| 387 | for (int i = 0; i < e->GetArrayLength(command); ++i) { |
| 388 | jstring element = (jstring)e->GetObjectArrayElement(command, i); |
| 389 | if (element) { |
| 390 | // worst case, assuming every character is '"', and we escape all of them |
| 391 | size += 2 * e->GetStringUTFLength(element) + 3; |
| 392 | } else { |
| 393 | throwNew(e, |
| 394 | "java/lang/NullPointerException", |
| 395 | strdup("null string array element")); |
| 396 | } |
| 397 | } |
| 398 | |
| 399 | RUNTIME_ARRAY(char, line, size); |
| 400 | char* linep = RUNTIME_ARRAY_BODY(line); |
| 401 | for (int i = 0; i < e->GetArrayLength(command); ++i) { |
| 402 | if (i) |
| 403 | *(linep++) = _T(' '); |
| 404 | jstring element = (jstring)e->GetObjectArrayElement(command, i); |
| 405 | const char* s = e->GetStringUTFChars(element, 0); |
| 406 | |
| 407 | copyAndEscape(&linep, s, e->GetStringUTFLength(element)); |
| 408 | |
| 409 | e->ReleaseStringUTFChars(element, s); |
| 410 | } |
| 411 | *(linep++) = _T('\0'); |
| 412 | |
| 413 | HANDLE in[] = {0, 0}; |
| 414 | HANDLE out[] = {0, 0}; |
| 415 | HANDLE err[] = {0, 0}; |
| 416 | |
| 417 | makePipe(e, in); |
| 418 | SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0); |
| 419 | jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0])); |
| 420 | if (e->ExceptionCheck()) |
| 421 | return; |
| 422 | e->SetLongArrayRegion(process, 2, 1, &inDescriptor); |
| 423 | makePipe(e, out); |
| 424 | SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0); |
| 425 | jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1])); |
| 426 | if (e->ExceptionCheck()) |
| 427 | return; |
| 428 | e->SetLongArrayRegion(process, 3, 1, &outDescriptor); |
| 429 | makePipe(e, err); |
| 430 | SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0); |
| 431 | jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0])); |
| 432 | if (e->ExceptionCheck()) |
| 433 | return; |
| 434 | e->SetLongArrayRegion(process, 4, 1, &errDescriptor); |
| 435 | |
| 436 | PROCESS_INFORMATION pi; |
nothing calls this directly
no test coverage detected