コード例 #1
0
ファイル: wafunc.c プロジェクト: AmericoBalboa/core
/*
 * 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;
}
コード例 #2
0
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();
      }
   }
}
コード例 #3
0
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 );
}
コード例 #4
0
ファイル: idle.c プロジェクト: JamesLinus/core
/* 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;
   }
}
コード例 #5
0
ファイル: netiosrv.c プロジェクト: abebuch/core
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;
}
コード例 #6
0
ファイル: hbcmplib.c プロジェクト: Rossine/harbour-core
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 );
   }
}
コード例 #7
0
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();
      }
   }
}
コード例 #8
0
ファイル: sqlbase.c プロジェクト: ItamarLins/harbour-core
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;
}
コード例 #9
0
ファイル: wafunc.c プロジェクト: AmericoBalboa/core
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;
}
コード例 #10
0
ファイル: idle.c プロジェクト: JamesLinus/core
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();
   }
}
コード例 #11
0
ファイル: idle.c プロジェクト: alcz/harbour
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();
   }
}
コード例 #12
0
ファイル: garbage.c プロジェクト: JamesLinus/core
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 );
   }
}
コード例 #13
0
ファイル: netiosrv.c プロジェクト: abebuch/core
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;
}
コード例 #14
0
ファイル: pplib.c プロジェクト: Petewg/V-harbour-core
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 );
   }
}
コード例 #15
0
ファイル: hbi18n1.c プロジェクト: JamesLinus/core
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;
}
コード例 #16
0
ファイル: adsx.c プロジェクト: SBCamus/core
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;
}
コード例 #17
0
ファイル: errapi.c プロジェクト: emazv72/core
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;
}
コード例 #18
0
ファイル: errapi.c プロジェクト: emazv72/core
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;
}
コード例 #19
0
ファイル: hbinet.c プロジェクト: diegopego/core
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();
   }
}
コード例 #20
0
ファイル: ssl_sock.c プロジェクト: mikomc/harbour-core
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;
}
コード例 #21
0
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;
}
コード例 #22
0
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;
}
コード例 #23
0
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;
}
コード例 #24
0
ファイル: hbinet.c プロジェクト: diegopego/core
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 );
   }
}
コード例 #25
0
ファイル: hbproces.c プロジェクト: mikomc/harbour-core
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();
}
コード例 #26
0
ファイル: garbage.c プロジェクト: JamesLinus/core
/* 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;
   }
}