@@ -97,6 +97,33 @@ class NativeOutputStream {
97
97
98
98
void SetHandle (HANDLE handle) { handle_ = handle; }
99
99
100
+ jint StreamBytesAvailable (JNIEnv* env) {
101
+ if (closed_.load () || handle_ == INVALID_HANDLE_VALUE) {
102
+ error_ = L" " ;
103
+ return 0 ;
104
+ }
105
+
106
+ DWORD avail = 0 ;
107
+ if (!::PeekNamedPipe (handle_, NULL , 0 , NULL , &avail, NULL )) {
108
+ // Check if either the other end closed the pipe or we did it with
109
+ // NativeOutputStream.Close() . In the latter case, we'll get a "system
110
+ // call interrupted" error.
111
+ if (GetLastError () == ERROR_BROKEN_PIPE || closed_.load ()) {
112
+ error_ = L" " ;
113
+ return 0 ;
114
+ } else {
115
+ DWORD err_code = GetLastError ();
116
+ error_ = bazel::windows::MakeErrorMessage (WSTR (__FILE__), __LINE__,
117
+ L" nativeStreamBytesAvailable" ,
118
+ L" " , err_code);
119
+ return -1 ;
120
+ }
121
+ } else {
122
+ error_ = L" " ;
123
+ }
124
+ return avail;
125
+ }
126
+
100
127
jint ReadStream (JNIEnv* env, jbyteArray java_bytes, jint offset,
101
128
jint length) {
102
129
JavaByteArray bytes (env, java_bytes);
@@ -210,6 +237,7 @@ class NativeProcess {
210
237
}
211
238
}
212
239
240
+ // Set up childs stdin pipe.
213
241
{
214
242
HANDLE pipe_read_h, pipe_write_h;
215
243
if (!CreatePipe (&pipe_read_h, &pipe_write_h, &sa, 0 )) {
@@ -220,6 +248,14 @@ class NativeProcess {
220
248
}
221
249
stdin_process = pipe_read_h;
222
250
stdin_ = pipe_write_h;
251
+
252
+ // "Our" end of the pipe must not be inherited by the child process
253
+ if (!SetHandleInformation (pipe_write_h, HANDLE_FLAG_INHERIT, 0 )) {
254
+ DWORD err_code = GetLastError ();
255
+ error_ = bazel::windows::MakeErrorMessage (
256
+ WSTR (__FILE__), __LINE__, L" nativeCreateProcess" , wpath, err_code);
257
+ return false ;
258
+ }
223
259
}
224
260
225
261
if (!stdout_is_stream) {
@@ -260,6 +296,13 @@ class NativeProcess {
260
296
}
261
297
stdout_.SetHandle (pipe_read_h);
262
298
stdout_process = pipe_write_h;
299
+ // "Our" end of the pipe must not be inherited by the child process
300
+ if (!SetHandleInformation (pipe_read_h, HANDLE_FLAG_INHERIT, 0 )) {
301
+ DWORD err_code = GetLastError ();
302
+ error_ = bazel::windows::MakeErrorMessage (
303
+ WSTR (__FILE__), __LINE__, L" nativeCreateProcess" , wpath, err_code);
304
+ return false ;
305
+ }
263
306
}
264
307
265
308
if (stderr_same_handle_as_stdout) {
@@ -314,6 +357,13 @@ class NativeProcess {
314
357
}
315
358
stderr_.SetHandle (pipe_read_h);
316
359
stderr_process = pipe_write_h;
360
+ // "Our" end of the pipe must not be inherited by the child process
361
+ if (!SetHandleInformation (pipe_read_h, HANDLE_FLAG_INHERIT, 0 )) {
362
+ DWORD err_code = GetLastError ();
363
+ error_ = bazel::windows::MakeErrorMessage (
364
+ WSTR (__FILE__), __LINE__, L" nativeCreateProcess" , wpath, err_code);
365
+ return false ;
366
+ }
317
367
}
318
368
return proc_.Create (
319
369
wpath, bazel::windows::GetJavaWstring (env, java_argv_rest),
@@ -443,6 +493,14 @@ Java_com_google_devtools_build_lib_windows_WindowsProcesses_readStream(
443
493
return stream->ReadStream (env, java_bytes, offset, length);
444
494
}
445
495
496
+ extern " C" JNIEXPORT jint JNICALL
497
+ Java_com_google_devtools_build_lib_windows_WindowsProcesses_streamBytesAvailable (
498
+ JNIEnv* env, jclass clazz, jlong stream_long) {
499
+ NativeOutputStream* stream =
500
+ reinterpret_cast <NativeOutputStream*>(stream_long);
501
+ return stream->StreamBytesAvailable (env);
502
+ }
503
+
446
504
extern " C" JNIEXPORT jint JNICALL
447
505
Java_com_google_devtools_build_lib_windows_WindowsProcesses_getExitCode (
448
506
JNIEnv* env, jclass clazz, jlong process_long) {
0 commit comments