diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 1dce688df3..d5cebd3413 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,18 @@ past entries belonging to author(s): Viktor Szakats. */ +2009-07-20 13:20 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/vm/itemapi.c + * cleaned hb_itemPutC*() functions. Now each function which accepts + only pure szText pointer without length can be called with NULL + as szText. Each function which need string length parameter needs + non NULL szText value. I hope it's easy to remember for developers. + % minor code optimizations for above rules + + * harbour/source/rtl/filebuf.c + * allow to reuse tables in aliased workarea in RW mode after previous + opening in RO mode + 2009-07-20 13:02 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbssl/ssl.c * contrib/hbssl/sslctx.c diff --git a/harbour/source/rtl/filebuf.c b/harbour/source/rtl/filebuf.c index 387b0a2d20..0ed6e6ba45 100644 --- a/harbour/source/rtl/filebuf.c +++ b/harbour/source/rtl/filebuf.c @@ -85,6 +85,7 @@ typedef struct _HB_FILE BOOL shared; BOOL readonly; HB_FHANDLE hFile; + HB_FHANDLE hFileRO; PHB_FLOCK pLocks; UINT uiLocks; UINT uiSize; @@ -141,6 +142,7 @@ static PHB_FILE hb_fileNew( HB_FHANDLE hFile, BOOL fShared, BOOL fReadonly, pFile->device = device; pFile->inode = inode; pFile->hFile = hFile; + pFile->hFileRO = FS_ERROR; pFile->shared = fShared; pFile->readonly = fReadonly; @@ -332,9 +334,10 @@ PHB_FILE hb_fileExtOpen( const char * pFilename, const char * pDefExt, pFile = hb_fileFind( statbuf.st_dev, statbuf.st_ino ); if( pFile ) { - if( !fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 || - ( !fReadonly && pFile->readonly ) ) + if( !fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 ) fResult = FALSE; + else if( !fReadonly && pFile->readonly ) + pFile = NULL; else pFile->used++; } @@ -380,12 +383,48 @@ PHB_FILE hb_fileExtOpen( const char * pFilename, const char * pDefExt, hb_threadEnterCriticalSection( &s_fileMtx ); pFile = hb_fileNew( hFile, fShared, fReadonly, device, inode, TRUE ); + if( pFile->hFile != hFile ) + { + if( pFile->hFileRO == FS_ERROR && !fReadonly && pFile->readonly ) + { + pFile->hFileRO = pFile->hFile; + pFile->hFile = hFile; + pFile->readonly = FALSE; + hFile = FS_ERROR; + } + if( pFile->uiLocks == 0 ) + { +#if !defined( HB_USE_SHARELOCKS ) || defined( HB_USE_BSDLOCKS ) + if( pFile->hFileRO != FS_ERROR ) + { + hb_fsClose( pFile->hFileRO ); + pFile->hFileRO = FS_ERROR; + } +#endif + if( hFile != FS_ERROR ) + { + hb_fsClose( hFile ); + hFile = FS_ERROR; +#if defined( HB_USE_SHARELOCKS ) && !defined( HB_USE_BSDLOCKS ) + /* TOFIX: possible race condition */ + hb_fsLockLarge( hFile, HB_SHARELOCK_POS, HB_SHARELOCK_SIZE, + FL_LOCK | FLX_SHARED ); +#endif + } + } + } + else + hFile = FS_ERROR; hb_threadLeaveCriticalSection( &s_fileMtx ); - if( !pFile || pFile->hFile != hFile ) + if( hFile != FS_ERROR ) + { + /* TOFIX: possible race condition in MT mode, + * close() is not safe due to existing locks + * which are removed. + */ hb_fsClose( hFile ); - if( !pFile ) - hb_fsSetError( 32 ); + } } } hb_xfree( pszFile ); @@ -395,7 +434,7 @@ PHB_FILE hb_fileExtOpen( const char * pFilename, const char * pDefExt, void hb_fileClose( PHB_FILE pFile ) { - HB_FHANDLE hFile = FS_ERROR; + HB_FHANDLE hFile = FS_ERROR, hFileRO = FS_ERROR; hb_threadEnterCriticalSection( &s_fileMtx ); @@ -414,6 +453,7 @@ void hb_fileClose( PHB_FILE pFile ) } hFile = pFile->hFile; + hFileRO = pFile->hFileRO; if( pFile->pLocks ) hb_xfree( pFile->pLocks ); @@ -425,6 +465,8 @@ void hb_fileClose( PHB_FILE pFile ) if( hFile != FS_ERROR ) hb_fsClose( hFile ); + if( hFileRO != FS_ERROR ) + hb_fsClose( hFileRO ); } BOOL hb_fileLock( PHB_FILE pFile, HB_FOFFSET ulStart, HB_FOFFSET ulLen, diff --git a/harbour/source/vm/itemapi.c b/harbour/source/vm/itemapi.c index 16227e9843..8fdddba0c3 100644 --- a/harbour/source/vm/itemapi.c +++ b/harbour/source/vm/itemapi.c @@ -264,7 +264,7 @@ PHB_ITEM hb_itemPutCL( PHB_ITEM pItem, const char * szText, ULONG ulLen ) else { ulAlloc = 0; - szText = ( char * ) ( ulLen ? hb_szAscii[ ( unsigned char ) ( szText[ 0 ] ) ] : "" ); + szText = ( ulLen ? hb_szAscii[ ( unsigned char ) ( szText[ 0 ] ) ] : "" ); } if( pItem ) @@ -328,23 +328,17 @@ PHB_ITEM hb_itemPutCLConst( PHB_ITEM pItem, const char * szText, ULONG ulLen ) else pItem = hb_itemNew( NULL ); - if( szText == NULL ) - { - pItem->item.asString.value = ( char * ) ""; - pItem->item.asString.length = 0; - } - else - { - if( szText[ ulLen ] != '\0' ) - hb_errInternal( 6003, "Internal error: hb_itemPutCLConst() missing termination character", NULL, NULL ); - - pItem->item.asString.value = ( char * ) szText; - pItem->item.asString.length = ulLen; - } - pItem->type = HB_IT_STRING; + pItem->item.asString.length = ulLen; pItem->item.asString.allocated = 0; + if( ulLen == 0 ) + pItem->item.asString.value = ( char * ) ""; + else if( szText[ ulLen ] == '\0' ) + pItem->item.asString.value = ( char * ) szText; + else + hb_errInternal( 6003, "Internal error: hb_itemPutCLConst() missing termination character", NULL, NULL ); + return pItem; } @@ -366,7 +360,7 @@ PHB_ITEM hb_itemPutCPtr( PHB_ITEM pItem, char * szText ) pItem->type = HB_IT_STRING; pItem->item.asString.length = ulLen; - if( ulLen == 0 || szText == NULL ) + if( ulLen == 0 ) { pItem->item.asString.allocated = 0; pItem->item.asString.value = ( char * ) ""; @@ -403,12 +397,11 @@ PHB_ITEM hb_itemPutCLPtr( PHB_ITEM pItem, char * szText, ULONG ulLen ) pItem->type = HB_IT_STRING; pItem->item.asString.length = ulLen; - if( ulLen == 0 || szText == NULL ) + if( ulLen == 0 ) { pItem->item.asString.allocated = 0; pItem->item.asString.value = ( char * ) ""; - if( szText ) - hb_xfree( szText ); + hb_xfree( szText ); } else if( ulLen == 1 ) {