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() );