/* * Assign a value to a field. */ HB_ERRCODE hb_rddPutFieldValue( PHB_ITEM pItem, PHB_SYMB pFieldSymbol ) { HB_ERRCODE errCode; HB_TRACE( HB_TR_DEBUG, ( "hb_rddPutFieldValue(%p, %p)", pItem, pFieldSymbol ) ); errCode = hb_rddFieldPut( pItem, pFieldSymbol ); if( errCode == HB_FAILURE && hb_vmRequestQuery() == 0 ) { /* * generate an error with retry possibility * (user created error handler can make this field accessible) */ PHB_ITEM pError = hb_errRT_New( ES_ERROR, NULL, EG_NOVAR, EDBCMD_NOVAR, NULL, pFieldSymbol->szName, 0, EF_CANRETRY ); while( hb_errLaunch( pError ) == E_RETRY ) { errCode = hb_rddFieldPut( pItem, pFieldSymbol ); if( errCode == HB_SUCCESS || hb_vmRequestQuery() != 0 ) break; } hb_itemRelease( pError ); } return errCode; }
static void hb_hrbExit( PHRB_BODY pHrbBody ) { if( pHrbBody->fExit ) { if( hb_vmRequestReenter() ) { HB_ULONG ul; pHrbBody->fExit = HB_FALSE; pHrbBody->fInit = HB_TRUE; for( ul = 0; ul < pHrbBody->ulSymbols; ul++ ) { if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_EXIT ) { hb_vmPushSymbol( pHrbBody->pSymRead + ul ); hb_vmPushNil(); hb_vmProc( 0 ); if( hb_vmRequestQuery() != 0 ) break; } } hb_vmRequestRestore(); } } }
static void hb_hrbDo( PHRB_BODY pHrbBody, int iPCount, PHB_ITEM * pParams ) { PHB_ITEM pRetVal = NULL; int i; hb_hrbInit( pHrbBody, iPCount, pParams ); /* May not have a startup symbol, if first symbol was an INIT Symbol (was executed already). */ if( pHrbBody->lSymStart >= 0 && hb_vmRequestQuery() == 0 ) { hb_vmPushSymbol( &pHrbBody->pSymRead[ pHrbBody->lSymStart ] ); hb_vmPushNil(); for( i = 0; i < iPCount; i++ ) hb_vmPush( pParams[ i ] ); hb_vmProc( ( HB_USHORT ) iPCount ); pRetVal = hb_itemNew( NULL ); hb_itemMove( pRetVal, hb_stackReturnItem() ); } if( pRetVal ) hb_itemReturnRelease( pRetVal ); }
/* performs all tasks defined for idle state */ void hb_idleState( void ) { PHB_IDLEDATA pIdleData = ( PHB_IDLEDATA ) hb_stackGetTSD( &s_idleData ); if( ! pIdleData->fIamIdle ) { pIdleData->fIamIdle = HB_TRUE; hb_releaseCPU(); if( hb_vmRequestQuery() == 0 ) { if( pIdleData->fCollectGarbage ) { hb_gcCollectAll( HB_FALSE ); pIdleData->fCollectGarbage = HB_FALSE; } if( pIdleData->pIdleTasks && pIdleData->iIdleTask < pIdleData->iIdleMaxTask ) { hb_itemRelease( hb_itemDo( pIdleData->pIdleTasks[ pIdleData->iIdleTask ], 0 ) ); ++pIdleData->iIdleTask; if( pIdleData->iIdleTask == pIdleData->iIdleMaxTask && hb_setGetIdleRepeat() ) { pIdleData->iIdleTask = 0; /* restart processing of idle tasks */ pIdleData->fCollectGarbage = HB_TRUE; } } } pIdleData->fIamIdle = HB_FALSE; } }
static long s_srvRecvAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lRead = 0, l; HB_MAXUINT end_timer; end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; while( lRead < len && ! conn->stop ) { if( conn->zstream ) l = hb_znetRead( conn->zstream, conn->sd, ptr + lRead, len - lRead, 1000 ); else l = hb_socketRecv( conn->sd, ptr + lRead, len - lRead, 0, 1000 ); if( l <= 0 ) { if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || hb_vmRequestQuery() != 0 || ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) break; } else { lRead += l; conn->rd_count += l; } } return lRead; }
static void s_pp_msg( void * cargo, int iErrorFmt, int iLine, const char * szModule, char cPrefix, int iValue, const char * szText, const char * szPar1, const char * szPar2 ) { HB_SYMBOL_UNUSED( cargo ); /* ignore all warning messages and errors when break or quit request */ if( cPrefix != 'W' && hb_vmRequestQuery() == 0 ) { char szMsgBuf[ 512 ], szLine[ 512 ]; PHB_ITEM pError; hb_snprintf( szMsgBuf, sizeof( szMsgBuf ), szText, szPar1, szPar2 ); if( ! szModule || *szModule == 0 || strcmp( szModule, "{SOURCE}.prg" ) == 0 ) hb_snprintf( szLine, sizeof( szLine ), "line:%i", iLine ); else hb_snprintf( szLine, sizeof( szLine ), iErrorFmt == HB_ERRORFMT_CLIPPER ? "%s(%i)" : "%s:%i", szModule, iLine ); pError = hb_errRT_New( ES_ERROR, "COMPILER", 1001, ( HB_ERRCODE ) iValue, szMsgBuf, szLine, 0 /*OsCode*/, EF_NONE ); hb_errLaunch( pError ); hb_errRelease( pError ); } }
static void hb_hrbInit( PHRB_BODY pHrbBody, int iPCount, PHB_ITEM * pParams ) { if( pHrbBody->fInit ) { if( hb_vmRequestReenter() ) { HB_ULONG ul; HB_BOOL fRepeat, fClipInit = HB_TRUE; int i; pHrbBody->fInit = HB_FALSE; pHrbBody->fExit = HB_TRUE; do { fRepeat = HB_FALSE; ul = pHrbBody->ulSymbols; while( ul-- ) { /* Check INIT functions */ if( ( pHrbBody->pSymRead[ ul ].scope.value & HB_FS_INITEXIT ) == HB_FS_INIT ) { if( strcmp( pHrbBody->pSymRead[ ul ].szName, "CLIPINIT$" ) ? ! fClipInit : fClipInit ) { hb_vmPushSymbol( pHrbBody->pSymRead + ul ); hb_vmPushNil(); for( i = 0; i < iPCount; i++ ) hb_vmPush( pParams[ i ] ); hb_vmProc( ( HB_USHORT ) iPCount ); if( hb_vmRequestQuery() != 0 ) break; } else if( fClipInit ) fRepeat = HB_TRUE; } } fClipInit = HB_FALSE; } while( fRepeat && hb_vmRequestQuery() == 0 ); hb_vmRequestRestore(); } } }
static HB_ERRCODE hb_errRT_SQLBASE( HB_ERRCODE errGenCode, HB_ERRCODE errSubCode, const char * szDescription, const char * szOperation ) { PHB_ITEM pError; HB_ERRCODE iRet = HB_FAILURE; if( hb_vmRequestQuery() == 0 ) { pError = hb_errRT_New( ES_ERROR, "SQLBASE", errGenCode, errSubCode, szDescription, szOperation, 0, EF_NONE ); iRet = hb_errLaunch( pError ); hb_itemRelease( pError ); } return iRet; }
static HB_ERRCODE hb_rddEvalWABlock( AREAP pArea, void * pBlock ) { PHB_ITEM pItem; hb_rddSelectWorkAreaNumber( pArea->uiArea ); pItem = hb_vmEvalBlockOrMacro( ( PHB_ITEM ) pBlock ); if( hb_vmRequestQuery() != 0 || ( HB_IS_LOGICAL( pItem ) && ! hb_itemGetL( pItem ) ) ) return HB_FAILURE; else return HB_SUCCESS; }
void hb_idleSleep( double dSeconds ) { if( dSeconds >= 0 ) { HB_MAXUINT end_timer = hb_dateMilliSeconds() + ( HB_MAXUINT ) ( dSeconds * 1000 ); do { hb_idleState(); } while( hb_dateMilliSeconds() < end_timer && hb_vmRequestQuery() == 0 ); hb_idleReset(); } }
void hb_idleSleep( double dSeconds ) { if( dSeconds >= 0 ) { HB_MAXINT timeout = dSeconds > 0 ? ( HB_MAXINT ) ( dSeconds * 1000 ) : 0; HB_MAXUINT timer = hb_timerInit( timeout ); do { hb_idleState(); } while( ( timeout = hb_timerTest( timeout, &timer ) ) != 0 && hb_vmRequestQuery() == 0 ); hb_idleReset(); } }
void hb_gcRefFree( void * pBlock ) { if( pBlock ) { PHB_GARBAGE pAlloc = HB_GC_PTR( pBlock ); if( hb_xRefDec( pAlloc ) ) { /* Don't release the block that will be deleted during finalization */ if( ! ( pAlloc->used & HB_GC_DELETE ) ) { pAlloc->used |= HB_GC_DELETE; /* execute clean-up function */ pAlloc->pFuncs->clear( pBlock ); if( hb_xRefCount( pAlloc ) != 0 ) { if( pAlloc->used & HB_GC_DELETE ) { pAlloc->used = s_uUsedFlag; if( hb_vmRequestQuery() == 0 ) hb_errRT_BASE( EG_DESTRUCTOR, 1301, NULL, "Reference to freed block", 0 ); } } else { HB_GC_LOCK(); if( pAlloc->locked ) hb_gcUnlink( &s_pLockedBlock, pAlloc ); else { hb_gcUnlink( &s_pCurrBlock, pAlloc ); HB_GC_AUTO_DEC(); } HB_GC_UNLOCK(); HB_GARBAGE_FREE( pAlloc ); } } } } else { hb_errInternal( HB_EI_XFREENULL, NULL, NULL, NULL ); } }
static long s_srvSendAll( PHB_CONSRV conn, void * buffer, long len ) { HB_BYTE * ptr = ( HB_BYTE * ) buffer; long lSent = 0, lLast = 1, l; HB_MAXUINT end_timer; if( ! conn->mutex || hb_threadMutexLock( conn->mutex ) ) { end_timer = conn->timeout > 0 ? hb_dateMilliSeconds() + conn->timeout : 0; while( lSent < len && ! conn->stop ) { if( conn->zstream ) l = hb_znetWrite( conn->zstream, conn->sd, ptr + lSent, len - lSent, 1000, &lLast ); else l = lLast = hb_socketSend( conn->sd, ptr + lSent, len - lSent, 0, 1000 ); if( l > 0 ) { lSent += l; conn->wr_count += l; } if( lLast <= 0 ) { if( hb_socketGetError() != HB_SOCKET_ERR_TIMEOUT || hb_vmRequestQuery() != 0 || ( end_timer != 0 && end_timer <= hb_dateMilliSeconds() ) ) break; } } if( conn->zstream && lLast > 0 && ! conn->stop ) { if( hb_znetFlush( conn->zstream, conn->sd, conn->timeout > 0 ? conn->timeout : -1 ) != 0 ) lSent = -1; } if( conn->mutex ) hb_threadMutexUnlock( conn->mutex ); } return lSent; }
HB_EXTERN_BEGIN static void hb_pp_ErrorMessage( void * cargo, const char * const szMsgTable[], char cPrefix, int iCode, const char * szParam1, const char * szParam2 ) { HB_TRACE( HB_TR_DEBUG, ( "hb_pp_ErrorGen(%p, %p, %c, %d, %s, %s)", cargo, szMsgTable, cPrefix, iCode, szParam1, szParam2 ) ); HB_SYMBOL_UNUSED( cargo ); /* ignore all warning messages and errors when break or quit request */ if( cPrefix != 'W' && hb_vmRequestQuery() == 0 ) { char szMsgBuf[ 1024 ]; PHB_ITEM pError; hb_snprintf( szMsgBuf, sizeof( szMsgBuf ), szMsgTable[ iCode - 1 ], szParam1, szParam2 ); pError = hb_errRT_New( ES_ERROR, "PP", 1001, ( HB_ERRCODE ) iCode, szMsgBuf, NULL, 0, EF_NONE | EF_CANDEFAULT ); hb_errLaunch( pError ); hb_errRelease( pError ); } }
static PHB_ITEM hb_i18n_pluralexp_compile( PHB_ITEM pExp ) { HB_SIZE nLen = hb_itemGetCLen( pExp ); PHB_ITEM pBlock = NULL; if( nLen > 0 ) { char * szMacro = ( char * ) hb_xgrab( nLen + 6 ); const char * szType; PHB_ITEM pMacro; szMacro[ 0 ] = '{'; szMacro[ 1 ] = '|'; szMacro[ 2 ] = 'n'; szMacro[ 3 ] = '|'; memcpy( &szMacro[ 4 ], hb_itemGetCPtr( pExp ), nLen ); szMacro[ 4 + nLen ] = '}'; szMacro[ 5 + nLen ] = '\0'; pMacro = hb_itemPutCLPtr( NULL, szMacro, nLen ); szType = hb_macroGetType( pMacro ); if( *szType == 'B' ) { hb_vmPush( pMacro ); hb_macroGetValue( hb_stackItemFromTop( -1 ), 0, 0 ); if( hb_vmRequestQuery() == 0 ) { pExp = hb_stackItemFromTop( -1 ); if( HB_IS_BLOCK( pExp ) ) pBlock = hb_itemNew( pExp ); hb_stackPop(); } } hb_itemRelease( pMacro ); } return pBlock; }
static HB_ERRCODE hb_mixErrorRT( ADSXAREAP pArea, HB_ERRCODE errGenCode, HB_ERRCODE errSubCode, char * filename, HB_ERRCODE errOsCode, HB_USHORT uiFlags ) { PHB_ITEM pError; HB_ERRCODE iRet = HB_FAILURE; if( hb_vmRequestQuery() == 0 ) { pError = hb_errNew(); hb_errPutGenCode( pError, errGenCode ); hb_errPutSubCode( pError, errSubCode ); hb_errPutOsCode( pError, errOsCode ); hb_errPutDescription( pError, hb_langDGetErrorDesc( errGenCode ) ); if( filename ) hb_errPutFileName( pError, filename ); if( uiFlags ) hb_errPutFlags( pError, uiFlags ); iRet = SELF_ERROR( ( AREAP ) pArea, pError ); hb_errRelease( pError ); } return iRet; }
PHB_ITEM hb_errLaunchSubst( PHB_ITEM pError ) { PHB_ITEM pResult; HB_TRACE( HB_TR_DEBUG, ( "hb_errLaunchSubst(%p)", pError ) ); if( pError ) { PHB_ERRDATA pErrData = ( PHB_ERRDATA ) hb_stackGetTSD( &s_errData ); HB_USHORT uiFlags = hb_errGetFlags( pError ); /* Check if we have a valid error handler */ if( ! pErrData->errorBlock || ! HB_IS_EVALITEM( pErrData->errorBlock ) ) hb_errInternal( HB_EI_ERRNOBLOCK, NULL, NULL, NULL ); /* Check if the error launcher was called too many times recursively */ if( pErrData->iLaunchCount == HB_ERROR_LAUNCH_MAX ) hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL ); /* Launch the error handler: "xResult := Eval( ErrorBlock(), oError )" */ pErrData->iLaunchCount++; /* set DosError() to last OS error code */ pErrData->uiErrorDOS = ( int ) hb_errGetOsCode( pError ); /* Add one try to the counter. */ if( uiFlags & EF_CANRETRY ) hb_errPutTries( pError, ( HB_USHORT ) ( hb_errGetTries( pError ) + 1 ) ); if( pErrData->errorHandler ) { /* there is a low-level error handler defined - use it instead * of normal Harbour level one */ pErrData->errorHandler->Error = pError; pErrData->errorHandler->ErrorBlock = pErrData->errorBlock; pResult = ( pErrData->errorHandler->Func )( pErrData->errorHandler ); pErrData->errorHandler->Error = NULL; } else pResult = hb_itemDo( pErrData->errorBlock, 1, pError ); pErrData->iLaunchCount--; /* Check results */ if( hb_vmRequestQuery() != 0 ) { if( pResult ) hb_itemRelease( pResult ); pResult = NULL; } else { /* If the canSubstitute flag has not been set, consider it as a failure. */ if( ! ( uiFlags & EF_CANSUBSTITUTE ) ) hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } } else pResult = hb_itemNew( NULL ); return pResult; }
HB_USHORT hb_errLaunch( PHB_ITEM pError ) { HB_USHORT uiAction = E_DEFAULT; /* Needed to avoid GCC -O2 warning */ HB_TRACE( HB_TR_DEBUG, ( "hb_errLaunch(%p)", pError ) ); if( pError ) { PHB_ERRDATA pErrData = ( PHB_ERRDATA ) hb_stackGetTSD( &s_errData ); HB_USHORT uiFlags = hb_errGetFlags( pError ); PHB_ITEM pResult; /* Check if we have a valid error handler */ if( ! pErrData->errorBlock || ! HB_IS_EVALITEM( pErrData->errorBlock ) ) hb_errInternal( HB_EI_ERRNOBLOCK, NULL, NULL, NULL ); /* Check if the error launcher was called too many times recursively */ if( pErrData->iLaunchCount == HB_ERROR_LAUNCH_MAX ) hb_errInternal( HB_EI_ERRTOOMANY, NULL, NULL, NULL ); /* Launch the error handler: "lResult := Eval( ErrorBlock(), oError )" */ pErrData->iLaunchCount++; /* set DosError() to last OS error code */ pErrData->uiErrorDOS = ( int ) hb_errGetOsCode( pError ); /* Add one try to the counter. */ if( uiFlags & EF_CANRETRY ) hb_errPutTries( pError, ( HB_USHORT ) ( hb_errGetTries( pError ) + 1 ) ); if( pErrData->errorHandler ) { /* there is a low-level error handler defined - use it instead * of normal Harbour level one */ pErrData->errorHandler->Error = pError; pErrData->errorHandler->ErrorBlock = pErrData->errorBlock; pResult = ( pErrData->errorHandler->Func )( pErrData->errorHandler ); pErrData->errorHandler->Error = NULL; } else pResult = hb_itemDo( pErrData->errorBlock, 1, pError ); pErrData->iLaunchCount--; /* Check results */ if( hb_vmRequestQuery() != 0 ) { if( pResult ) hb_itemRelease( pResult ); uiAction = E_BREAK; } else if( pResult ) { HB_BOOL bFailure = HB_FALSE; /* If the error block didn't return a logical value, */ /* or the canSubstitute flag has been set, consider it as a failure */ if( ! HB_IS_LOGICAL( pResult ) || ( uiFlags & EF_CANSUBSTITUTE ) ) bFailure = HB_TRUE; else { uiAction = hb_itemGetL( pResult ) ? E_RETRY : E_DEFAULT; if( ( uiAction == E_DEFAULT && !( uiFlags & EF_CANDEFAULT ) ) || ( uiAction == E_RETRY && !( uiFlags & EF_CANRETRY ) ) ) bFailure = HB_TRUE; } hb_itemRelease( pResult ); if( bFailure ) hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } else hb_errInternal( HB_EI_ERRRECFAILURE, NULL, NULL, NULL ); } else uiAction = E_RETRY; /* Clipper does this, undocumented */ return uiAction; }
static void s_inetRecvPattern( const char * const * patterns, int * patternsizes, int iPatternsCount, int iParam ) { PHB_SOCKET_STRUCT socket = HB_PARSOCKET( 1 ); PHB_ITEM pResult = hb_param( iParam, HB_IT_BYREF ); PHB_ITEM pMaxSize = hb_param( iParam + 1, HB_IT_NUMERIC ); PHB_ITEM pBufferSize = hb_param( iParam + 2, HB_IT_NUMERIC ); char cChar = '\0'; char * buffer; int iPaternFound = 0; int iTimeElapsed = 0; int iPos = 0; int iLen; int iAllocated, iBufferSize, iMax; int i; if( socket == NULL ) { hb_inetErrRT(); return; } else if( ! hb_inetIsOpen( socket ) ) { if( pResult ) hb_itemPutNI( pResult, -1 ); hb_retc_null(); return; } iBufferSize = pBufferSize ? hb_itemGetNI( pBufferSize ) : 80; iMax = pMaxSize ? hb_itemGetNI( pMaxSize ) : 0; socket->iError = HB_INET_ERR_OK; buffer = ( char * ) hb_xgrab( iBufferSize ); iAllocated = iBufferSize; do { if( iPos == iAllocated - 1 ) { iAllocated += iBufferSize; buffer = ( char * ) hb_xrealloc( buffer, iAllocated ); } iLen = s_inetRecv( socket, &cChar, 1, HB_TRUE, socket->iTimeout ); if( iLen == -1 && s_inetIsTimeout( socket ) ) { iLen = -2; /* this signals timeout */ if( socket->pPeriodicBlock ) { HB_BOOL fResult; iTimeElapsed += socket->iTimeout; hb_execFromArray( socket->pPeriodicBlock ); fResult = hb_parl( -1 ) && hb_vmRequestQuery() == 0; if( fResult && ( socket->iTimeLimit == -1 || iTimeElapsed < socket->iTimeLimit ) ) iLen = 1; } } else if( iLen > 0 ) { buffer[ iPos++ ] = cChar; for( i = 0; i < iPatternsCount; ++i ) { if( patternsizes[ i ] <= iPos && cChar == patterns[ i ][ patternsizes[ i ] - 1 ] ) { if( memcmp( buffer + iPos - patternsizes[ i ], patterns[ i ], patternsizes[ i ] ) == 0 ) { iPaternFound = i + 1; break; } } } } } while( iLen > 0 && iPaternFound == 0 && ( iMax == 0 || iPos < iMax ) ); if( iPaternFound ) { socket->iCount = iPos; if( pResult ) hb_itemPutNI( pResult, iPos ); hb_retclen_buffer( buffer, iPos - patternsizes[ iPaternFound - 1 ] ); } else { if( iLen == 0 ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) hb_inetGetError( socket ); else { socket->iError = HB_INET_ERR_BUFFOVERRUN; iLen = -1; } if( pResult ) hb_itemPutNI( pResult, iLen ); hb_xfree( buffer ); hb_retc_null(); } }
PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, HB_MAXINT timeout, int * piResult ) { int iResult; PHB_SSLSTREAM pStream; HB_MAXUINT timer; pStream = ( HB_SSLSTREAM * ) hb_xgrabz( sizeof( HB_SSLSTREAM ) ); timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); pStream->ssl = ssl; pStream->pSSL = hb_itemNew( hb_param( 2, HB_IT_POINTER ) ); pStream->blocking = timeout < 0; if( hb_socketSetBlockingIO( sd, pStream->blocking ) < 0 ) pStream->blocking = ! pStream->blocking; SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); iResult = SSL_set_fd( ssl, sd ); while( iResult == 1 ) { if( fServer ) iResult = SSL_accept( ssl ); else iResult = SSL_connect( ssl ); if( iResult != 1 && hb_vmRequestQuery() == 0 ) { int iError = SSL_get_error( ssl, iResult ); if( iError == SSL_ERROR_WANT_READ || iError == SSL_ERROR_WANT_WRITE ) { if( timeout < 0 ) { iResult = 1; continue; } else if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) { timeout -= timecurr - timer; timer = timecurr; } if( timeout > 0 ) { if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) { iResult = 1; continue; } } } hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); } } break; } if( iResult != 1 ) { hb_ssl_socketClose( pStream ); pStream = NULL; } else pStream->blocking = hb_socketSetBlockingIO( sd, HB_FALSE ) < 0; if( piResult ) *piResult = iResult; return pStream; }
long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd, void * buffer, long len, HB_MAXINT timeout ) { HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); long lRead = -1; int iToRead = -1; /* sd = SSL_get_rfd( pStream->ssl ); */ #if LONG_MAX > INT_MAX if( len > INT_MAX ) len = INT_MAX; #endif #if 0 while( ERR_get_error() != 0 ) { /* eat pending errors */ } #endif if( pStream->blocking ? timeout >= 0 : timeout < 0 ) { if( hb_socketSetBlockingIO( sd, timeout < 0 ) >= 0 ) pStream->blocking = ! pStream->blocking; } if( len > 0 ) { iToRead = SSL_pending( pStream->ssl ); if( iToRead <= 0 ) { iToRead = timeout < 0 ? 1 : hb_socketSelectRead( sd, timeout ); if( iToRead > 0 ) iToRead = ( int ) len; else if( iToRead == 0 ) hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); } else if( iToRead > len ) iToRead = ( int ) len; } while( iToRead > 0 ) { lRead = SSL_read( pStream->ssl, buffer, iToRead ); if( lRead > 0 ) hb_socketSetError( 0 ); else { int iError = SSL_get_error( pStream->ssl, ( int ) lRead ); switch( iError ) { case SSL_ERROR_ZERO_RETURN: hb_socketSetError( HB_SOCKET_ERR_PIPE ); lRead = 0; break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if( hb_vmRequestQuery() == 0 ) { if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) timeout -= timecurr - timer; if( timeout > 0 ) { timer = timecurr; if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) continue; else if( iError < 0 ) break; } } hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); break; } default: hb_socketSetError( HB_SSL_SOCK_ERROR_BASE + iError ); } } break; } return lRead; }
PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, HB_MAXINT timeout, PHB_ITEM pSSL, int * piResult ) { int iResult; PHB_SSLSTREAM pStream; HB_MAXUINT timer; pStream = ( HB_SSLSTREAM * ) hb_xgrabz( sizeof( HB_SSLSTREAM ) ); timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); pStream->ssl = ssl; pStream->pSSL = pSSL ? hb_itemNew( pSSL ) : NULL; pStream->blocking = timeout < 0; if( hb_socketSetBlockingIO( sd, pStream->blocking ) < 0 ) pStream->blocking = ! pStream->blocking; SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); iResult = SSL_set_fd( ssl, sd ); /* Truncates `sd` on win64. OpenSSL bug: https://rt.openssl.org/Ticket/Display.html?id=1928&user=guest&pass=guest */ while( iResult == 1 ) { if( fServer ) iResult = SSL_accept( ssl ); else iResult = SSL_connect( ssl ); if( iResult != 1 && hb_vmRequestQuery() == 0 ) { int iError = SSL_get_error( ssl, iResult ); if( iError == SSL_ERROR_WANT_READ || iError == SSL_ERROR_WANT_WRITE ) { if( timeout < 0 ) { iResult = 1; continue; } else if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) { timeout -= timecurr - timer; if( timeout < 0 ) timeout = 0; timer = timecurr; } if( timeout > 0 ) { if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) { iResult = 1; continue; } } } hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); } } break; } if( iResult != 1 ) { hb_ssl_socketClose( pStream ); pStream = NULL; } else pStream->blocking = hb_socketSetBlockingIO( sd, HB_FALSE ) < 0; if( piResult ) *piResult = iResult; return pStream; }
long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd, const void * buffer, long len, HB_MAXINT timeout, long * plast ) { HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); long lWritten = 0, lWr = 0; /* sd = SSL_get_wfd( pStream->ssl ); */ #if LONG_MAX > INT_MAX if( len > INT_MAX ) len = INT_MAX; #endif #if 0 while( ERR_get_error() != 0 ) { /* eat pending errors */ } #endif if( pStream->blocking ? timeout >= 0 : timeout < 0 ) { if( hb_socketSetBlockingIO( sd, timeout < 0 ) >= 0 ) pStream->blocking = ! pStream->blocking; } while( len > 0 ) { lWr = SSL_write( pStream->ssl, buffer, ( int ) len ); if( plast ) *plast = lWr; if( lWr > 0 ) { lWritten += lWr; len -= lWr; buffer = ( const char * ) buffer + lWr; hb_socketSetError( 0 ); } else { int iError = SSL_get_error( pStream->ssl, ( int ) lWr ); switch( iError ) { case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: if( hb_vmRequestQuery() == 0 ) { if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) timeout -= timecurr - timer; if( timeout > 0 ) { timer = timecurr; if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) continue; } else iError = 0; } else iError = 0; if( lWritten == 0 && iError == 0 ) hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); break; } default: hb_socketSetError( HB_SSL_SOCK_ERROR_BASE + iError ); } break; } } return lWritten != 0 ? lWritten : lWr; }
static void s_inetRecvInternal( int iMode ) { PHB_SOCKET_STRUCT socket = HB_PARSOCKET( 1 ); PHB_ITEM pBuffer = hb_param( 2, HB_IT_STRING ); if( socket == NULL || pBuffer == NULL || ! HB_ISBYREF( 2 ) ) hb_inetErrRT(); else if( ! hb_inetIsOpen( socket ) ) hb_retni( -1 ); else { int iLen, iMaxLen, iReceived, iTimeElapsed; char * buffer; HB_SIZE nLen; if( hb_itemGetWriteCL( pBuffer, &buffer, &nLen ) ) iLen = ( int ) nLen; else { iLen = 0; buffer = NULL; } if( HB_ISNUM( 3 ) ) { iMaxLen = hb_parni( 3 ); if( iMaxLen < 0 ) iMaxLen = 0; else if( iLen < iMaxLen ) iMaxLen = iLen; } else iMaxLen = iLen; iReceived = iTimeElapsed = 0; socket->iError = HB_INET_ERR_OK; do { iLen = s_inetRecv( socket, buffer + iReceived, iMaxLen - iReceived, HB_FALSE, socket->iTimeout ); if( iLen >= 0 ) { iReceived += iLen; if( iMode == 0 ) /* Called from hb_inetRecv()? */ break; } else if( iLen == -1 && s_inetIsTimeout( socket ) ) { /* if we have a pPeriodicBlock, timeLimit is our REAL timeout */ if( socket->pPeriodicBlock ) { /* timed out; let's see if we have to run a cb routine */ iTimeElapsed += socket->iTimeout; hb_execFromArray( socket->pPeriodicBlock ); /* do we continue? */ if( hb_parl( -1 ) && hb_vmRequestQuery() == 0 && ( socket->iTimeLimit == -1 || iTimeElapsed < socket->iTimeLimit ) ) iLen = 1; /* Declare success to continue loop */ } } } while( iReceived < iMaxLen && iLen > 0 ); socket->iCount = iReceived; if( iLen == 0 ) socket->iError = HB_INET_ERR_CLOSEDCONN; else if( iLen < 0 ) hb_inetGetError( socket ); hb_retni( iReceived > 0 ? iReceived : iLen ); } }
int hb_fsProcessRun( const char * pszFileName, const char * pStdInBuf, HB_SIZE nStdInLen, char ** pStdOutPtr, HB_SIZE * pulStdOut, char ** pStdErrPtr, HB_SIZE * pulStdErr, HB_BOOL fDetach ) { HB_FHANDLE hStdin, hStdout, hStderr, *phStdin, *phStdout, *phStderr; char * pOutBuf, *pErrBuf; HB_SIZE nOutSize, nErrSize, nOutBuf, nErrBuf; int iResult; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessRun(%s, %p, %" HB_PFS "u, %p, %p, %p, %p, %d)", pStdInBuf, pStdInBuf, nStdInLen, pStdOutPtr, pulStdOut, pStdErrPtr, pulStdErr, fDetach ) ); nOutBuf = nErrBuf = nOutSize = nErrSize = 0; pOutBuf = pErrBuf = NULL; hStdin = hStdout = hStderr = FS_ERROR; phStdin = pStdInBuf ? &hStdin : NULL; phStdout = pStdOutPtr && pulStdOut ? &hStdout : NULL; phStderr = pStdErrPtr && pulStdErr ? ( pStdOutPtr == pStdErrPtr ? phStdout : &hStderr ) : NULL; #if defined( HB_PROCESS_USEFILES ) { #if defined( HB_OS_WIN_CE ) # define _HB_NULLHANDLE() FS_ERROR #elif defined( HB_OS_UNIX ) # define _HB_NULLHANDLE() open( "/dev/null", O_RDWR ) #else # define _HB_NULLHANDLE() open( "NUL:", O_RDWR ) #endif char sTmpIn[ HB_PATH_MAX ]; char sTmpOut[ HB_PATH_MAX ]; char sTmpErr[ HB_PATH_MAX ]; HB_SYMBOL_UNUSED( phStdin ); HB_SYMBOL_UNUSED( nOutSize ); HB_SYMBOL_UNUSED( nErrSize ); sTmpIn[ 0 ] = sTmpOut[ 0 ] = sTmpErr[ 0 ] = '\0'; if( pStdInBuf ) { hStdin = hb_fsCreateTempEx( sTmpIn, NULL, NULL, NULL, FC_NORMAL ); if( nStdInLen ) { hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); hb_fsSeek( hStdin, 0, FS_SET ); } } else if( fDetach ) hStdin = _HB_NULLHANDLE(); if( pStdOutPtr && pulStdOut ) hStdout = hb_fsCreateTempEx( sTmpOut, NULL, NULL, NULL, FC_NORMAL ); else if( fDetach ) hStdout = _HB_NULLHANDLE(); if( pStdErrPtr && pulStdErr ) { if( phStdout == phStderr ) hStderr = hStdout; else hStderr = hb_fsCreateTempEx( sTmpErr, NULL, NULL, NULL, FC_NORMAL ); } else if( fDetach ) hStderr = _HB_NULLHANDLE(); iResult = hb_fsProcessExec( pszFileName, hStdin, hStdout, hStderr ); if( hStdin != FS_ERROR ) { hb_fsClose( hStdin ); if( sTmpIn[ 0 ] ) hb_fsDelete( sTmpIn ); } if( hStdout != FS_ERROR ) { if( pStdOutPtr && pulStdOut ) { nOutBuf = hb_fsSeek( hStdout, 0, FS_END ); if( nOutBuf ) { pOutBuf = ( char * ) hb_xgrab( nOutBuf + 1 ); hb_fsSeek( hStdout, 0, FS_SET ); nOutBuf = hb_fsReadLarge( hStdout, pOutBuf, nOutBuf ); } } hb_fsClose( hStdout ); if( sTmpOut[ 0 ] ) hb_fsDelete( sTmpOut ); } if( hStderr != FS_ERROR && hStderr != hStdout ) { if( pStdErrPtr && pulStdErr ) { nErrBuf = hb_fsSeek( hStderr, 0, FS_END ); if( nErrBuf ) { pErrBuf = ( char * ) hb_xgrab( nErrBuf + 1 ); hb_fsSeek( hStderr, 0, FS_SET ); nErrBuf = hb_fsReadLarge( hStderr, pErrBuf, nErrBuf ); } } hb_fsClose( hStderr ); if( sTmpErr[ 0 ] ) hb_fsDelete( sTmpErr ); } } #else /* ! HB_PROCESS_USEFILES */ { HB_FHANDLE hProcess; hb_vmUnlock(); iResult = -1; hProcess = hb_fsProcessOpen( pszFileName, phStdin, phStdout, phStderr, fDetach, NULL ); if( hProcess != FS_ERROR ) { #if defined( HB_OS_WIN ) HB_BOOL fFinished = HB_FALSE, fBlocked; int iPipeCount = 0; if( nStdInLen == 0 && hStdin != FS_ERROR ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } if( hStdout == hStderr ) hStderr = FS_ERROR; if( hStdin != FS_ERROR ) ++iPipeCount; if( hStdout != FS_ERROR ) ++iPipeCount; if( hStderr != FS_ERROR ) ++iPipeCount; fBlocked = iPipeCount <= 1; if( ! fBlocked ) { if( hStdin != FS_ERROR ) hb_fsPipeUnblock( hStdin ); if( hStdout != FS_ERROR ) hb_fsPipeUnblock( hStdout ); if( hStderr != FS_ERROR ) hb_fsPipeUnblock( hStderr ); } for( ;; ) { DWORD dwResult, dwWait; HB_SIZE nLen; dwWait = 1000; if( hStdout != FS_ERROR ) { if( nOutBuf == nOutSize ) { if( nOutSize == 0 ) nOutSize = HB_STD_BUFFER_SIZE; else nOutSize += nOutSize >> 1; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); if( nLen > 0 ) nOutBuf += nLen; else if( fBlocked ) { hb_fsClose( hStdout ); hStdout = FS_ERROR; --iPipeCount; } dwWait = nLen > 0 ? 0 : 10; } if( hStderr != FS_ERROR ) { if( nErrBuf == nErrSize ) { if( nErrSize == 0 ) nErrSize = HB_STD_BUFFER_SIZE; else nErrSize += nErrSize >> 1; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); if( nLen > 0 ) nErrBuf += nLen; else if( fBlocked ) { hb_fsClose( hStderr ); hStderr = FS_ERROR; --iPipeCount; } if( dwWait ) dwWait = nLen > 0 ? 0 : 10; } if( fFinished ) { if( dwWait != 0 ) break; } else if( hStdin != FS_ERROR ) { nLen = ! fBlocked && nStdInLen > 4096 ? 4096 : nStdInLen; nLen = hb_fsWriteLarge( hStdin, pStdInBuf, nLen ); pStdInBuf += nLen; nStdInLen -= nLen; if( nStdInLen == 0 || ( fBlocked && nLen == 0 ) ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; --iPipeCount; } else if( dwWait ) dwWait = nLen > 0 ? 0 : 10; } if( iPipeCount == 0 ) dwWait = INFINITE; 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; } } if( hStdin != FS_ERROR ) hb_fsClose( hStdin ); if( hStdout != FS_ERROR ) hb_fsClose( hStdout ); if( hStderr != FS_ERROR ) hb_fsClose( hStderr ); CloseHandle( ( HANDLE ) hb_fsGetOsHandle( hProcess ) ); #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) HB_MAXINT nTimeOut = 0; int iPipeCount = 0; if( nStdInLen == 0 && hStdin != FS_ERROR ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } if( hStdout == hStderr ) hStderr = FS_ERROR; if( hStdin != FS_ERROR ) ++iPipeCount; if( hStdout != FS_ERROR ) ++iPipeCount; if( hStderr != FS_ERROR ) ++iPipeCount; while( iPipeCount > 0 ) { HB_MAXINT nNextTOut = 10; HB_SIZE nLen; if( hStdin != FS_ERROR ) { if( iPipeCount == 1 ) nLen = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); else nLen = hb_fsPipeWrite( hStdin, pStdInBuf, nStdInLen, nTimeOut ); if( nLen == ( HB_SIZE ) ( iPipeCount == 1 ? 0 : FS_ERROR ) ) nStdInLen = 0; else if( nLen > 0 ) { pStdInBuf += nLen; nStdInLen -= nLen; nNextTOut = 0; } if( nStdInLen == 0 ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; --iPipeCount; } } if( hStdout != FS_ERROR ) { if( nOutBuf == nOutSize ) { if( nOutSize == 0 ) nOutSize = HB_STD_BUFFER_SIZE; else nOutSize += nOutSize >> 1; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } if( iPipeCount == 1 ) nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); else nLen = hb_fsPipeRead( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf, nTimeOut ); if( nLen == ( HB_SIZE ) ( iPipeCount == 1 ? 0 : FS_ERROR ) ) { hb_fsClose( hStdout ); hStdout = FS_ERROR; --iPipeCount; } else if( nLen > 0 ) { nOutBuf += nLen; nNextTOut = 0; } } if( hStderr != FS_ERROR ) { if( nErrBuf == nErrSize ) { if( nErrSize == 0 ) nErrSize = HB_STD_BUFFER_SIZE; else nErrSize += nErrSize >> 1; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } if( iPipeCount == 1 ) nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); else nLen = hb_fsPipeRead( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf, nTimeOut ); if( nLen == ( HB_SIZE ) ( iPipeCount == 1 ? 0 : FS_ERROR ) ) { hb_fsClose( hStderr ); hStderr = FS_ERROR; --iPipeCount; } else if( nLen > 0 ) { nErrBuf += nLen; nNextTOut = 0; } } nTimeOut = nNextTOut; } if( hStdin != FS_ERROR ) hb_fsClose( hStdin ); if( hStdout != FS_ERROR ) hb_fsClose( hStdout ); if( hStderr != FS_ERROR ) hb_fsClose( hStderr ); iResult = hb_fsProcessValue( hProcess, HB_TRUE ); #elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) if( nStdInLen == 0 && hStdin != FS_ERROR ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } if( hStdout == hStderr ) hStderr = FS_ERROR; if( hStdin != FS_ERROR ) hb_fsPipeUnblock( hStdin ); if( hStdout != FS_ERROR ) hb_fsPipeUnblock( hStdout ); if( hStderr != FS_ERROR ) hb_fsPipeUnblock( hStderr ); for( ;; ) { HB_BOOL fStdout, fStderr, fStdin; HB_SIZE nLen; #if defined( HB_HAS_POLL ) { struct pollfd fds[ 3 ]; nfds_t nfds = 0; if( hStdout != FS_ERROR ) { fds[ nfds ].fd = hStdout; fds[ nfds ].events = POLLIN; fds[ nfds++ ].revents = 0; } if( hStderr != FS_ERROR ) { fds[ nfds ].fd = hStderr; fds[ nfds ].events = POLLIN; fds[ nfds++ ].revents = 0; } if( hStdin != FS_ERROR ) { fds[ nfds ].fd = hStdin; fds[ nfds ].events = POLLOUT; fds[ nfds++ ].revents = 0; } if( nfds == 0 ) break; iResult = poll( fds, nfds, -1 ); hb_fsSetIOError( iResult >= 0, 0 ); if( iResult == -1 && hb_fsOsError() == ( HB_ERRCODE ) EINTR && hb_vmRequestQuery() == 0 ) continue; else if( iResult <= 0 ) break; nfds = 0; fStdout = fStderr = fStdin = HB_FALSE; if( hStdout != FS_ERROR ) { if( ( fds[ nfds ].revents & POLLIN ) != 0 ) fStdout = HB_TRUE; else if( ( fds[ nfds ].revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) { hb_fsClose( hStdout ); hStdout = FS_ERROR; } nfds++; } if( hStderr != FS_ERROR ) { if( ( fds[ nfds ].revents & POLLIN ) != 0 ) fStderr = HB_TRUE; else if( ( fds[ nfds ].revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) { hb_fsClose( hStderr ); hStderr = FS_ERROR; } nfds++; } if( hStdin != FS_ERROR ) { if( ( fds[ nfds ].revents & POLLOUT ) != 0 ) fStdin = HB_TRUE; else if( ( fds[ nfds ].revents & ( POLLHUP | POLLNVAL | POLLERR ) ) != 0 ) { hb_fsClose( hStdin ); hStderr = FS_ERROR; } } } #else /* ! HB_HAS_POLL */ { fd_set rfds, wfds, *prfds, *pwfds; HB_FHANDLE fdMax; fdMax = 0; prfds = pwfds = NULL; if( hStdout != FS_ERROR || hStderr != FS_ERROR ) { FD_ZERO( &rfds ); if( hStdout != FS_ERROR ) { FD_SET( hStdout, &rfds ); if( hStdout > fdMax ) fdMax = hStdout; } if( hStderr != FS_ERROR ) { FD_SET( hStderr, &rfds ); if( hStderr > fdMax ) fdMax = hStderr; } prfds = &rfds; } if( hStdin != FS_ERROR ) { FD_ZERO( &wfds ); FD_SET( hStdin, &wfds ); if( hStdin > fdMax ) fdMax = hStdin; pwfds = &wfds; } if( prfds == NULL && pwfds == NULL ) break; iResult = select( fdMax + 1, prfds, pwfds, NULL, NULL ); hb_fsSetIOError( iResult >= 0, 0 ); if( iResult == -1 && hb_fsOsError() != ( HB_ERRCODE ) EINTR && hb_vmRequestQuery() == 0 ) continue; else if( iResult <= 0 ) break; fStdout = hStdout != FS_ERROR && FD_ISSET( hStdout, &rfds ); fStderr = hStderr != FS_ERROR && FD_ISSET( hStderr, &rfds ); fStdin = hStdin != FS_ERROR && FD_ISSET( hStdin, &wfds ); } #endif /* ! HB_HAS_POLL */ if( fStdout ) { if( nOutBuf == nOutSize ) { if( nOutSize == 0 ) nOutSize = HB_STD_BUFFER_SIZE; else nOutSize += nOutSize >> 1; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); if( nLen == 0 ) { /* zero bytes read after positive Select() * - writing process closed the pipe */ hb_fsClose( hStdout ); hStdout = FS_ERROR; } else nOutBuf += nLen; } if( fStderr ) { if( nErrBuf == nErrSize ) { if( nErrSize == 0 ) nErrSize = HB_STD_BUFFER_SIZE; else nErrSize += nErrSize >> 1; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); if( nLen == 0 ) { /* zero bytes read after positive Select() * - writing process closed the pipe */ hb_fsClose( hStderr ); hStderr = FS_ERROR; } else nErrBuf += nLen; } if( fStdin ) { nLen = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); pStdInBuf += nLen; nStdInLen -= nLen; if( nStdInLen == 0 ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } } } if( hStdin != FS_ERROR ) hb_fsClose( hStdin ); if( hStdout != FS_ERROR ) hb_fsClose( hStdout ); if( hStderr != FS_ERROR ) hb_fsClose( hStderr ); iResult = hb_fsProcessValue( hProcess, HB_TRUE ); #else int iTODO; HB_SYMBOL_UNUSED( nStdInLen ); HB_SYMBOL_UNUSED( nOutSize ); HB_SYMBOL_UNUSED( nErrSize ); #endif } hb_vmLock(); }
/* Check all memory block if they can be released */ void hb_gcCollectAll( HB_BOOL fForce ) { /* MTNOTE: it's not necessary to protect s_bCollecting with mutex * because it can be changed at RT only inside this procedure * when all other threads are stoped by hb_vmSuspendThreads(), * [druzus] */ if( ! s_bCollecting && hb_vmSuspendThreads( fForce ) ) { PHB_GARBAGE pAlloc, pDelete; if( ! s_pCurrBlock || s_bCollecting ) { hb_vmResumeThreads(); return; } s_bCollecting = HB_TRUE; /* Step 1 - mark */ /* All blocks are already marked because we are flipping * the used/unused flag */ /* Step 2 - sweep */ /* check all known places for blocks they are referring */ hb_vmIsStackRef(); hb_vmIsStaticRef(); hb_clsIsClassRef(); /* check list of locked block for blocks referenced from * locked block */ if( s_pLockedBlock ) { pAlloc = s_pLockedBlock; do { pAlloc->pFuncs->mark( HB_BLOCK_PTR( pAlloc ) ); pAlloc = pAlloc->pNext; } while( s_pLockedBlock != pAlloc ); } /* Step 3 - finalize */ /* Release all blocks that are still marked as unused */ /* * infinite loop can appear when we are executing clean-up functions * scanning s_pCurrBlock. It's possible that one of them will free * the GC block which we are using as stop condition. Only blocks * for which we set HB_GC_DELETE flag are guarded against releasing. * To avoid such situation first we are moving blocks which will be * deleted to separate list. It's additional operation but it can * even increase the speed when we are deleting only few percent * of all allocated blocks because in next passes we will scan only * deleted block list. [druzus] */ pAlloc = NULL; /* for stop condition */ do { if( s_pCurrBlock->used == s_uUsedFlag ) { pDelete = s_pCurrBlock; pDelete->used |= HB_GC_DELETE | HB_GC_DELETELST; hb_gcUnlink( &s_pCurrBlock, pDelete ); hb_gcLink( &s_pDeletedBlock, pDelete ); HB_GC_AUTO_DEC(); } else { /* at least one block will not be deleted, set new stop condition */ if( ! pAlloc ) pAlloc = s_pCurrBlock; s_pCurrBlock = s_pCurrBlock->pNext; } } while( pAlloc != s_pCurrBlock ); /* Step 4 - flip flag */ /* Reverse used/unused flag so we don't have to mark all blocks * during next collecting */ s_uUsedFlag ^= HB_GC_USED_FLAG; #ifdef HB_GC_AUTO /* store number of marked blocks for automatic GC activation */ s_ulBlocksMarked = s_ulBlocks; if( s_ulBlocksAuto == 0 ) s_ulBlocksCheck = HB_GC_AUTO_MAX; else { s_ulBlocksCheck = s_ulBlocksMarked + s_ulBlocksAuto; if( s_ulBlocksCheck <= s_ulBlocksMarked ) s_ulBlocksCheck = HB_GC_AUTO_MAX; } #endif /* call memory manager cleanup function */ hb_xclean(); /* resume suspended threads */ hb_vmResumeThreads(); /* do we have any deleted blocks? */ if( s_pDeletedBlock ) { /* call a cleanup function */ pAlloc = s_pDeletedBlock; do { s_pDeletedBlock->pFuncs->clear( HB_BLOCK_PTR( s_pDeletedBlock ) ); s_pDeletedBlock = s_pDeletedBlock->pNext; } while( pAlloc != s_pDeletedBlock ); /* release all deleted blocks */ do { pDelete = s_pDeletedBlock; hb_gcUnlink( &s_pDeletedBlock, pDelete ); if( hb_xRefCount( pDelete ) != 0 ) { pDelete->used = s_uUsedFlag; pDelete->locked = 0; HB_GC_LOCK(); hb_gcLink( &s_pCurrBlock, pDelete ); HB_GC_AUTO_INC(); HB_GC_UNLOCK(); if( hb_vmRequestQuery() == 0 ) hb_errRT_BASE( EG_DESTRUCTOR, 1302, NULL, "Reference to freed block", 0 ); } else HB_GARBAGE_FREE( pDelete ); } while( s_pDeletedBlock ); } s_bCollecting = HB_FALSE; } }