From 1df7b744c363a0f29e35a2680fd9f75280f50756 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Mon, 18 Apr 2011 07:34:17 +0000 Subject: [PATCH] 2011-04-18 09:33 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/include/hbapifs.h * harbour/src/rtl/filesys.c + added new C functions: HB_BOOL hb_fsPipeCreate( HB_FHANDLE hPipe[ 2 ] ); HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, HB_MAXINT nTimeOut ); HB_SIZE hb_fsPipeRead( HB_FHANDLE hPipeHandle, void * buffer, HB_SIZE nSize, HB_MAXINT nTimeOut ); * harbour/src/rtl/philes.c + added new PRG function: HB_PREAD( , <@cBuffer>, [], [] ) -> It can be used for unblocking read from pipes, i.e. using handles returned by hb_processOpen() function. is pipe read handle is string variable passed by reference with read buffer is maximum number of bytes which can be read is timeout in milliseconds to wait for data to read, this function returns when at least one byte can be read is number of bytes read from the pipe, on error this function return -1. * harbour/src/rtl/hbproces.c + add new implementation of hb_fsProcessValue() and hb_fsProcessClose() for OS2 which uses OS2 API * use hb_fsPipeCreate() * harbour/src/rtl/hbjson.c * minor code reorganization to cleanup warning --- harbour/ChangeLog | 33 +++++ harbour/include/hbapifs.h | 3 + harbour/src/rtl/filesys.c | 206 ++++++++++++++++++++++++++- harbour/src/rtl/hbjson.c | 20 +-- harbour/src/rtl/hbproces.c | 281 +++++++++++++------------------------ harbour/src/rtl/philes.c | 41 ++++++ 6 files changed, 387 insertions(+), 197 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 70d97c2b6a..a4a750339e 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,39 @@ The license applies to all entries newer than 2009-04-28. */ +2011-04-18 09:33 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbapifs.h + * harbour/src/rtl/filesys.c + + added new C functions: + HB_BOOL hb_fsPipeCreate( HB_FHANDLE hPipe[ 2 ] ); + HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, + HB_MAXINT nTimeOut ); + HB_SIZE hb_fsPipeRead( HB_FHANDLE hPipeHandle, + void * buffer, HB_SIZE nSize, + HB_MAXINT nTimeOut ); + + * harbour/src/rtl/philes.c + + added new PRG function: + HB_PREAD( , <@cBuffer>, [], [] ) + -> + It can be used for unblocking read from pipes, i.e. using handles + returned by hb_processOpen() function. + is pipe read handle + is string variable passed by reference with read buffer + is maximum number of bytes which can be read + is timeout in milliseconds to wait for data to read, + this function returns when at least one byte can be read + is number of bytes read from the pipe, + on error this function return -1. + + * harbour/src/rtl/hbproces.c + + add new implementation of hb_fsProcessValue() and hb_fsProcessClose() + for OS2 which uses OS2 API + * use hb_fsPipeCreate() + + * harbour/src/rtl/hbjson.c + * minor code reorganization to cleanup warning + 2011-04-18 09:33 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg * INSTALL diff --git a/harbour/include/hbapifs.h b/harbour/include/hbapifs.h index 6440f9c8a1..2432f8499a 100644 --- a/harbour/include/hbapifs.h +++ b/harbour/include/hbapifs.h @@ -174,6 +174,9 @@ extern HB_EXPORT HB_USHORT hb_fsWrite ( HB_FHANDLE hFileHandle, const voi extern HB_EXPORT HB_SIZE hb_fsWriteLarge ( HB_FHANDLE hFileHandle, const void * pBuff, HB_SIZE nCount ); /* write to an open file from a buffer (>64K) */ extern HB_EXPORT HB_SIZE hb_fsWriteAt ( HB_FHANDLE hFileHandle, const void * pBuff, HB_SIZE nCount, HB_FOFFSET nOffset ); /* write to an open file at given offset from a buffer (>64K) */ extern HB_EXPORT HB_FHANDLE hb_fsPOpen ( const char * pFilename, const char * pMode ); +extern HB_EXPORT HB_BOOL hb_fsPipeCreate ( HB_FHANDLE hPipe[ 2 ] ); +extern HB_EXPORT HB_SIZE hb_fsPipeIsData ( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, HB_MAXINT nTimeOut ); +extern HB_EXPORT HB_SIZE hb_fsPipeRead ( HB_FHANDLE hPipeHandle, void * buffer, HB_SIZE nSize, HB_MAXINT nTimeOut ); extern HB_EXPORT HB_FHANDLE hb_fsGetOsHandle ( HB_FHANDLE hFileHandle ); extern HB_EXPORT HB_ERRCODE hb_fsGetFError ( void ); /* get FERROR() flag */ extern HB_EXPORT void hb_fsSetFError ( HB_ERRCODE uiError ); /* set FERROR() flag */ diff --git a/harbour/src/rtl/filesys.c b/harbour/src/rtl/filesys.c index dcac2de130..343e2bfab4 100644 --- a/harbour/src/rtl/filesys.c +++ b/harbour/src/rtl/filesys.c @@ -116,9 +116,7 @@ #include #include #include - #if defined( HB_OS_LINUX ) && !defined( __WATCOMC__ ) - #include - #endif + #include #endif #if !defined( HB_OS_WIN ) # include @@ -177,6 +175,7 @@ #include #include #elif defined( HB_OS_OS2 ) + #define INCL_BASE #define INCL_DOSFILEMGR #define INCL_DOSERRORS #define INCL_DOSDATETIME @@ -730,6 +729,207 @@ HB_FHANDLE hb_fsPOpen( const char * pFilename, const char * pMode ) return hFileHandle; } +HB_BOOL hb_fsPipeCreate( HB_FHANDLE hPipe[ 2 ] ) +{ + HB_BOOL fResult; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsPipeCreate(%p)", hPipe)); + +#if defined( HB_OS_WIN ) && !defined( HB_OS_WIN_CE ) +{ + SECURITY_ATTRIBUTES sa; + HANDLE hPipeRd, hPipeWr; + + memset( &sa, 0, sizeof( sa ) ); + sa.nLength = sizeof( sa ); + sa.bInheritHandle = TRUE; + + fResult = CreatePipe( &hPipeRd, &hPipeWr, &sa, 0 ) != 0; + if( fResult ) + { + hPipe[ 0 ] = ( HB_FHANDLE ) hPipeRd; + hPipe[ 1 ] = ( HB_FHANDLE ) hPipeWr; + } + else + hPipe[ 0 ] = hPipe[ 1 ] = FS_ERROR; +} +#elif defined( HB_OS_OS2 ) +{ +# if defined( __GNUC__ ) + fResult = pipe( hPipe ) == 0; + if( fResult ) + { + setmode( hPipe[ 0 ], O_BINARY ); + setmode( hPipe[ 1 ], O_BINARY ); + } + else + hPipe[ 0 ] = hPipe[ 1 ] = FS_ERROR; +# else + fResult = _pipe( hPipe, 4096, _O_BINARY ) == 0; + if( !fResult ) + hPipe[ 0 ] = hPipe[ 1 ] = FS_ERROR; +# endif +} +#elif defined( HB_OS_UNIX ) && !defined( HB_OS_VXWORKS ) && !defined( HB_OS_SYMBIAN ) +{ + fResult = pipe( hPipe ) == 0; + if( !fResult ) + hPipe[ 0 ] = hPipe[ 1 ] = FS_ERROR; +} +#else +{ + int iTODO; /* TODO: for given platform */ + + hPipe[ 0 ] = hPipe[ 1 ] = FS_ERROR; + hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); + fResult = HB_FALSE; +} +#endif + + return fResult; +} + +HB_SIZE hb_fsPipeIsData( HB_FHANDLE hPipeHandle, HB_SIZE nBufferSize, + HB_MAXINT nTimeOut ) +{ + HB_SIZE nToRead = 0; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsPipeIsData(%p,%" HB_PFS "u,%" PFHL "d)", ( void * ) ( HB_PTRDIFF ) hPipeHandle, nBufferSize, nTimeOut)); + + hb_vmUnlock(); + +#if defined( HB_OS_WIN ) && !defined( HB_OS_WIN_CE ) +{ + HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_BOOL fResult = HB_FALSE; + DWORD dwAvail; + + do + { + if( fResult ) + hb_releaseCPU(); + + dwAvail = 0; + fResult = PeekNamedPipe( ( HANDLE ) hb_fsGetOsHandle( hPipeHandle ), + NULL, 0, NULL, &dwAvail, NULL ) != 0; + hb_fsSetIOError( fResult, 0 ); + } + while( fResult && dwAvail == 0 && + ( nTimeOut < 0 || ( end_timer > 0 && + end_timer > hb_dateMilliSeconds() ) ) && + hb_vmRequestQuery() == 0 ); + + if( !fResult ) + nToRead = ( HB_SIZE ) -1; + else if( dwAvail > 0 ) + nToRead = ( ( HB_SIZE ) dwAvail < nBufferSize ) ? dwAvail : nBufferSize; +} +#elif defined( HB_OS_OS2 ) +{ + HB_MAXUINT end_timer = nTimeOut > 0 ? hb_dateMilliSeconds() + nTimeOut : 0; + HB_BOOL fResult = HB_FALSE; + AVAILDATA avail; + + do + { + APIRET ret; + + if( fResult ) + hb_releaseCPU(); + + avail.cbpipe = 0; + avail.cbmessage = 0; + ret = DosPeekNPipe( ( HPIPE ) hPipeHandle, + NULL, 0, NULL, &avail, NULL ); + fResult = ret == NO_ERROR || ret == ERROR_PIPE_BUSY; + hb_fsSetIOError( fResult, 0 ); + } + while( fResult && avail.cbpipe == 0 && + ( nTimeOut < 0 || ( end_timer > 0 && + end_timer > hb_dateMilliSeconds() ) ) && + hb_vmRequestQuery() == 0 ); + + if( !fResult ) + nToRead = ( HB_SIZE ) -1; + else if( avail.cbpipe > 0 ) + nToRead = ( ( HB_SIZE ) avail.cbpipe < nBufferSize ) ? avail.cbpipe : + nBufferSize; +} +#elif defined( HB_OS_UNIX ) && !defined( HB_OS_SYMBIAN ) +{ + struct timeval tv; + fd_set rfds; + int iResult; +#if !defined( HB_OS_LINUX ) + HB_MAXUINT timer = nTimeOut <= 0 ? 0 : hb_dateMilliSeconds(); +#endif + + for( ;; ) + { + if( nTimeOut < 0 ) + { + tv.tv_sec = 1; + tv.tv_usec = 0; + } + else + { + tv.tv_sec = nTimeOut / 1000; + tv.tv_usec = ( nTimeOut % 1000 ) * 1000; + } + + FD_ZERO( &rfds ); + FD_SET( hPipeHandle, &rfds ); + iResult = select( hPipeHandle + 1, &rfds, NULL, NULL, &tv ); + hb_fsSetIOError( iResult >= 0, 0 ); + if( iResult != -1 || nTimeOut == 0 || errno != EINTR || + hb_vmRequestQuery() != 0 ) + break; +#if !defined( HB_OS_LINUX ) + else if( nTimeOut > 0 ) + { + HB_MAXUINT timecurr = hb_dateMilliSeconds(); + if( timecurr > timer ) + { + if( ( nTimeOut -= timecurr - timer ) <= 0 ) + break; + timer = timecurr; + } + } +#endif + } + if( iResult > 0 ) + nToRead = nBufferSize; +} +#else +{ + int iTODO; /* TODO: for given platform */ + + HB_SYMBOL_UNUSED( hPipeHandle ); + HB_SYMBOL_UNUSED( nBufferSize ); + HB_SYMBOL_UNUSED( nTimeOut ); + hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); +} +#endif + + hb_vmLock(); + + return nToRead; +} + +HB_SIZE hb_fsPipeRead( HB_FHANDLE hPipeHandle, void * buffer, HB_SIZE nSize, + HB_MAXINT nTimeOut ) +{ + HB_SIZE nRead; + + HB_TRACE(HB_TR_DEBUG, ("hb_fsPipeRead(%p,%p,%" HB_PFS "u,%" PFHL "d)", ( void * ) ( HB_PTRDIFF ) hPipeHandle, buffer, nSize, nTimeOut)); + + nRead = hb_fsPipeIsData( hPipeHandle, nSize, nTimeOut ); + if( nRead != ( HB_SIZE ) -1 && nRead > 0 ) + nRead = hb_fsReadLarge( hPipeHandle, buffer, nRead ); + + return nRead; +} + HB_FHANDLE hb_fsOpen( const char * pFilename, HB_USHORT uiFlags ) { HB_FHANDLE hFileHandle; diff --git a/harbour/src/rtl/hbjson.c b/harbour/src/rtl/hbjson.c index 018e218ef7..5b59a32d21 100644 --- a/harbour/src/rtl/hbjson.c +++ b/harbour/src/rtl/hbjson.c @@ -135,19 +135,19 @@ static void _hb_jsonCtxAdd( PHB_JSON_ENCODE_CTX pCtx, const char * szString, HB_ static void _hb_jsonCtxAddIndent( PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nCount ) { - if( nCount <= 0 ) - return; - - if( pCtx->pHead + nCount >= pCtx->pBuffer + pCtx->nAlloc ) + if( nCount > 0 ) { - HB_SIZE nSize = pCtx->pHead - pCtx->pBuffer; + if( pCtx->pHead + nCount >= pCtx->pBuffer + pCtx->nAlloc ) + { + HB_SIZE nSize = pCtx->pHead - pCtx->pBuffer; - pCtx->nAlloc += ( pCtx->nAlloc << 1 ) + nCount; - pCtx->pBuffer = ( char * ) hb_xrealloc( pCtx->pBuffer, pCtx->nAlloc ); - pCtx->pHead = pCtx->pBuffer + nSize; + pCtx->nAlloc += ( pCtx->nAlloc << 1 ) + nCount; + pCtx->pBuffer = ( char * ) hb_xrealloc( pCtx->pBuffer, pCtx->nAlloc ); + pCtx->pHead = pCtx->pBuffer + nSize; + } + hb_xmemset( pCtx->pHead, ' ', nCount ); + pCtx->pHead += nCount; } - hb_xmemset( pCtx->pHead, ' ', nCount ); - pCtx->pHead += nCount; } static void _hb_jsonEncode( PHB_ITEM pValue, PHB_JSON_ENCODE_CTX pCtx, HB_SIZE nLevel ) diff --git a/harbour/src/rtl/hbproces.c b/harbour/src/rtl/hbproces.c index 5b41c107d5..2200a06a19 100644 --- a/harbour/src/rtl/hbproces.c +++ b/harbour/src/rtl/hbproces.c @@ -66,6 +66,9 @@ # include # include #elif defined( HB_OS_OS2 ) +# define INCL_DOSERRORS +# define INCL_DOSPROCESS +# include # include # include # include @@ -395,95 +398,70 @@ HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { + HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, + hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, + hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; + HB_BOOL fError = HB_FALSE; char * pszFree = NULL; HB_TRACE(HB_TR_DEBUG, ("hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFilename, phStdin, phStdout, phStderr, fDetach, pulPID)); pszFilename = hb_osEncodeCP( pszFilename, &pszFree, NULL ); -#if defined( HB_OS_WIN ) -{ - -#if defined( HB_OS_WIN_CE ) -# define CreatePipe( hIn, hOut, sa, flags ) ( FALSE ) -#endif - - HB_BOOL fError = HB_FALSE; - HANDLE hPipes[ 6 ]; - SECURITY_ATTRIBUTES sa; - int i; - - for( i = 0; i < 6; ++i ) - hPipes[ i ] = INVALID_HANDLE_VALUE; - - memset( &sa, 0, sizeof( sa ) ); - sa.nLength = sizeof( sa ); - sa.bInheritHandle = TRUE; if( phStdin != NULL ) - { - fError = !CreatePipe( &hPipes[ 0 ], &hPipes[ 1 ], &sa, 0 ); - if( !fError ) - SetHandleInformation( hPipes[ 1 ], HANDLE_FLAG_INHERIT, 0 ); - } + fError = !hb_fsPipeCreate( hPipeIn ); if( !fError && phStdout != NULL ) - { - fError = !CreatePipe( &hPipes[ 2 ], &hPipes[ 3 ], &sa, 0 ); - if( !fError ) - SetHandleInformation( hPipes[ 2 ], HANDLE_FLAG_INHERIT, 0 ); - } + fError = !hb_fsPipeCreate( hPipeOut ); if( !fError && phStderr != NULL ) { if( phStdout == phStderr ) { - hPipes[ 4 ] = hPipes[ 2 ]; - hPipes[ 5 ] = hPipes[ 3 ]; + hPipeErr[ 0 ] = hPipeOut[ 0 ]; + hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else - { - fError = !CreatePipe( &hPipes[ 4 ], &hPipes[ 5 ], &sa, 0 ); - if( !fError ) - SetHandleInformation( hPipes[ 4 ], HANDLE_FLAG_INHERIT, 0 ); - } + fError = !hb_fsPipeCreate( hPipeErr ); } - if( fError ) - hb_fsSetIOError( HB_FALSE, 0 ); - else + if( !fError ) { +#if defined( HB_OS_WIN ) + PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; -#if defined( UNICODE ) +# if defined( UNICODE ) LPWSTR lpCommand = hb_mbtowc( pszFilename ); -#else +# else char * lpCommand = hb_strdup( pszFilename ); -#endif +# endif + memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); -#ifdef STARTF_USESTDHANDLES +# ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; -#endif +# endif if( fDetach ) { -#ifdef STARTF_USESHOWWINDOW +# ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; -#endif +# endif si.wShowWindow = SW_HIDE; - si.hStdInput = hPipes[ 0 ]; - si.hStdOutput = hPipes[ 3 ]; - si.hStdError = hPipes[ 5 ]; -#ifdef DETACHED_PROCESS + si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); + si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); + si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); +# ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; -#endif +# endif } else { - si.hStdInput = phStdin ? hPipes[ 0 ] : GetStdHandle( STD_INPUT_HANDLE ); - si.hStdOutput = phStdout ? hPipes[ 3 ] : GetStdHandle( STD_OUTPUT_HANDLE ); - si.hStdError = phStderr ? hPipes[ 5 ] : GetStdHandle( STD_ERROR_HANDLE ); + si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); + si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); + si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, @@ -501,57 +479,28 @@ HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, { if( phStdin != NULL ) { - *phStdin = ( HB_FHANDLE ) hPipes[ 1 ]; - hPipes[ 1 ] = INVALID_HANDLE_VALUE; + *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; + hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { - *phStdout = ( HB_FHANDLE ) hPipes[ 2 ]; - hPipes[ 2 ] = INVALID_HANDLE_VALUE; + *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; + hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { - *phStderr = ( HB_FHANDLE ) hPipes[ 4 ]; - hPipes[ 4 ] = INVALID_HANDLE_VALUE; + *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; + hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } - } - for( i = phStdout == phStderr ? 3 : 5; i >= 0; --i ) - { - if( hPipes[ i ] != INVALID_HANDLE_VALUE ) - CloseHandle( hPipes[ i ] ); - } -} #elif defined( HB_OS_UNIX ) && \ - !defined( HB_OS_VXWORKS ) && !defined( HB_OS_SYMBIAN ) -{ - HB_BOOL fError = HB_FALSE; - HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, - hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, - hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; + !defined( HB_OS_VXWORKS ) && !defined( HB_OS_SYMBIAN ) - if( phStdin != NULL ) - fError = pipe( hPipeIn ) != 0; - if( !fError && phStdout != NULL ) - fError = pipe( hPipeOut ) != 0; - if( !fError && phStderr != NULL ) - { - if( phStdout == phStderr ) - { - hPipeErr[ 0 ] = hPipeOut[ 0 ]; - hPipeErr[ 1 ] = hPipeOut[ 1 ]; - } - else - fError = pipe( hPipeErr ) != 0; - } - - if( !fError ) - { pid_t pid = fork(); if( pid == -1 ) @@ -627,7 +576,7 @@ HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, /* execute command */ { -#if 0 +# if 0 char * argv[4]; argv[0] = ( char * ) "sh"; @@ -635,92 +584,26 @@ HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, argv[2] = ( char * ) pszFilename; argv[3] = ( char * ) 0; execv( "/bin/sh", argv ); -#else +# else char ** argv; argv = hb_buildArgs( pszFilename ); -#if defined( __WATCOMC__ ) +# if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); -#else +# else execvp( argv[ 0 ], argv ); -#endif +# endif hb_freeArgs( argv ); -#endif +# endif exit(1); } } - } - hb_fsSetIOError( !fError, 0 ); - - if( hPipeIn[ 0 ] != FS_ERROR ) - hb_fsClose( hPipeIn[ 0 ] ); - if( hPipeIn[ 1 ] != FS_ERROR ) - hb_fsClose( hPipeIn[ 1 ] ); - if( hPipeOut[ 0 ] != FS_ERROR ) - hb_fsClose( hPipeOut[ 0 ] ); - if( hPipeOut[ 1 ] != FS_ERROR ) - hb_fsClose( hPipeOut[ 1 ] ); - if( phStdout != phStderr ) - { - if( hPipeErr[ 0 ] != FS_ERROR ) - hb_fsClose( hPipeErr[ 0 ] ); - if( hPipeErr[ 1 ] != FS_ERROR ) - hb_fsClose( hPipeErr[ 1 ] ); - } -} #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) -{ -#if defined( HB_OS_OS2 ) && defined( __GNUC__ ) - -# define _hb_pipe( e, p ) do { \ - (e) = pipe( (p) ) != 0; \ - if( !(e) ) \ - { \ - setmode( (p)[ 0 ], O_BINARY ); \ - setmode( (p)[ 1 ], O_BINARY ); \ - } \ - } while( 0 ) -#else - -# define pid_t int -# define _hb_pipe( e, p ) do { \ - (e) = _pipe( (p), 2048, _O_BINARY ) != 0; \ - } while( 0 ) -#endif - - HB_BOOL fError = HB_FALSE; - HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, - hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, - hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; - - if( phStdin != NULL ) - { - _hb_pipe( fError, hPipeIn ); - } - if( !fError && phStdout != NULL ) - { - _hb_pipe( fError, hPipeOut ); - } - if( !fError && phStderr != NULL ) - { - if( phStdout == phStderr ) - { - hPipeErr[ 0 ] = hPipeOut[ 0 ]; - hPipeErr[ 1 ] = hPipeOut[ 1 ]; - } - else - { - _hb_pipe( fError, hPipeErr ); - } - } - - if( !fError ) - { int hStdIn, hStdOut, hStdErr; char ** argv; - pid_t pid; + int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); @@ -792,40 +675,35 @@ HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } + +#else + int iTODO; /* TODO: for given platform */ + + HB_SYMBOL_UNUSED( pszFilename ); + HB_SYMBOL_UNUSED( fDetach ); + HB_SYMBOL_UNUSED( pulPID ); + + hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); +#endif } hb_fsSetIOError( !fError, 0 ); if( hPipeIn[ 0 ] != FS_ERROR ) - close( hPipeIn[ 0 ] ); + hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) - close( hPipeIn[ 1 ] ); + hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) - close( hPipeOut[ 0 ] ); + hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) - close( hPipeOut[ 1 ] ); + hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) - close( hPipeErr[ 0 ] ); + hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) - close( hPipeErr[ 1 ] ); + hb_fsClose( hPipeErr[ 1 ] ); } -} -#else -{ - int iTODO; /* TODO: for given platform */ - - HB_SYMBOL_UNUSED( pszFilename ); - HB_SYMBOL_UNUSED( phStdin ); - HB_SYMBOL_UNUSED( phStdout ); - HB_SYMBOL_UNUSED( phStderr ); - HB_SYMBOL_UNUSED( fDetach ); - HB_SYMBOL_UNUSED( pulPID ); - - hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); -} -#endif if( pszFree ) hb_xfree( pszFree ); @@ -887,6 +765,26 @@ int hb_fsProcessValue( HB_FHANDLE hProcess, HB_BOOL fWait ) else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } +#elif defined( HB_OS_OS2 ) +{ + PID pid = ( PID ) hProcess; + + if( pid > 0 ) + { + RESULTCODES resultCodes = { 0, 0 }; + APIRET ret; + + ret = DosWaitChild( DCWA_PROCESS, fWait ? DCWW_WAIT : DCWW_NOWAIT, + &resultCodes, &pid, pid ); + hb_fsSetIOError( ret == NO_ERROR, 0 ); + if( ret == NO_ERROR ) + iRetStatus = resultCodes.codeResult; + else + iRetStatus = -2; + } + else + hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); +} #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) { int iPid = ( int ) hProcess; @@ -958,6 +856,21 @@ HB_BOOL hb_fsProcessClose( HB_FHANDLE hProcess, HB_BOOL fGentle ) else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } +#elif defined( HB_OS_OS2 ) +{ + PID pid = ( PID ) hProcess; + + HB_SYMBOL_UNUSED( fGentle ); + + if( pid > 0 ) + { + if( DosKillProcess( DKP_PROCESS, pid ) == NO_ERROR ) + fResult = HB_TRUE; + hb_fsSetIOError( fResult, 0 ); + } + else + hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); +} #else { int iTODO; /* TODO: for given platform */ @@ -1324,7 +1237,7 @@ int hb_fsProcessRun( const char * pszFilename, return iResult; } -/* temporary hack for still missing sysconf() in Watcom 1.8 */ +/* temporary hack for still missing sysconf() in Watcom 1.9 */ #if defined( HB_OS_LINUX ) && defined( __WATCOMC__ ) && \ __WATCOMC__ <= 1290 _WCRTLINK long sysconf( int __name ) diff --git a/harbour/src/rtl/philes.c b/harbour/src/rtl/philes.c index 6058de9a1b..eac8f259e3 100644 --- a/harbour/src/rtl/philes.c +++ b/harbour/src/rtl/philes.c @@ -475,6 +475,47 @@ HB_FUNC( HB_FISDEVICE ) hb_retl( hb_fsIsDevice( hb_numToHandle( hb_parnint( 1 ) ) ) ); } +/* HB_PREAD( , <@cBuffer>, [], [] ) + -> */ +HB_FUNC( HB_PREAD ) +{ + HB_FHANDLE hStdHandle = hb_numToHandle( hb_parnintdef( 1, FS_ERROR ) ); + PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); + char * buffer; + HB_SIZE nSize; + + if( hStdHandle != FS_ERROR && pBuffer && HB_ISBYREF( 2 ) && + hb_itemGetWriteCL( pBuffer, &buffer, &nSize ) ) + { + HB_ERRCODE uiError = 0; + + if( HB_ISNUM( 3 ) ) + { + HB_ISIZ nToRead = hb_parns( 3 ); + + if( nToRead >= 0 && ( HB_SIZE ) nToRead < nSize ) + nSize = nToRead; + } + + if( nSize > 0 ) + { + nSize = hb_fsPipeRead( hStdHandle, buffer, nSize, hb_parnint( 4 ) ); + uiError = hb_fsError(); + } + else + nSize = 0; + + if( nSize == ( HB_SIZE ) -1 ) + hb_retni( -1 ); + else + hb_retns( nSize ); + hb_fsSetFError( uiError ); + } + else + hb_errRT_BASE_SubstR( EG_ARG, 4001, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS ); +} + + HB_FUNC( HB_OSERROR ) { hb_retni( hb_fsOsError() );