@@ -3012,6 +3012,62 @@ static char *wcstoutfdup_startup(char *buffer, const wchar_t *wcs, size_t len)
3012
3012
return memcpy (malloc_startup (len ), buffer , len );
3013
3013
}
3014
3014
3015
+ static void maybe_redirect_std_handle (const wchar_t * key , DWORD std_id , int fd ,
3016
+ DWORD desired_access , DWORD flags )
3017
+ {
3018
+ DWORD create_flag = fd ? OPEN_ALWAYS : OPEN_EXISTING ;
3019
+ wchar_t buf [MAX_LONG_PATH ];
3020
+ DWORD max = ARRAY_SIZE (buf );
3021
+ HANDLE handle ;
3022
+ DWORD ret = GetEnvironmentVariableW (key , buf , max );
3023
+
3024
+ if (!ret || ret >= max )
3025
+ return ;
3026
+
3027
+ /* make sure this does not leak into child processes */
3028
+ SetEnvironmentVariableW (key , NULL );
3029
+ if (!wcscmp (buf , L"off" )) {
3030
+ close (fd );
3031
+ handle = GetStdHandle (std_id );
3032
+ if (handle != INVALID_HANDLE_VALUE )
3033
+ CloseHandle (handle );
3034
+ return ;
3035
+ }
3036
+ if (std_id == STD_ERROR_HANDLE && !wcscmp (buf , L"2>&1" )) {
3037
+ handle = GetStdHandle (STD_OUTPUT_HANDLE );
3038
+ if (handle == INVALID_HANDLE_VALUE ) {
3039
+ close (fd );
3040
+ handle = GetStdHandle (std_id );
3041
+ if (handle != INVALID_HANDLE_VALUE )
3042
+ CloseHandle (handle );
3043
+ } else {
3044
+ int new_fd = _open_osfhandle ((intptr_t )handle , O_BINARY );
3045
+ SetStdHandle (std_id , handle );
3046
+ dup2 (new_fd , fd );
3047
+ /* do *not* close the new_fd: that would close stdout */
3048
+ }
3049
+ return ;
3050
+ }
3051
+ handle = CreateFileW (buf , desired_access , 0 , NULL , create_flag ,
3052
+ flags , NULL );
3053
+ if (handle != INVALID_HANDLE_VALUE ) {
3054
+ int new_fd = _open_osfhandle ((intptr_t )handle , O_BINARY );
3055
+ SetStdHandle (std_id , handle );
3056
+ dup2 (new_fd , fd );
3057
+ close (new_fd );
3058
+ }
3059
+ }
3060
+
3061
+ static void maybe_redirect_std_handles (void )
3062
+ {
3063
+ maybe_redirect_std_handle (L"GIT_REDIRECT_STDIN" , STD_INPUT_HANDLE , 0 ,
3064
+ GENERIC_READ , FILE_ATTRIBUTE_NORMAL );
3065
+ maybe_redirect_std_handle (L"GIT_REDIRECT_STDOUT" , STD_OUTPUT_HANDLE , 1 ,
3066
+ GENERIC_WRITE , FILE_ATTRIBUTE_NORMAL );
3067
+ maybe_redirect_std_handle (L"GIT_REDIRECT_STDERR" , STD_ERROR_HANDLE , 2 ,
3068
+ GENERIC_WRITE , FILE_FLAG_NO_BUFFERING );
3069
+ }
3070
+
3015
3071
#if defined(_MSC_VER )
3016
3072
3017
3073
#ifdef _DEBUG
@@ -3050,6 +3106,8 @@ int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
3050
3106
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
3051
3107
#endif
3052
3108
3109
+ maybe_redirect_std_handles ();
3110
+
3053
3111
/* determine size of argv conversion buffer */
3054
3112
maxlen = wcslen (_wpgmptr );
3055
3113
for (k = 1 ; k < argc ; k ++ )
@@ -3114,6 +3172,8 @@ void mingw_startup(void)
3114
3172
wchar_t * * wenv , * * wargv ;
3115
3173
_startupinfo si ;
3116
3174
3175
+ maybe_redirect_std_handles ();
3176
+
3117
3177
/* get wide char arguments and environment */
3118
3178
si .newmode = 0 ;
3119
3179
if (__wgetmainargs (& argc , & wargv , & wenv , _CRT_glob , & si ) < 0 )
0 commit comments