Ok, after more investigating I've found the problem, I believe.
Windows appears to expect ALL std handles to be set to valid handles if
the STARTF_USESTDHANDLES flag is set in the STARTUPINFO -- but *only*
for .cmd and .bat files...exe's don't seem to have a problem.
When Subversion launches a pre-commit hook, it doesn't specify a stdout
handle, only a stderr one -- so apr_proc_create sets the stdout handle
to INVALID_HANDLE_VALUE. Then what's happening is the shell script
writes to stdout, the stdout handle is bad, and Windows (cmd.exe, I
suspect) spits out a 'Invalid handle' message to stderr. Thus, stderr
output is littered with invalid handle messages as well as the normal
stderr output.
Very weird, since it doesn't seem to apply to exe's (probably, cmd.exe
is 'helping' by printing error messages to stderr or something and
normal exe's just ignore the write failure).
Anyway, I'm not sure what exactly should be done to fix it...change APR
to provide a valid handle if the caller doesn't, or if Subversion should
just specify stdout as well or...?
I've inlined the little test program I made to play with it. Just
comment/uncomment setting the stdout handle in the STARTUPINFO to see
the differences when it is valid or not valid. Note that it is a
hastily written little test program and leaks handles, has hardcoded
paths, etc...The test.cmd script just echoes a line to stdout and one to
stderr.
DJ
----- stderr.cpp -----
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), 0, true};
HANDLE out = CreateFile( "c:\\temp\\stdout.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
CREATE_ALWAYS, 0, 0 );
if ( out == INVALID_HANDLE_VALUE )
{
printf( "CreateFile for out failed: 0x%x\n", GetLastError() );
return -1;
}
HANDLE err = CreateFile( "c:\\temp\\stderr.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
CREATE_ALWAYS, 0, 0 );
if ( err == INVALID_HANDLE_VALUE )
{
printf( "CreateFile for err failed: 0x%x\n", GetLastError() );
return -1;
}
STARTUPINFO si = {sizeof(STARTUPINFO)};
si.dwFlags = STARTF_USESTDHANDLES;
// si.hStdOutput = out;
si.hStdError = err;
PROCESS_INFORMATION pi = {0};
BOOL rc = CreateProcess( "c:\\temp\\test.cmd", "c:\\temp\\test.cmd",
0, 0, true, 0, 0, 0, &si, &pi );
if ( rc == FALSE )
{
printf( "CreateProcess failed: 0x%x\n", GetLastError() );
return -1;
}
WaitForSingleObject( pi.hThread, INFINITE );
printf( "Complete.\n" );
return 0;
}
----- test.cmd -----
@echo off
echo hello stdout
echo 1>&2 hello stderr
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Aug 15 02:19:19 2003