diff --git a/ChangeLog.txt b/ChangeLog.txt index 0474ae59ac..376654848e 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,14 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2014-01-12 20:28 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * src/rtl/filesys.c + + added support for setting non blocking mode in MS-Windows builds + of hb_fsPipeUnblock() + + * src/rtl/hbproces.c + ! rewritten MS-Windows version of hb_fsProcessRun() + 2014-01-11 14:58 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rtl/hbproces.c ! clear inheritance flag for second side of pipes passed to child process diff --git a/src/rtl/filesys.c b/src/rtl/filesys.c index c89d7bbc7d..7ce007f719 100644 --- a/src/rtl/filesys.c +++ b/src/rtl/filesys.c @@ -857,7 +857,17 @@ HB_BOOL hb_fsPipeUnblock( HB_FHANDLE hPipeHandle ) { HB_TRACE( HB_TR_DEBUG, ( "hb_fsPipeUnblock(%p)", ( void * ) ( HB_PTRDIFF ) hPipeHandle ) ); -#if defined( HB_OS_UNIX ) && ! defined( HB_OS_MINIX ) +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + { + DWORD dwMode = PIPE_NOWAIT; + + if( SetNamedPipeHandleState( ( HANDLE ) hb_fsGetOsHandle( hPipeHandle ), + &dwMode, NULL, NULL ) ) + return HB_TRUE; + else + return HB_FALSE; + } +#elif defined( HB_OS_UNIX ) && ! defined( HB_OS_MINIX ) { int ret = fcntl( hPipeHandle, F_GETFL, 0 ); diff --git a/src/rtl/hbproces.c b/src/rtl/hbproces.c index d9b6888310..e0ea222a31 100644 --- a/src/rtl/hbproces.c +++ b/src/rtl/hbproces.c @@ -987,10 +987,7 @@ int hb_fsProcessRun( const char * pszFilename, if( hProcess != FS_ERROR ) { #if defined( HB_OS_WIN ) - - DWORD dwResult, dwCount; - HANDLE lpHandles[ 4 ]; - HB_SIZE ul; + HB_BOOL fFinished = HB_FALSE; if( nStdInLen == 0 && hStdin != FS_ERROR ) { @@ -998,79 +995,75 @@ int hb_fsProcessRun( const char * pszFilename, hStdin = FS_ERROR; } + if( hStdin != FS_ERROR ) + hb_fsPipeUnblock( hStdin ); + if( hStdout != FS_ERROR ) + hb_fsPipeUnblock( hStdout ); + if( hStderr != FS_ERROR ) + hb_fsPipeUnblock( hStderr ); + for( ;; ) { - dwCount = 0; - if( hStdout != FS_ERROR ) - lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStdout ); - if( hStderr != FS_ERROR ) - lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStderr ); - if( nStdInLen && hStdin != FS_ERROR ) - lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hStdin ); + DWORD dwResult, dwWait; + HB_SIZE nLen; - lpHandles[ dwCount++ ] = ( HANDLE ) hb_fsGetOsHandle( hProcess ); + dwWait = 1000; - dwResult = WaitForMultipleObjects( dwCount, lpHandles, FALSE, INFINITE ); - - if( /* dwResult >= WAIT_OBJECT_0 && */ dwResult < WAIT_OBJECT_0 + dwCount ) + if( hStdout != FS_ERROR ) { - if( nStdInLen && hStdin != FS_ERROR && - lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStdin ) ) + if( nOutBuf == nOutSize ) { - ul = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); - pStdInBuf += ul; - nStdInLen -= ul; - if( nStdInLen == 0 ) - { - hb_fsClose( hStdin ); - hStdin = FS_ERROR; - } - } - else if( hStdout != FS_ERROR && - lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStdout ) ) - { - if( nOutBuf == nOutSize ) - { - nOutSize += HB_STD_BUFFER_SIZE; - pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); - } - ul = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); - if( ul == 0 ) - { - hb_fsClose( hStdout ); - hStdout = FS_ERROR; - } - else - nOutBuf += ul; - } - else if( hStderr != FS_ERROR && - lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hStderr ) ) - { - if( nErrBuf == nErrSize ) - { - nErrSize += HB_STD_BUFFER_SIZE; - pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); - } - ul = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); - if( ul == 0 ) - { - hb_fsClose( hStderr ); - hStderr = FS_ERROR; - } - else - nErrBuf += ul; - } - else if( lpHandles[ dwResult ] == ( HANDLE ) hb_fsGetOsHandle( hProcess ) ) - { - if( GetExitCodeProcess( ( HANDLE ) hb_fsGetOsHandle( hProcess ), &dwResult ) ) - iResult = ( int ) dwResult; - else - iResult = -2; - break; + nOutSize += HB_STD_BUFFER_SIZE; + pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } + nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); + if( nLen > 0 ) + nOutBuf += nLen; + dwWait = nLen > 0 ? 0 : 10; + } + + if( hStderr != FS_ERROR ) + { + if( nErrBuf == nErrSize ) + { + nErrSize += HB_STD_BUFFER_SIZE; + pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); + } + nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); + if( nLen > 0 ) + nErrBuf += nLen; + if( dwWait ) + dwWait = nLen > 0 ? 0 : 10; + } + + if( fFinished ) + { + if( dwWait != 0 ) + break; + } + else if( hStdin != FS_ERROR ) + { + nLen = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); + pStdInBuf += nLen; + nStdInLen -= nLen; + if( nStdInLen == 0 ) + { + hb_fsClose( hStdin ); + hStdin = FS_ERROR; + } + else if( dwWait ) + dwWait = nLen > 0 ? 0 : 10; + } + + dwResult = WaitForSingleObject( ( HANDLE ) hb_fsGetOsHandle( hProcess ), dwWait ); + if( dwResult == WAIT_OBJECT_0 ) + { + if( GetExitCodeProcess( ( HANDLE ) hb_fsGetOsHandle( hProcess ), &dwResult ) ) + iResult = ( int ) dwResult; + else + iResult = -2; + fFinished = HB_TRUE; } - else - break; } if( hStdin != FS_ERROR )