TA_RetCode TA_FileSeqClose( TA_FileHandle *handle ) { TA_PROLOG TA_RetCode retCode; TA_FileHandlePriv *fileHandlePriv; TA_SystemGlobal *global; #if defined( USE_WIN32_API ) DWORD win32Error; BOOL retValue; #endif TA_TRACE_BEGIN( TA_FileSeqClose ); retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) { TA_TRACE_RETURN( retCode ); } TA_ASSERT( handle != NULL ); fileHandlePriv = (TA_FileHandlePriv *)handle; if( fileHandlePriv ) { #if defined( USE_WIN32_API ) if( fileHandlePriv->handle != INVALID_HANDLE_VALUE ) { retValue = CloseHandle( fileHandlePriv->handle ); if( retValue == 0 ) { win32Error = GetLastError(); global->lastError = win32Error; TA_FATAL( NULL, 0, win32Error ); } } if( fileHandlePriv->allocBuffer ) { freeDiskBuffer( fileHandlePriv->allocBuffer, fileHandlePriv->allocBufferSize ); } #endif #if defined( USE_OSLAYER ) if( fileHandlePriv->handle != NULL ) fclose( fileHandlePriv->handle ); if( fileHandlePriv->allocBuffer ) TA_Free( fileHandlePriv->allocBuffer ); #endif if( fileHandlePriv->streamAccess ) { TA_StreamAccessFree( fileHandlePriv->streamAccess ); } TA_Free( fileHandlePriv ); } TA_TRACE_RETURN( TA_SUCCESS ); }
void TA_PrivTraceCheckpoint( const char *funcname, const char *filename, unsigned int lineNb ) { TA_TraceGlobal *global; TA_RetCode retCode; #if defined( TA_DEBUG ) TA_String *key; TA_StringCache *stringCache; #endif /* Get access to the global. */ retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return; #if !defined( TA_DEBUG ) internalCheckpoint( global, NULL, funcname, filename, lineNb ); #else /* Build a unique string representing the position. */ stringCache = TA_GetGlobalStringCache(); key = TA_StringValueAlloc( stringCache, filename, lineNb ); if( !key ) return; internalCheckpoint( global, key, funcname, filename, lineNb ); TA_StringFree( stringCache, key ); #endif }
void TA_FatalReport( FILE *out ) { TA_TraceGlobal *global; TA_RetCode retCode; unsigned int i, pos; TA_TracePosition *tracePosition; retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return; if( global->fatalErrorRecorded ) printFatalError( &global->fatalError, out ); else fprintf( out, "No fatal error" ); /* Output the calling sequence. */ fprintf( out, "Execution Sequence:\n" ); pos = global->posForNextTrace; for( i=0; i < TA_CODE_TRACE_SIZE; i++ ) { tracePosition = &global->codeTrace[pos]; if( tracePosition && tracePosition->repetition ) printTracePosition( tracePosition, out ); pos++; if( pos >= TA_CODE_TRACE_SIZE ) pos = 0; } }
void TA_PrivTraceBegin( const char *funcname, const char *filename, unsigned int lineNb ) { #if defined( TA_DEBUG) && defined( TA_SINGLE_THREAD ) unsigned int newTracePositionNeeded; /* Boolean */ TA_TracePosition *tracePosition; TA_TraceGlobal *global; TA_RetCode retCode; #endif /* Entry point of a function are "checkpoint" for code * coverage. */ TA_PrivTraceCheckpoint( funcname, filename, lineNb ); /* If debugging a single thread, maintain a call stack. */ #if defined( TA_DEBUG ) && defined( TA_SINGLE_THREAD ) if( TA_IsTraceEnabled() ) { /* Disable tracing within tracing! */ TA_TraceDisable(); /* Get access to the global. */ retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return; tracePosition = TA_ListRemoveTail( global->callStack ); newTracePositionNeeded = 1; if( tracePosition ) { /* Check if last trace in the stack is the same function. */ if( (tracePosition->filename == filename) && (tracePosition->funcname == funcname) ) { /* Same fucntion, so just increment the repetition. */ tracePosition->repetition++; newTracePositionNeeded = 0; } else /* Not the same function, put back this trace. */ TA_ListAddTail( global->callStack, tracePosition ); } /* New function, so add the trace to the stack. */ if( newTracePositionNeeded ) { tracePosition = newTracePosition( funcname, filename, lineNb ); if( tracePosition ) TA_ListAddTail( global->callStack, (void *)tracePosition ); } /* Re-enable tracing. */ TA_TraceDisable(); } #endif }
/**** Global functions definitions. ****/ int TA_GetLastError( void ) { TA_RetCode retCode; TA_SystemGlobal *global; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return 0; return global->lastError; }
static LPVOID allocDiskBuffer( const char *path, DWORD *nbByteAlloc ) { BOOL retValue; LPCTSTR lpRootPathName; /* address of root path */ DWORD lpSectorsPerCluster; /* address of sectors per cluster */ DWORD lpBytesPerSector; /* address of bytes per sector */ DWORD lpNumberOfFreeClusters; /* address of number of free clusters */ DWORD lpTotalNumberOfClusters; /* address of total number of clusters */ LPVOID allocatedMem; DWORD win32Error; TA_RetCode retCode; TA_SystemGlobal *global; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return (LPVOID)NULL; lpRootPathName = path; *nbByteAlloc = 0; retValue = GetDiskFreeSpace( NULL/*lpRootPathName*/, &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters ); if( retValue == 0 ) { win32Error = GetLastError(); global->lastError = win32Error; return (LPVOID)NULL; } allocatedMem = VirtualAlloc( NULL, /* No specific address needed. */ lpBytesPerSector, /* size of region */ MEM_COMMIT|MEM_RESERVE, /* type of allocation */ PAGE_READWRITE/* type of access protection */ ); if( !allocatedMem ) { win32Error = GetLastError(); global->lastError = win32Error; return (LPVOID)NULL; } /* Success... return information to caller. */ *nbByteAlloc = lpBytesPerSector; return allocatedMem; }
/**** Global functions definitions. ****/ TA_RetCode TA_TraceInit( void ) { TA_RetCode retCode; TA_TraceGlobal *global; /* "Getting" the global will allocate/initialize the global for * this module. * Note: All this will guarantee that TA_TraceGlobalShutdown * will get called when TA_Shutdown is called by the * library user. */ retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return retCode; return TA_SUCCESS; }
TA_RetCode TA_DirectoryFree( TA_Directory *directory ) { TA_RetCode retCode; TA_SystemGlobal *global; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return retCode; if( directory ) { stringListFree( global->filenameCache, directory->listOfFile ); stringListFree( global->dirnameCache, directory->listOfDirectory ); TA_Free( directory ); } return TA_SUCCESS; }
TA_RetCode TA_PrivTraceReturn( const char *funcname, const char *filename, unsigned int lineNb, TA_RetCode retCode ) { #if defined( TA_SINGLE_THREAD ) TA_TracePosition *tracePosition; TA_TraceGlobal *global; TA_RetCode localRetCode; #endif TA_PrivTraceCheckpoint( funcname, filename, lineNb ); /* If debugging a single threaded, maintain a calling stack. */ #if defined( TA_DEBUG ) && defined( TA_SINGLE_THREAD ) if( !TA_IsTraceEnabled() ) { /* Disable tracing within tracing! */ TA_TraceDisable(); /* Get access to the global. */ localRetCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( localRetCode != TA_SUCCESS ) return retCode; tracePosition = TA_ListRemoveTail( global->callStack ); if( tracePosition ) { --tracePosition->repetition; if( tracePosition->repetition == 0 ) TA_Free( tracePosition ); else TA_ListAddTail( global->callStack, tracePosition ); } TA_TraceEnable(); } #endif return retCode; }
TA_RetCode TA_SetFatalErrorHandler( TA_FatalHandler handler ) { TA_TraceGlobal *global; TA_RetCode retCode; retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return retCode; #if !defined( TA_SINGLE_THREAD ) retCode = TA_SemaWait( &global->callSema ); if( retCode != TA_SUCCESS ) return retCode; #endif global->userHandler = handler; #if !defined( TA_SINGLE_THREAD ) TA_SemaPost( &global->callSema ); #endif return TA_SUCCESS; }
int TA_NbProcessor( void ) { #if defined( USE_WIN32_API ) TA_RetCode retCode; TA_SystemGlobal *global; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return 1; /* Run time function checking the number of processor on that system. * Will eventually allows to make better decision for parallelism. */ initSysInfo(global); return global->sysInfo.dwNumberOfProcessors; #else /* For the time being... do not assume more than one * processor on other platform. */ return 1; #endif }
static TA_RetCode freeDiskBuffer( LPVOID buffer, DWORD nbByteAlloc ) { TA_PROLOG BOOL retValue; DWORD win32Error; TA_RetCode retCode; TA_SystemGlobal *global; TA_TRACE_BEGIN( freeDiskBuffer ); retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) { TA_TRACE_RETURN( retCode ); } /* Uncommit all pages. */ retValue = VirtualFree( buffer, nbByteAlloc, MEM_DECOMMIT ); if( retValue == 0 ) { win32Error = GetLastError(); global->lastError = win32Error; TA_FATAL( "Win32 Cannot free paged mem", nbByteAlloc, win32Error ); } /* Unreserve all pages. */ retValue = VirtualFree( buffer, 0, MEM_RELEASE ); if( retValue == 0 ) { win32Error = GetLastError(); global->lastError = win32Error; TA_FATAL( "Win32 Cannot free paged mem", 0, win32Error ); } TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_DirectoryAlloc( const char *path, TA_Directory **directory ) { #if defined( USE_WIN32_API ) HANDLE handle; WIN32_FIND_DATA data; DWORD win32Error; #endif #if defined( USE_OSLAYER ) DIRST dirHandle; const char *filePattern; char *basePath; #endif unsigned pathLength; int findNextRetCode; TA_Directory *dir; TA_String *string; TA_RetCode retCode; TA_SystemGlobal *global; const char *entryName; unsigned int entryIsDirectory; *directory = NULL; if( (path == NULL) || (directory == NULL) ) return TA_BAD_PARAM; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return retCode; dir = (TA_Directory *)TA_Malloc( sizeof( TA_Directory ) ); if( dir == NULL ) return TA_ALLOC_ERR; dir->nbFile = 0; dir->nbDirectory = 0; dir->listOfFile = TA_ListAlloc(); dir->listOfDirectory = TA_ListAlloc(); if( (dir->listOfFile == NULL) || (dir->listOfDirectory == NULL) ) { TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } /* Verify that the path is valid. */ pathLength = strlen( path ); if( (pathLength == 0) || (pathLength >= MAX_PATH) ) { TA_DirectoryFree( dir ); return TA_BAD_PARAM; } /* Now get the directory from the operating system. */ #if defined( USE_WIN32_API ) handle = FindFirstFile( path, &data ); if( handle == INVALID_HANDLE_VALUE ) { win32Error = GetLastError(); global->lastError = win32Error; if( (win32Error != ERROR_FILE_NOT_FOUND) && (win32Error != ERROR_PATH_NOT_FOUND) ) { TA_DirectoryFree( dir ); return TA_ACCESS_FAILED; } /* No files or directory... but still have to pass the result * to the caller. */ *directory = dir; return TA_SUCCESS; } entryName = data.cFileName; entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #endif #if defined( USE_OSLAYER ) /* Split the path into the basePath and the filePattern. */ basePath = TA_Malloc( pathLength+1 ); memcpy( basePath, path, pathLength+1 ); filePattern = split_path_and_file( basePath ); if( !filePattern ) { /* With no filePattern, no file can be found... * so return an empty directory to the caller. */ *directory = dir; TA_Free( basePath ); return TA_SUCCESS; } /* Look for last separetor. */ if( !open_dir(&dirHandle, basePath ) ) { /* Errors, or no files or no directory... but * still have to pass the result to the caller. */ TA_Free( basePath ); *directory = dir; return TA_SUCCESS; } entryName = dirHandle.file_name; entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR; #endif do { #if defined( USE_OSLAYER ) if( file_matches( entryName, filePattern ) ) { #endif if( entryIsDirectory ) { if( entryName[0] != '.' ) { string = TA_StringAlloc( global->dirnameCache, entryName ); if( string == NULL ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } retCode = TA_ListAddTail( dir->listOfDirectory, (void *)string ); if( retCode != TA_SUCCESS ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return retCode; } dir->nbDirectory++; } } else { string = TA_StringAlloc( global->filenameCache, entryName ); if( string == NULL ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } retCode = TA_ListAddTail( dir->listOfFile, (void *)string ); if( retCode != TA_SUCCESS ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return retCode; } dir->nbFile++; } #if defined( USE_OSLAYER ) } #endif #if defined( USE_WIN32_API ) findNextRetCode = FindNextFile( handle, &data ); entryName = data.cFileName; entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #endif #if defined( USE_OSLAYER ) findNextRetCode = read_dir( &dirHandle ); entryName = dirHandle.file_name; entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR; #endif } while( findNextRetCode == TRUE ); #if defined( USE_OSLAYER ) TA_Free( basePath ); if( !close_dir(&dirHandle) ) { TA_DirectoryFree( dir ); return TA_INTERNAL_ERROR(11); } #endif #if defined( USE_WIN32_API ) if( FindClose( handle ) != TRUE ) { global->lastError = GetLastError(); TA_DirectoryFree( dir ); return TA_INTERNAL_ERROR(12); } #endif /* Pass the result to the caller. */ *directory = dir; return TA_SUCCESS; }
void TA_PrivError( unsigned int type, const char *str, const char *filename, const char *date, const char *time, int line, unsigned int j, unsigned int k ) { TA_RetCode retCode; TA_TraceGlobal *global; unsigned int length; retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return; /* If a fatal error already got handled, return * immediatly. */ if( global->fatalErrorRecorded ) return; #if !defined( TA_SINGLE_THREAD ) retCode = TA_SemaWait( &global->callSema ); if( retCode != TA_SUCCESS ) return; #endif /* Double-check inside the critical section. */ if( global->fatalErrorRecorded ) { #if !defined( TA_SINGLE_THREAD ) TA_SemaPost( &global->callSema ); #endif return; } global->fatalErrorRecorded = 1; /* Log the fatal error. */ global->fatalError.position.filename = filename; global->fatalError.position.funcname = NULL; global->fatalError.position.lineNb = line; global->fatalError.position.repetition = 1; global->fatalError.str = NULL; if( str ) { length = strlen( str ) + 1; if( length != 0 ) { global->fatalError.str = (char *)TA_Malloc( length ); memcpy( global->fatalError.str, str, length ); } } global->fatalError.date = date; global->fatalError.time = time; global->fatalError.param1 = j; global->fatalError.param2 = k; global->fatalError.type = type; /* Call the user handler. */ if( global->userHandler ) global->userHandler(); #if !defined( TA_SINGLE_THREAD ) TA_SemaPost( &global->callSema ); #endif }
TA_RetCode internalWebPageAlloc( const char *webSiteAddr, const char *webSitePage, const char *proxyName, const char *proxyPort, TA_WebPage **webPageAllocated ) { TA_PROLOG TA_RetCode retCode; TA_NetworkGlobal *global; TA_WebPage *tmpWebPage; TA_WebPageHiddenData *webPageHiddenData; if( !webSiteAddr || !webPageAllocated ) return TA_BAD_PARAM; TA_TRACE_BEGIN( TA_WebPageAlloc ); *webPageAllocated = NULL; /* Get the pointer on the global variables. */ retCode = TA_GetGlobal( &TA_NetworkGlobalControl, (void *)&global ); if( retCode != TA_SUCCESS ) { TA_TRACE_RETURN( retCode ); } /* Make sure the network library was initialized. */ if( !global->initialized ) { TA_TRACE_RETURN( TA_SOCKET_LIB_INIT_ERR ); } /* Alloc the TA_WebPage. */ tmpWebPage = (TA_WebPage *) TA_Malloc( sizeof(TA_WebPage) ); if( !tmpWebPage ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } memset( tmpWebPage, 0, sizeof( TA_WebPage ) ); /* Alloc the hidden implementation of a TA_WebPage. */ webPageHiddenData = (TA_WebPageHiddenData *) TA_Malloc( sizeof(TA_WebPageHiddenData)); if( !webPageHiddenData ) { TA_Free( tmpWebPage ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } memset( webPageHiddenData, 0, sizeof( TA_WebPageHiddenData ) ); webPageHiddenData->magicNb = TA_WEBPAGE_MAGIC_NB; webPageHiddenData->webSiteAddr = webSiteAddr; webPageHiddenData->webSitePage = webSitePage; webPageHiddenData->proxyName = proxyName; webPageHiddenData->proxyPort = proxyPort; tmpWebPage->hiddenData = webPageHiddenData; /* From this point, TA_WebPageFree shall be called to clean-up. */ #ifdef DEBUG_PRINTF printf( "Fetching [%s][%s]", webSiteAddr, webSitePage ); #endif #if defined( USE_WININET ) retCode = fetchUsingWinInet( global, tmpWebPage ); #endif #if defined( USE_LIBCURL ) retCode = fetchUsingLibCurl( global, tmpWebPage ); #endif if( retCode != TA_SUCCESS ) { /* If an error occured at any point in this module, * we are sure to free up everything by ending-up here. * It is assumed that all ressources are referenced * within the 'tmpWebPage' of course. */ TA_WebPageFree( tmpWebPage ); TA_TRACE_RETURN( retCode ); } /* Everything is fine! Return the page to the caller. */ *webPageAllocated = tmpWebPage; TA_TRACE_RETURN( TA_SUCCESS ); }