HB_FOFFSET hb_fsFSize( const char * pszFileName, HB_BOOL bUseDirEntry ) { if( bUseDirEntry ) { #if defined( HB_OS_WIN ) PHB_FFIND ffind = hb_fsFindFirst( pszFileName, HB_FA_ALL ); hb_fsSetIOError( ffind != NULL, 0 ); if( ffind ) { HB_FOFFSET size = ffind->size; hb_fsFindClose( ffind ); return size; } #elif defined( HB_USE_LARGEFILE64 ) char * pszFree; HB_BOOL fResult; struct stat64 statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat64( pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #else char * pszFree; HB_BOOL fResult; struct stat statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat( ( char * ) pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #endif } else { HB_FHANDLE hFileHandle = hb_fsOpen( pszFileName, FO_READ | FO_COMPAT ); if( hFileHandle != FS_ERROR ) { HB_FOFFSET nPos = hb_fsSeekLarge( hFileHandle, 0, FS_END ); hb_fsClose( hFileHandle ); return nPos; } } return 0; }
static void s_fileClose( PHB_FILE pFile ) { hb_vmUnlock(); hb_fsSetError( 0 ); hb_threadEnterCriticalSection( &s_fileMtx ); if( --pFile->used == 0 ) { if( pFile->pNext ) { pFile->pPrev->pNext = pFile->pNext; pFile->pNext->pPrev = pFile->pPrev; if( pFile == s_openFiles ) { s_openFiles = pFile->pNext; if( pFile == s_openFiles ) s_openFiles = NULL; } } if( pFile->hFile != FS_ERROR ) hb_fsClose( pFile->hFile ); if( pFile->hFileRO != FS_ERROR ) hb_fsClose( pFile->hFileRO ); if( pFile->pLocks ) hb_xfree( pFile->pLocks ); hb_xfree( pFile ); } hb_threadLeaveCriticalSection( &s_fileMtx ); hb_vmLock(); }
static int s_fileLockTest( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType ) { HB_BOOL fLocked; int iResult; hb_vmUnlock(); hb_threadEnterCriticalSection( &s_fileMtx ); fLocked = hb_fileTestLock( pFile, nStart, nLen ); hb_threadLeaveCriticalSection( &s_fileMtx ); if( fLocked ) { #if defined( HB_OS_UNIX ) iResult = getpid(); #else iResult = 1; #endif } else iResult = hb_fsLockTest( pFile->hFile, nStart, nLen, ( HB_USHORT ) iType ); hb_vmLock(); return iResult; }
void hb_fsFindClose( PHB_FFIND ffind ) { if( ffind ) { if( ffind->pszFree ) hb_xfree( ffind->pszFree ); /* Do platform dependant cleanup */ if( ffind->info ) { PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; if( ! ffind->bFirst ) { hb_vmUnlock(); #if defined( HB_OS_DOS ) # if defined( __WATCOMC__ ) _dos_findclose( &info->entry ); # elif ! defined( __DJGPP__ ) && ! defined( __BORLANDC__ ) findclose( &info->entry ); # endif #elif defined( HB_OS_OS2 ) if( info->hFindFile != HDIR_CREATE ) DosFindClose( info->hFindFile ); if( info->entry ) DosFreeMem( info->entry ); #elif defined( HB_OS_WIN ) if( info->hFindFile != INVALID_HANDLE_VALUE ) FindClose( info->hFindFile ); #elif defined( HB_OS_UNIX ) if( info->dir ) closedir( info->dir ); #else { /* Intentionally do nothing */ int iTODO; /* TODO: for given platform */ } #endif hb_vmLock(); } hb_xfree( info ); } hb_xfree( ffind ); } }
/* GZIP stream destructor */ static HB_GARBAGE_FUNC( hb_gz_Destructor ) { gzFile * gzHolder = ( gzFile * ) Cargo; if( *gzHolder ) { hb_vmUnlock(); gzclose( *gzHolder ); hb_vmLock(); *gzHolder = NULL; } }
static HB_BOOL s_fileLock( PHB_FILE pFile, HB_FOFFSET nStart, HB_FOFFSET nLen, int iType ) { HB_BOOL fResult, fLockFS = HB_FALSE; hb_vmUnlock(); if( ( iType & FL_MASK ) == FL_UNLOCK ) { hb_threadEnterCriticalSection( &s_lockMtx ); fResult = hb_fileUnlock( pFile, &fLockFS, nStart, nLen ); hb_threadLeaveCriticalSection( &s_lockMtx ); if( fLockFS ) { hb_fsLockLarge( pFile->hFile, nStart, nLen, ( HB_USHORT ) iType ); hb_threadEnterCriticalSection( &s_lockMtx ); hb_fileUnlock( pFile, NULL, nStart, nLen ); hb_threadLeaveCriticalSection( &s_lockMtx ); } else hb_fsSetError( fResult ? 0 : 33 ); } else { hb_threadEnterCriticalSection( &s_lockMtx ); fResult = hb_fileSetLock( pFile, &fLockFS, nStart, nLen ); hb_threadLeaveCriticalSection( &s_lockMtx ); if( fLockFS ) { #if defined( HB_OS_UNIX ) if( pFile->mode == FO_READ ) iType |= FLX_SHARED; else if( pFile->mode == FO_WRITE ) iType &= ~FLX_SHARED; #endif fResult = hb_fsLockLarge( pFile->hFile, nStart, nLen, ( HB_USHORT ) iType ); if( ! fResult ) { hb_threadEnterCriticalSection( &s_lockMtx ); hb_fileUnlock( pFile, NULL, nStart, nLen ); hb_threadLeaveCriticalSection( &s_lockMtx ); } } else hb_fsSetError( fResult ? 0 : 33 ); } hb_vmLock(); return fResult; }
static HB_BOOL hb_IsNetShared( const char * szLocalDevice ) { TCHAR lpRemoteDevice[ HB_PATH_MAX ]; LPCTSTR lpLocalDevice; LPTSTR lpFree; DWORD dwLen = HB_SIZEOFARRAY( lpRemoteDevice ); DWORD dwResult; lpLocalDevice = HB_FSNAMECONV( szLocalDevice, &lpFree ); hb_vmUnlock(); dwResult = WNetGetConnection( lpLocalDevice, lpRemoteDevice, &dwLen ); hb_vmLock(); if( lpFree ) hb_xfree( lpFree ); return dwResult == NO_ERROR; }
HB_BOOL hb_fileRegisterFull( const HB_FILE_FUNCS * pFuncs ) { HB_BOOL fResult = HB_FALSE; hb_vmUnlock(); hb_threadEnterCriticalSection( &s_fileMtx ); if( s_iFileTypes < HB_FILE_TYPE_MAX ) { s_pFileTypes[ s_iFileTypes ] = pFuncs; s_iFileTypes++; fResult = HB_TRUE; } hb_threadLeaveCriticalSection( &s_fileMtx ); hb_vmLock(); return fResult; }
static PHB_FILE s_fileExtOpen( PHB_FILE_FUNCS pFuncs, const char * pszFileName, const char * pDefExt, HB_FATTR nExFlags, const char * pPaths, PHB_ITEM pError ) { PHB_FILE pFile = NULL; #if defined( HB_OS_UNIX ) HB_BOOL fSeek = HB_FALSE; # if defined( HB_USE_LARGEFILE64 ) struct stat64 statbuf; # else struct stat statbuf; # endif #endif HB_BOOL fResult, fShared; int iMode; HB_FHANDLE hFile; char * pszFile; HB_SYMBOL_UNUSED( pFuncs ); fShared = ( nExFlags & ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ) ) == 0; iMode = ( int ) ( nExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) ); pszFile = hb_fsExtName( pszFileName, pDefExt, nExFlags, pPaths ); hb_vmUnlock(); #if ! defined( HB_OS_UNIX ) fResult = HB_TRUE; #else # if defined( HB_USE_SHARELOCKS ) && ! defined( HB_USE_BSDLOCKS ) if( nExFlags & FXO_SHARELOCK ) { if( iMode == FO_WRITE && fShared ) { if( access( ( char * ) pszFile, R_OK ) == 0 || access( ( char * ) pszFile, F_OK ) != 0 ) { nExFlags = ( nExFlags ^ FO_WRITE ) | FO_READWRITE; iMode = FO_READWRITE; } else nExFlags ^= FXO_SHARELOCK; } else if( iMode == FO_READ && ! fShared ) { nExFlags &= ~ ( HB_FATTR ) ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ); fShared = HB_TRUE; } } # endif hb_threadEnterCriticalSection( &s_fileMtx ); # if defined( HB_USE_LARGEFILE64 ) fResult = stat64( ( char * ) pszFile, &statbuf ) == 0; # else fResult = stat( ( char * ) pszFile, &statbuf ) == 0; # endif hb_fsSetIOError( fResult, 0 ); if( fResult ) { pFile = hb_fileFind( ( HB_ULONG ) statbuf.st_dev, ( HB_ULONG ) statbuf.st_ino ); if( pFile ) { if( ! fShared || ! pFile->shared || ( nExFlags & FXO_TRUNCATE ) != 0 ) { fResult = HB_FALSE; pFile = NULL; } else if( pFile->mode != FO_READWRITE && pFile->mode != iMode ) { iMode = FO_READWRITE; pFile = NULL; } else { pFile->used++; if( ( nExFlags & FXO_NOSEEKPOS ) == 0 ) { # if defined( HB_OS_VXWORKS ) fSeek = ! S_ISFIFO( statbuf.st_mode ); # else fSeek = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode ); # endif } } } } else fResult = HB_TRUE; if( fResult && pFile == NULL ) #endif /* HB_OS_UNIX */ { hFile = hb_fsExtOpen( pszFile, NULL, nExFlags & ~ ( HB_FATTR ) ( FXO_DEFAULTS | FXO_COPYNAME ), NULL, NULL ); if( hFile != FS_ERROR ) { HB_ULONG device = 0, inode = 0; #if ! defined( HB_OS_UNIX ) hb_threadEnterCriticalSection( &s_fileMtx ); #else # if defined( HB_USE_LARGEFILE64 ) if( fstat64( hFile, &statbuf ) == 0 ) # else if( fstat( hFile, &statbuf ) == 0 ) # endif { device = ( HB_ULONG ) statbuf.st_dev; inode = ( HB_ULONG ) statbuf.st_ino; if( ( nExFlags & FXO_NOSEEKPOS ) == 0 ) { # if defined( HB_OS_VXWORKS ) fSeek = ! S_ISFIFO( statbuf.st_mode ); # else fSeek = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode ); # endif } } #endif /* HB_OS_UNIX */ pFile = hb_fileNew( hFile, fShared, iMode, device, inode, HB_TRUE ); if( pFile->hFile != hFile ) { if( pFile->mode != FO_READWRITE && iMode == FO_READWRITE ) { HB_FHANDLE hTemp = pFile->hFileRO; pFile->hFileRO = pFile->hFile; pFile->hFile = hFile; pFile->mode = iMode; hFile = hTemp; } if( ! fShared || ! pFile->shared || pFile->mode != FO_READWRITE ) { fResult = HB_FALSE; if( pFile->hFileRO == FS_ERROR && pFile->uiLocks != 0 ) { pFile->hFileRO = hFile; 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( pFile->hFile, HB_SHARELOCK_POS, HB_SHARELOCK_SIZE, FL_LOCK | FLX_SHARED ); #endif } } if( !fResult ) { if( pFile ) { --pFile->used; pFile = NULL; } 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 ! defined( HB_OS_UNIX ) hb_threadLeaveCriticalSection( &s_fileMtx ); #endif } } #if defined( HB_OS_UNIX ) hb_threadLeaveCriticalSection( &s_fileMtx ); if( pFile && fSeek ) pFile = hb_fileposNew( pFile ); #endif if( ! fResult ) hb_fsSetError( ( nExFlags & FXO_TRUNCATE ) ? 5 : 32 ); if( ( nExFlags & FXO_COPYNAME ) != 0 && pFile ) hb_strncpy( ( char * ) HB_UNCONST( pszFileName ), pszFile, HB_PATH_MAX - 1 ); if( pError ) { hb_errPutFileName( pError, pszFile ); if( ! fResult ) { hb_errPutOsCode( pError, hb_fsError() ); hb_errPutGenCode( pError, ( HB_ERRCODE ) ( ( nExFlags & FXO_TRUNCATE ) ? EG_CREATE : EG_OPEN ) ); } } hb_xfree( pszFile ); hb_vmLock(); return pFile; }
HB_BOOL hb_fsLink( const char * pszExisting, const char * pszNewFile ) { HB_BOOL fResult; if( pszExisting && pszNewFile ) { hb_vmUnlock(); #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) { typedef BOOL ( WINAPI * _HB_CREATEHARDLINK )( LPCTSTR, LPCTSTR, LPSECURITY_ATTRIBUTES ); static _HB_CREATEHARDLINK s_pCreateHardLink = NULL; if( ! s_pCreateHardLink ) { HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); if( hModule ) s_pCreateHardLink = ( _HB_CREATEHARDLINK ) HB_WINAPI_GETPROCADDRESST( hModule, "CreateHardLink" ); } if( s_pCreateHardLink ) { LPCTSTR lpFileName, lpExistingFileName; LPTSTR lpFileNameFree, lpExistingFileNameFree; lpFileName = HB_FSNAMECONV( pszNewFile, &lpFileNameFree ); lpExistingFileName = HB_FSNAMECONV( pszExisting, &lpExistingFileNameFree ); fResult = s_pCreateHardLink( lpFileName, lpExistingFileName, NULL ) != 0; hb_fsSetIOError( fResult, 0 ); if( lpFileNameFree ) hb_xfree( lpFileNameFree ); if( lpExistingFileNameFree ) hb_xfree( lpExistingFileNameFree ); } else { hb_fsSetError( 1 ); fResult = HB_FALSE; } } #elif defined( HB_OS_UNIX ) { char * pszExistingFree; char * pszNewFileFree; pszExisting = hb_fsNameConv( pszExisting, &pszExistingFree ); pszNewFile = hb_fsNameConv( pszNewFile, &pszNewFileFree ); fResult = ( link( pszExisting, pszNewFile ) == 0 ); hb_fsSetIOError( fResult, 0 ); if( pszExistingFree ) hb_xfree( pszExistingFree ); if( pszNewFileFree ) hb_xfree( pszNewFileFree ); } #else { hb_fsSetError( 1 ); fResult = HB_FALSE; } #endif hb_vmLock(); } else { hb_fsSetError( 2 ); fResult = HB_FALSE; } return fResult; }
static int hb_fsProcessExec( const char * pszFileName, HB_FHANDLE hStdin, HB_FHANDLE hStdout, HB_FHANDLE hStderr ) { int iResult = FS_ERROR; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessExec(%s, %p, %p, %p)", pszFileName, ( void * ) ( HB_PTRUINT ) hStdin, ( void * ) ( HB_PTRUINT ) hStdout, ( void * ) ( HB_PTRUINT ) hStderr ) ); #if defined( HB_OS_WIN_CE ) { LPTSTR lpAppName, lpParams; HB_BOOL fError; HB_SYMBOL_UNUSED( hStdin ); HB_SYMBOL_UNUSED( hStdout ); HB_SYMBOL_UNUSED( hStderr ); hb_getCommand( pszFileName, &lpAppName, &lpParams ); hb_vmUnlock(); fError = ! CreateProcess( lpAppName, /* lpAppName */ lpParams, /* lpCommandLine */ NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ FALSE, /* bInheritHandles */ 0, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ NULL, /* lpStartupInfo */ NULL ); /* lpProcessInformation */ hb_fsSetIOError( ! fError, 0 ); if( ! fError ) iResult = 0; hb_vmLock(); if( lpAppName ) hb_xfree( lpAppName ); if( lpParams ) hb_xfree( lpParams ); } #elif defined( HB_OS_DOS ) || defined( HB_OS_WIN ) || defined( HB_OS_OS2 ) || \ defined( HB_OS_UNIX ) { int iStdIn, iStdOut, iStdErr; char ** argv; argv = hb_buildArgs( pszFileName ); hb_vmUnlock(); iStdIn = iStdOut = iStdErr = FS_ERROR; if( hStdin != FS_ERROR ) { iStdIn = dup( 0 ); dup2( hStdin, 0 ); } if( hStdout != FS_ERROR ) { iStdOut = dup( 1 ); dup2( hStdout, 1 ); } if( hStderr != FS_ERROR ) { iStdErr = dup( 2 ); dup2( hStderr, 2 ); } #if defined( HB_OS_UNIX ) && ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) { pid_t pid = fork(); if( pid == 0 ) { /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ ( void ) setuid( getuid() ); ( void ) setgid( getgid() ); /* execute command */ execvp( argv[ 0 ], argv ); exit( -1 ); } else if( pid != -1 ) { int iStatus; iResult = waitpid( pid, &iStatus, 0 ); #ifdef ERESTARTSYS if( iResult < 0 && errno != ERESTARTSYS ) #else if( iResult < 0 ) #endif iResult = -2; else if( iResult == 0 ) iResult = -1; else iResult = WIFEXITED( iStatus ) ? WEXITSTATUS( iStatus ) : 0; } } #elif defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) iResult = _spawnvp( _P_WAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) iResult = spawnvp( P_WAIT, argv[ 0 ], ( const char * const * ) argv ); #else iResult = spawnvp( P_WAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_fsSetIOError( iResult >= 0, 0 ); if( iStdIn != FS_ERROR ) { dup2( iStdIn, 0 ); close( iStdIn ); } if( iStdOut != FS_ERROR ) { dup2( iStdOut, 1 ); close( iStdOut ); } if( iStdErr != FS_ERROR ) { dup2( iStdErr, 2 ); close( iStdErr ); } hb_vmLock(); hb_freeArgs( argv ); } #else { int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFileName ); HB_SYMBOL_UNUSED( hStdin ); HB_SYMBOL_UNUSED( hStdout ); HB_SYMBOL_UNUSED( hStderr ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #endif return iResult; }
int hb_fsProcessValue( HB_FHANDLE hProcess, HB_BOOL fWait ) { int iRetStatus = -1; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessValue(%p, %d)", ( void * ) ( HB_PTRUINT ) hProcess, fWait ) ); #if defined( HB_OS_WIN ) { HB_BOOL fError = HB_TRUE; DWORD dwResult; HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess ); if( hProc ) { hb_vmUnlock(); dwResult = WaitForSingleObject( hProc, fWait ? INFINITE : 0 ); if( dwResult == WAIT_OBJECT_0 ) { fError = ! GetExitCodeProcess( hProc, &dwResult ); iRetStatus = ! fError ? ( int ) dwResult : -2; } hb_fsSetIOError( ! fError, 0 ); if( ! fError ) CloseHandle( hProc ); hb_vmLock(); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif defined( HB_OS_OS2 ) { PID pid = ( PID ) hProcess; if( pid > 0 ) { RESULTCODES resultCodes = { 0, 0 }; APIRET ret; hb_vmUnlock(); ret = DosWaitChild( DCWA_PROCESS, fWait ? DCWW_WAIT : DCWW_NOWAIT, &resultCodes, &pid, pid ); hb_fsSetError( ( HB_ERRCODE ) ret ); if( ret == NO_ERROR ) iRetStatus = resultCodes.codeResult; else iRetStatus = -2; hb_vmLock(); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif defined( HB_OS_UNIX ) { int iStatus; pid_t pid = ( pid_t ) hProcess; if( pid > 0 ) { hb_vmUnlock(); iRetStatus = waitpid( pid, &iStatus, fWait ? 0 : WNOHANG ); hb_fsSetIOError( iRetStatus >= 0, 0 ); #ifdef ERESTARTSYS if( iRetStatus < 0 && hb_fsOsError() != ( HB_ERRCODE ) ERESTARTSYS ) #else if( iRetStatus < 0 ) #endif iRetStatus = -2; else if( iRetStatus == 0 ) iRetStatus = -1; else iRetStatus = WIFEXITED( iStatus ) ? WEXITSTATUS( iStatus ) : 0; hb_vmLock(); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #else { int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( hProcess ); HB_SYMBOL_UNUSED( fWait ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #endif return iRetStatus; }
static HB_BOOL hb_fsFindNextLow( PHB_FFIND ffind ) { HB_BOOL bFound; int iYear = 0; int iMonth = 0; int iDay = 0; int iHour = 0; int iMin = 0; int iSec = 0; int iMSec = 0; HB_FATTR raw_attr = 0, nAttr = 0; /* Set the default values in case some platforms don't support some of these, or they may fail on them. */ ffind->szName[ 0 ] = '\0'; ffind->size = 0; /* Do platform dependant first/next search */ hb_vmUnlock(); #if defined( HB_OS_DOS ) { PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; /* Handling HB_FA_LABEL doesn't need any special tricks under the MS-DOS platform. */ if( ffind->bFirst ) { ffind->bFirst = HB_FALSE; /* tzset(); */ #if defined( __WATCOMC__ ) bFound = ( _dos_findfirst( ffind->pszFileMask, ( HB_USHORT ) hb_fsAttrToRaw( ffind->attrmask ), &info->entry ) == 0 ); #else bFound = ( findfirst( ffind->pszFileMask, &info->entry, ( HB_USHORT ) hb_fsAttrToRaw( ffind->attrmask ) ) == 0 ); #endif } else { #if defined( __WATCOMC__ ) bFound = ( _dos_findnext( &info->entry ) == 0 ); #else bFound = ( findnext( &info->entry ) == 0 ); #endif } /* Fill Harbour found file info */ if( bFound ) { hb_strncpy( ffind->szName, info->entry.ff_name, sizeof( ffind->szName ) - 1 ); ffind->size = info->entry.ff_fsize; raw_attr = info->entry.ff_attrib; { time_t ftime; struct tm * ft; struct stat sStat; stat( info->entry.ff_name, &sStat ); ftime = sStat.st_mtime; ft = localtime( &ftime ); iYear = ft->tm_year + 1900; iMonth = ft->tm_mon + 1; iDay = ft->tm_mday; iHour = ft->tm_hour; iMin = ft->tm_min; iSec = ft->tm_sec; } } hb_fsSetIOError( bFound, 0 ); } #elif defined( HB_OS_OS2 ) { #define HB_OS2_DIRCNT 16 PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; APIRET ret = NO_ERROR; /* TODO: HB_FA_LABEL handling */ if( ffind->bFirst ) { ffind->bFirst = HB_FALSE; info->isWSeB = hb_isWSeB(); info->findSize = sizeof( FILEFINDBUF3L ); if( info->findSize & 0x07 ) info->findSize += 0x08 - ( info->findSize & 0x07 ); info->findSize *= HB_OS2_DIRCNT; if( info->findSize > 0xF000 ) info->findSize = 0xF000; info->findInitCnt = ! info->isWSeB ? info->findSize / 32 : HB_OS2_DIRCNT; info->hFindFile = HDIR_CREATE; info->findCount = info->findInitCnt; ret = DosAllocMem( &info->entry, info->findSize, OBJ_TILE | PAG_COMMIT | PAG_WRITE ); if( ret == NO_ERROR ) { ret = DosFindFirst( ( PCSZ ) ffind->pszFileMask, &info->hFindFile, ( ULONG ) hb_fsAttrToRaw( ffind->attrmask ), info->entry, info->findSize, &info->findCount, FIL_STANDARDL ); bFound = ret == NO_ERROR && info->findCount > 0; if( bFound ) info->next = info->entry; } else { info->entry = NULL; bFound = HB_FALSE; } } else if( info->findCount == 0 ) { info->findCount = info->findInitCnt; ret = DosFindNext( info->hFindFile, info->entry, info->findSize, &info->findCount ); bFound = ret == NO_ERROR && info->findCount > 0; if( bFound ) info->next = info->entry; } else bFound = HB_TRUE; if( bFound ) { ULONG oNextEntryOffset; if( info->isWSeB ) { PFILEFINDBUF3L pFFB = ( PFILEFINDBUF3L ) info->next; hb_strncpy( ffind->szName, pFFB->achName, sizeof( ffind->szName ) - 1 ); ffind->size = ( HB_FOFFSET ) pFFB->cbFile; raw_attr = pFFB->attrFile; iYear = pFFB->fdateLastWrite.year + 1980; iMonth = pFFB->fdateLastWrite.month; iDay = pFFB->fdateLastWrite.day; iHour = pFFB->ftimeLastWrite.hours; iMin = pFFB->ftimeLastWrite.minutes; iSec = pFFB->ftimeLastWrite.twosecs * 2; oNextEntryOffset = pFFB->oNextEntryOffset; } else { PFILEFINDBUF3 pFFB = ( PFILEFINDBUF3 ) info->next; hb_strncpy( ffind->szName, pFFB->achName, sizeof( ffind->szName ) - 1 ); ffind->size = ( HB_FOFFSET ) pFFB->cbFile; raw_attr = pFFB->attrFile; iYear = pFFB->fdateLastWrite.year + 1980; iMonth = pFFB->fdateLastWrite.month; iDay = pFFB->fdateLastWrite.day; iHour = pFFB->ftimeLastWrite.hours; iMin = pFFB->ftimeLastWrite.minutes; iSec = pFFB->ftimeLastWrite.twosecs * 2; oNextEntryOffset = pFFB->oNextEntryOffset; } if( oNextEntryOffset > 0 ) { info->next = ( char * ) info->next + oNextEntryOffset; info->findCount--; } else info->findCount = 0; } hb_fsSetError( ( HB_ERRCODE ) ret ); } #elif defined( HB_OS_WIN ) { PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; bFound = HB_FALSE; #if ! defined( HB_OS_WIN_CE ) if( ( ffind->attrmask & HB_FA_LABEL ) != 0 && ! info->fLabelDone ) { TCHAR lpVolName[ HB_PATH_MAX ]; LPTSTR lpFileMask = NULL; char * mask = NULL; info->fLabelDone = HB_TRUE; if( ffind->pszFileMask && *ffind->pszFileMask ) { PHB_FNAME pFileName = hb_fsFNameSplit( ffind->pszFileMask ); if( pFileName->szName && pFileName->szName[ 0 ] ) mask = hb_strdup( pFileName->szName ); if( pFileName->szPath && pFileName->szPath[ 0 ] && ( pFileName->szPath[ 1 ] || pFileName->szPath[ 0 ] != HB_OS_PATH_DELIM_CHR ) ) lpFileMask = HB_CHARDUP( pFileName->szPath ); hb_xfree( pFileName ); } bFound = GetVolumeInformation( lpFileMask, lpVolName, HB_SIZEOFARRAY( lpVolName ), NULL, NULL, NULL, NULL, 0 ) != 0; if( bFound ) { HB_OSSTRDUP2( lpVolName, ffind->szName, sizeof( ffind->szName ) - 1 ); if( mask && *mask && ! hb_strMatchFile( ffind->szName, mask ) ) { ffind->szName[ 0 ] = '\0'; bFound = HB_FALSE; } } if( lpFileMask ) hb_xfree( lpFileMask ); if( mask ) hb_xfree( mask ); } #endif if( ! bFound && ( ffind->attrmask & ( HB_FA_LABEL | HB_FA_HIDDEN | HB_FA_SYSTEM | HB_FA_DIRECTORY ) ) != HB_FA_LABEL ) { if( ffind->bFirst ) { LPTSTR lpFileMask = HB_CHARDUP( ffind->pszFileMask ); ffind->bFirst = HB_FALSE; info->dwAttr = ( DWORD ) hb_fsAttrToRaw( ffind->attrmask ); info->hFindFile = FindFirstFile( lpFileMask, &info->pFindFileData ); hb_xfree( lpFileMask ); if( ( info->hFindFile != INVALID_HANDLE_VALUE ) && _HB_WIN_MATCH() ) bFound = HB_TRUE; } if( ! bFound && info->hFindFile != INVALID_HANDLE_VALUE ) { while( FindNextFile( info->hFindFile, &info->pFindFileData ) ) { if( _HB_WIN_MATCH() ) { bFound = HB_TRUE; break; } } } /* Fill Harbour found file info */ if( bFound ) { HB_OSSTRDUP2( info->pFindFileData.cFileName, ffind->szName, sizeof( ffind->szName ) - 1 ); if( info->pFindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ffind->size = 0; else { #if defined( __XCC__ ) || ( defined( __POCC__ ) && __POCC__ >= 500 ) /* NOTE: PellesC 5.00.1 will go into an infinite loop if we don't split this into two operations. [vszakats] */ ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow; ffind->size += ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32; #else ffind->size = ( HB_FOFFSET ) info->pFindFileData.nFileSizeLow + ( ( HB_FOFFSET ) info->pFindFileData.nFileSizeHigh << 32 ); #endif } raw_attr = ( HB_FATTR ) info->pFindFileData.dwFileAttributes; /* NOTE: One of these may fail when searching on an UNC path, I don't know yet what's the reason. [vszakats] */ { FILETIME ft; SYSTEMTIME time; if( FileTimeToLocalFileTime( &info->pFindFileData.ftLastWriteTime, &ft ) && FileTimeToSystemTime( &ft, &time ) ) { iYear = time.wYear; iMonth = time.wMonth; iDay = time.wDay; iHour = time.wHour; iMin = time.wMinute; iSec = time.wSecond; iMSec = time.wMilliseconds; } } } } hb_fsSetIOError( bFound, 0 ); } #elif defined( HB_OS_UNIX ) { PHB_FFIND_INFO info = ( PHB_FFIND_INFO ) ffind->info; char dirname[ HB_PATH_MAX ]; bFound = HB_FALSE; /* TODO: HB_FA_LABEL handling */ if( ffind->bFirst ) { char * pos; ffind->bFirst = HB_FALSE; hb_strncpy( dirname, ffind->pszFileMask, sizeof( dirname ) - 1 ); pos = strrchr( dirname, HB_OS_PATH_DELIM_CHR ); if( pos ) { hb_strncpy( info->pattern, pos + 1, sizeof( info->pattern ) - 1 ); *( pos + 1 ) = '\0'; } else { hb_strncpy( info->pattern, dirname, sizeof( info->pattern ) - 1 ); dirname[ 0 ] = '.'; dirname[ 1 ] = HB_OS_PATH_DELIM_CHR; dirname[ 2 ] = '\0'; } /* tzset(); */ info->dir = opendir( dirname ); hb_strncpy( info->path, dirname, sizeof( info->path ) - 1 ); } if( info->dir && info->pattern[ 0 ] != '\0' ) { while( ( info->entry = readdir( info->dir ) ) != NULL ) { if( hb_strMatchFile( info->entry->d_name, info->pattern ) ) { bFound = HB_TRUE; break; } } } /* Fill Harbour found file info */ if( bFound ) { hb_strncpy( dirname, info->path, sizeof( dirname ) - 1 ); hb_strncat( dirname, info->entry->d_name, sizeof( dirname ) - 1 ); { time_t ftime; struct tm lt; #if defined( HB_USE_LARGEFILE64 ) struct stat64 sStat, sStatL; if( lstat64( dirname, &sStat ) == 0 ) { if( S_ISLNK( sStat.st_mode ) && ( ffind->attrmask & HB_FA_LINK ) == 0 ) { if( stat64( dirname, &sStatL ) == 0 ) memcpy( &sStat, &sStatL, sizeof( sStat ) ); nAttr |= HB_FA_LINK; } #else struct stat sStat, sStatL; if( lstat( dirname, &sStat ) == 0 ) { if( S_ISLNK( sStat.st_mode ) && ( ffind->attrmask & HB_FA_LINK ) == 0 ) { if( stat( dirname, &sStatL ) == 0 ) memcpy( &sStat, &sStatL, sizeof( sStat ) ); nAttr |= HB_FA_LINK; } #endif hb_strncpy( ffind->szName, info->entry->d_name, sizeof( ffind->szName ) - 1 ); ffind->size = sStat.st_size; raw_attr = sStat.st_mode; ftime = sStat.st_mtime; # if defined( HB_HAS_LOCALTIME_R ) localtime_r( &ftime, < ); # else lt = *localtime( &ftime ); # endif iYear = lt.tm_year + 1900; iMonth = lt.tm_mon + 1; iDay = lt.tm_mday; iHour = lt.tm_hour; iMin = lt.tm_min; iSec = lt.tm_sec; # if defined( HB_OS_LINUX ) && \ defined( __GLIBC__ ) && defined( __GLIBC_MINOR__ ) && \ ( __GLIBC__ > 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ >= 6 ) ) # if defined( _BSD_SOURCE ) || defined( _SVID_SOURCE ) || \ ( __GLIBC_MINOR__ >= 12 && \ ( ( defined( _POSIX_C_SOURCE ) || _POSIX_C_SOURCE >= 200809L ) || \ ( defined( _XOPEN_SOURCE ) || _XOPEN_SOURCE >= 700 ) ) ) iMSec = sStat.st_mtim.tv_nsec / 1000000; # else iMSec = sStat.st_mtimensec / 1000000; # endif # endif } else bFound = HB_FALSE; } } hb_fsSetIOError( bFound, 0 ); } #else { int iTODO; /* TODO: for given platform */ /* HB_SYMBOL_UNUSED( ffind ); */ HB_SYMBOL_UNUSED( iYear ); HB_SYMBOL_UNUSED( iMonth ); HB_SYMBOL_UNUSED( iDay ); HB_SYMBOL_UNUSED( iHour ); HB_SYMBOL_UNUSED( iMin ); HB_SYMBOL_UNUSED( iSec ); HB_SYMBOL_UNUSED( iMSec ); HB_SYMBOL_UNUSED( raw_attr ); bFound = HB_FALSE; hb_fsSetIOError( bFound, 0 ); } #endif /* Fill common Harbour found file info */ if( bFound ) { /* Do the conversions common for all platforms */ ffind->szName[ sizeof( ffind->szName ) - 1 ] = '\0'; #if ! defined( HB_OS_WIN ) /* Convert from OS codepage */ { char * pszFree = NULL; HB_SIZE nSize = sizeof( ffind->szName ); const char * pszResult = hb_osDecodeCP( ffind->szName, &pszFree, &nSize ); if( pszFree ) { hb_strncpy( ffind->szName, pszResult, sizeof( ffind->szName ) - 1 ); hb_xfree( pszFree ); } } #endif ffind->attr = hb_fsAttrFromRaw( raw_attr ) | nAttr; ffind->lDate = hb_dateEncode( iYear, iMonth, iDay ); ffind->lTime = hb_timeEncode( iHour, iMin, iSec, iMSec ); hb_dateStrPut( ffind->szDate, iYear, iMonth, iDay ); ffind->szDate[ 8 ] = '\0'; hb_snprintf( ffind->szTime, sizeof( ffind->szTime ), "%02d:%02d:%02d", iHour, iMin, iSec ); } hb_vmLock(); return bFound; } PHB_FFIND hb_fsFindFirst( const char * pszFileMask, HB_FATTR attrmask ) { PHB_FFIND ffind = ( PHB_FFIND ) hb_xgrabz( sizeof( HB_FFIND ) ); /* Allocate platform dependent file find info storage */ ffind->info = ( void * ) hb_xgrabz( sizeof( HB_FFIND_INFO ) ); /* Store search parameters */ #if defined( HB_OS_WIN ) ffind->pszFileMask = pszFileMask; #else /* Convert to OS codepage */ ffind->pszFileMask = hb_fsNameConv( pszFileMask, &ffind->pszFree ); #endif ffind->attrmask = attrmask; ffind->bFirst = HB_TRUE; /* Find first/next matching file */ if( hb_fsFindNext( ffind ) ) return ffind; /* If no file found at all, free stuff allocated so far and return NULL. */ hb_fsFindClose( ffind ); return NULL; }
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(); }
static HB_BOOL hb_fsTempName( char * pszBuffer, const char * pszDir, const char * pszPrefix ) { HB_BOOL fResult; pszBuffer[ 0 ] = '\0'; hb_vmUnlock(); #if defined( HB_OS_WIN ) { LPCTSTR lpPrefix, lpDir; LPTSTR lpPrefixFree = NULL, lpDirFree = NULL; TCHAR lpBuffer[ HB_PATH_MAX ]; TCHAR lpTempDir[ HB_PATH_MAX ]; lpPrefix = pszPrefix ? HB_FSNAMECONV( pszPrefix, &lpPrefixFree ) : NULL; if( pszDir && pszDir[ 0 ] != '\0' ) lpDir = HB_FSNAMECONV( pszDir, &lpDirFree ); else { if( ! GetTempPath( HB_PATH_MAX, lpTempDir ) ) { hb_fsSetIOError( HB_FALSE, 0 ); return HB_FALSE; } lpTempDir[ HB_PATH_MAX - 1 ] = TEXT( '\0' ); lpDir = lpTempDir; } fResult = GetTempFileName( lpDir, lpPrefix ? lpPrefix : TEXT( "hb" ), 0, lpBuffer ); if( fResult ) HB_OSSTRDUP2( lpBuffer, pszBuffer, HB_PATH_MAX - 1 ); if( lpPrefixFree ) hb_xfree( lpPrefixFree ); if( lpDirFree ) hb_xfree( lpDirFree ); } #else { char * pTmpBuffer = hb_xgrab( L_tmpnam + 1 ); /* TODO: Implement these: */ HB_SYMBOL_UNUSED( pszDir ); HB_SYMBOL_UNUSED( pszPrefix ); pTmpBuffer[ 0 ] = '\0'; fResult = ( tmpnam( pszBuffer ) != NULL ); pTmpBuffer[ L_tmpnam ] = '\0'; if( fResult ) { # if defined( __DJGPP__ ) /* convert '/' to '\' */ char * pszDelim = pTmpBuffer; while( ( pszDelim = strchr( pszDelim, '/' ) ) != NULL ) *pszDelim = '\\'; # endif hb_osStrDecode2( pTmpBuffer, pszBuffer, HB_PATH_MAX - 1 ); } hb_xfree( pTmpBuffer ); } #endif hb_fsSetIOError( fResult, 0 ); hb_vmLock(); return fResult; }
HB_FHANDLE hb_fsCreateTempEx( char * pszName, const char * pszDir, const char * pszPrefix, const char * pszExt, HB_FATTR ulAttr ) { /* less attemps */ int iAttemptLeft = 99, iLen; HB_FHANDLE fd; do { pszName[ 0 ] = '\0'; if( pszDir && pszDir[ 0 ] != '\0' ) { hb_strncpy( pszName, pszDir, HB_PATH_MAX - 1 ); iLen = ( int ) strlen( pszName ); if( pszName[ iLen - 1 ] != HB_OS_PATH_DELIM_CHR && iLen < HB_PATH_MAX - 1 ) { pszName[ iLen ] = HB_OS_PATH_DELIM_CHR; pszName[ iLen + 1 ] = '\0'; } } else hb_fsTempDir( pszName ); if( pszPrefix ) hb_strncat( pszName, pszPrefix, HB_PATH_MAX - 1 ); iLen = ( int ) strlen( pszName ); if( iLen > ( HB_PATH_MAX - 1 ) - 6 - ( pszExt ? ( int ) strlen( pszExt ) : 0 ) ) { fd = FS_ERROR; break; } #if defined( HB_HAS_MKSTEMP ) if( hb_setGetFileCase() != HB_SET_CASE_LOWER && hb_setGetFileCase() != HB_SET_CASE_UPPER && hb_setGetDirCase() != HB_SET_CASE_LOWER && hb_setGetDirCase() != HB_SET_CASE_UPPER #if ! defined( HB_HAS_MKSTEMPS ) && ( pszExt == NULL || *pszExt == 0 ) #endif ) { hb_vmUnlock(); hb_strncat( pszName, "XXXXXX", HB_PATH_MAX - 1 ); #if defined( HB_HAS_MKSTEMPS ) if( pszExt && *pszExt ) { hb_strncat( pszName, pszExt, HB_PATH_MAX - 1 ); #if defined( HB_USE_LARGEFILE64 ) fd = ( HB_FHANDLE ) mkstemps64( pszName, ( int ) strlen( pszExt ) ); #else fd = ( HB_FHANDLE ) mkstemps( pszName, ( int ) strlen( pszExt ) ); #endif } else #endif #if defined( HB_USE_LARGEFILE64 ) fd = ( HB_FHANDLE ) mkstemp64( pszName ); #else fd = ( HB_FHANDLE ) mkstemp( pszName ); #endif hb_fsSetIOError( fd != ( HB_FHANDLE ) -1, 0 ); hb_vmLock(); } else #endif /* HB_HAS_MKSTEMP */ { int i, n; double d = hb_random_num(), x; for( i = 0; i < 6; i++ ) { d = d * 36; n = ( int ) d; d = modf( d, &x ); pszName[ iLen++ ] = ( char ) ( n + ( n > 9 ? 'a' - 10 : '0' ) ); } pszName[ iLen ] = '\0'; if( pszExt ) hb_strncat( pszName, pszExt, HB_PATH_MAX - 1 ); fd = hb_fsCreateEx( pszName, ulAttr, FO_EXCLUSIVE | FO_EXCL ); } if( fd != ( HB_FHANDLE ) FS_ERROR ) break; } while( --iAttemptLeft ); return fd; }
HB_BOOL hb_fsLinkSym( const char * pszTarget, const char * pszNewFile ) { HB_BOOL fResult; if( pszTarget && pszNewFile ) { hb_vmUnlock(); #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) { typedef BOOL ( WINAPI * _HB_CREATESYMBOLICLINK )( LPCTSTR, LPCTSTR, DWORD ); static _HB_CREATESYMBOLICLINK s_pCreateSymbolicLink = NULL; #ifndef SYMBOLIC_LINK_FLAG_DIRECTORY #define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 #endif if( ! s_pCreateSymbolicLink ) { HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); if( hModule ) s_pCreateSymbolicLink = ( _HB_CREATESYMBOLICLINK ) HB_WINAPI_GETPROCADDRESST( hModule, "CreateSymbolicLink" ); } if( s_pCreateSymbolicLink ) { LPCTSTR lpSymlinkFileName, lpTargetFileName; LPTSTR lpSymlinkFileNameFree, lpTargetFileNameFree; DWORD dwAttr; HB_BOOL fDir; lpSymlinkFileName = HB_FSNAMECONV( pszNewFile, &lpSymlinkFileNameFree ); lpTargetFileName = HB_FSNAMECONV( pszTarget, &lpTargetFileNameFree ); dwAttr = GetFileAttributes( lpTargetFileName ); fDir = ( dwAttr != INVALID_FILE_ATTRIBUTES ) && ( dwAttr & FILE_ATTRIBUTE_DIRECTORY ); fResult = s_pCreateSymbolicLink( lpSymlinkFileName, lpTargetFileName, fDir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ) != 0; hb_fsSetIOError( fResult, 0 ); if( lpSymlinkFileNameFree ) hb_xfree( lpSymlinkFileNameFree ); if( lpTargetFileNameFree ) hb_xfree( lpTargetFileNameFree ); } else { hb_fsSetError( 1 ); fResult = HB_FALSE; } } #elif defined( HB_OS_UNIX ) { char * pszTargetFree; char * pszNewFileFree; pszTarget = hb_fsNameConv( pszTarget, &pszTargetFree ); pszNewFile = hb_fsNameConv( pszNewFile, &pszNewFileFree ); fResult = ( symlink( pszTarget, pszNewFile ) == 0 ); hb_fsSetIOError( fResult, 0 ); if( pszTargetFree ) hb_xfree( pszTargetFree ); if( pszNewFileFree ) hb_xfree( pszNewFileFree ); } #else { hb_fsSetError( 1 ); fResult = HB_FALSE; } #endif hb_vmLock(); } else { hb_fsSetError( 2 ); fResult = HB_FALSE; } return fResult; }
static PHB_FILE s_fileExtOpen( PHB_FILE_FUNCS pFuncs, const char * pszFileName, const char * pDefExt, HB_USHORT uiExFlags, const char * pPaths, PHB_ITEM pError ) { PHB_FILE pFile = NULL; #if defined( HB_OS_UNIX ) HB_BOOL fResult, fSeek = HB_FALSE; # if defined( HB_USE_LARGEFILE64 ) struct stat64 statbuf; # else struct stat statbuf; # endif #endif HB_BOOL fShared, fReadonly; HB_FHANDLE hFile; char * pszFile; HB_SYMBOL_UNUSED( pFuncs ); fShared = ( uiExFlags & ( FO_DENYREAD | FO_DENYWRITE | FO_EXCLUSIVE ) ) == 0; fReadonly = ( uiExFlags & ( FO_READ | FO_WRITE | FO_READWRITE ) ) == FO_READ; pszFile = hb_fsExtName( pszFileName, pDefExt, uiExFlags, pPaths ); hb_vmUnlock(); #if defined( HB_OS_UNIX ) # if defined( HB_USE_LARGEFILE64 ) fResult = stat64( ( char * ) pszFile, &statbuf ) == 0; # else fResult = stat( ( char * ) pszFile, &statbuf ) == 0; # endif hb_fsSetIOError( fResult, 0 ); if( fResult ) { hb_threadEnterCriticalSection( &s_fileMtx ); pFile = hb_fileFind( statbuf.st_dev, statbuf.st_ino ); if( pFile ) { if( ! fShared || ! pFile->shared || ( uiExFlags & FXO_TRUNCATE ) != 0 ) fResult = HB_FALSE; else if( ! fReadonly && pFile->readonly ) pFile = NULL; else pFile->used++; if( ( uiExFlags & FXO_NOSEEKPOS ) == 0 ) { # if defined( HB_OS_VXWORKS ) fSeek = ! S_ISFIFO( statbuf.st_mode ); # else fSeek = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode ); # endif } } hb_threadLeaveCriticalSection( &s_fileMtx ); } if( pFile ) { if( ! fResult ) { hb_fsSetError( ( uiExFlags & FXO_TRUNCATE ) ? 5 : 32 ); pFile = NULL; } else if( uiExFlags & FXO_COPYNAME ) hb_strncpy( ( char * ) pszFileName, pszFile, HB_PATH_MAX - 1 ); if( pError ) { hb_errPutFileName( pError, pszFile ); if( ! fResult ) { hb_errPutOsCode( pError, hb_fsError() ); hb_errPutGenCode( pError, ( HB_ERRCODE ) ( ( uiExFlags & FXO_TRUNCATE ) ? EG_CREATE : EG_OPEN ) ); } } } else #endif { hFile = hb_fsExtOpen( pszFileName, pDefExt, uiExFlags, pPaths, pError ); if( hFile != FS_ERROR ) { HB_ULONG device = 0, inode = 0; #if defined( HB_OS_UNIX ) # if defined( HB_USE_LARGEFILE64 ) if( fstat64( hFile, &statbuf ) == 0 ) # else if( fstat( hFile, &statbuf ) == 0 ) # endif { device = ( HB_ULONG ) statbuf.st_dev; inode = ( HB_ULONG ) statbuf.st_ino; if( ( uiExFlags & FXO_NOSEEKPOS ) == 0 ) { # if defined( HB_OS_VXWORKS ) fSeek = ! S_ISFIFO( statbuf.st_mode ); # else fSeek = ! S_ISFIFO( statbuf.st_mode ) && ! S_ISSOCK( statbuf.st_mode ); # endif } } #endif hb_threadEnterCriticalSection( &s_fileMtx ); pFile = hb_fileNew( hFile, fShared, fReadonly, device, inode, HB_TRUE ); if( pFile->hFile != hFile ) { if( pFile->hFileRO == FS_ERROR && ! fReadonly && pFile->readonly ) { pFile->hFileRO = pFile->hFile; pFile->hFile = hFile; pFile->readonly = HB_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( hFile != FS_ERROR ) { /* TOFIX: possible race condition in MT mode, * close() is not safe due to existing locks * which are removed. */ hb_fsClose( hFile ); } } } hb_xfree( pszFile ); #if defined( HB_OS_UNIX ) if( pFile && fSeek ) pFile = hb_fileposNew( pFile ); #endif hb_vmLock(); return pFile; }
/* NOTE: Caller must free the pointer, if not NULL */ char * hb_fsLinkRead( const char * pszFile ) { char * pszLink = NULL; if( pszFile ) { hb_vmUnlock(); #if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) { typedef DWORD ( WINAPI * _HB_GETFINALPATHNAMEBYHANDLE )( HANDLE, LPTSTR, DWORD, DWORD ); static _HB_GETFINALPATHNAMEBYHANDLE s_pGetFinalPathNameByHandle = NULL; #ifndef VOLUME_NAME_DOS #define VOLUME_NAME_DOS 0x0 #endif #ifndef VOLUME_NAME_GUID #define VOLUME_NAME_GUID 0x1 #endif #ifndef VOLUME_NAME_NT #define VOLUME_NAME_NT 0x2 #endif #ifndef VOLUME_NAME_NONE #define VOLUME_NAME_NONE 0x4 #endif #ifndef FILE_NAME_NORMALIZED #define FILE_NAME_NORMALIZED 0x0 #endif #ifndef FILE_NAME_OPENED #define FILE_NAME_OPENED 0x8 #endif if( ! s_pGetFinalPathNameByHandle ) { HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); if( hModule ) s_pGetFinalPathNameByHandle = ( _HB_GETFINALPATHNAMEBYHANDLE ) HB_WINAPI_GETPROCADDRESST( hModule, "GetFinalPathNameByHandle" ); } if( s_pGetFinalPathNameByHandle ) { LPCTSTR lpFileName; LPTSTR lpFileNameFree; HANDLE hFile; DWORD dwAttr; HB_BOOL fDir; lpFileName = HB_FSNAMECONV( pszFile, &lpFileNameFree ); dwAttr = GetFileAttributes( lpFileName ); fDir = ( dwAttr != INVALID_FILE_ATTRIBUTES ) && ( dwAttr & FILE_ATTRIBUTE_DIRECTORY ); hFile = CreateFile( lpFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, fDir ? ( FILE_ATTRIBUTE_DIRECTORY | FILE_FLAG_BACKUP_SEMANTICS ) : FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) hb_fsSetIOError( HB_FALSE, 0 ); else { DWORD size; TCHAR lpLink[ HB_PATH_MAX ]; size = s_pGetFinalPathNameByHandle( hFile, lpLink, HB_PATH_MAX, VOLUME_NAME_DOS ); if( size < HB_PATH_MAX ) { if( size > 0 ) { lpLink[ size ] = TEXT( '\0' ); pszLink = HB_OSSTRDUP( lpLink ); } hb_fsSetIOError( HB_TRUE, 0 ); } else hb_fsSetError( 9 ); } if( lpFileNameFree ) hb_xfree( lpFileNameFree ); } else hb_fsSetError( 1 ); } #elif defined( HB_OS_UNIX ) { char * pszFileFree; size_t size; pszFile = hb_fsNameConv( pszFile, &pszFileFree ); pszLink = ( char * ) hb_xgrab( HB_PATH_MAX + 1 ); size = readlink( pszFile, pszLink, HB_PATH_MAX ); hb_fsSetIOError( size != ( size_t ) -1, 0 ); if( size == ( size_t ) -1 ) { hb_xfree( pszLink ); pszLink = NULL; } else { pszLink[ size ] = '\0'; /* Convert from OS codepage */ pszLink = ( char * ) HB_UNCONST( hb_osDecodeCP( pszLink, NULL, NULL ) ); } if( pszFileFree ) hb_xfree( pszFileFree ); } #else { hb_fsSetError( 1 ); } #endif hb_vmLock(); } else hb_fsSetError( 2 ); return pszLink; }
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_OS_DOS ) || defined( HB_OS_OS2 ) || defined( HB_OS_WIN_CE ) { #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_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; int iPipeCount = 0; if( nStdInLen == 0 && hStdin != FS_ERROR ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } if( hStdin != FS_ERROR ) ++iPipeCount; if( hStdout != FS_ERROR ) ++iPipeCount; if( hStderr != FS_ERROR ) ++iPipeCount; if( iPipeCount > 1 ) { 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 ) { nOutSize += HB_STD_BUFFER_SIZE; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } nLen = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); if( nLen > 0 ) nOutBuf += nLen; else if( iPipeCount == 1 ) { hb_fsClose( hStdout ); hStdout = FS_ERROR; iPipeCount = 0; } dwWait = nLen > 0 ? 0 : 10; } if( hStderr != FS_ERROR ) { if( nErrBuf == nErrSize ) { nErrSize += HB_STD_BUFFER_SIZE; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } nLen = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); if( nLen > 0 ) nErrBuf += nLen; else if( iPipeCount == 1 ) { hb_fsClose( hStderr ); hStderr = FS_ERROR; iPipeCount = 0; } if( dwWait ) dwWait = nLen > 0 ? 0 : 10; } if( fFinished ) { if( dwWait != 0 ) break; } else if( hStdin != FS_ERROR ) { nLen = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); pStdInBuf += nLen; nStdInLen -= nLen; if( nStdInLen == 0 || ( iPipeCount == 1 && nLen == 0 ) ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; if( iPipeCount == 1 ) iPipeCount = 0; } 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_UNIX ) && ! defined( HB_OS_SYMBIAN ) fd_set rfds, wfds, *prfds, *pwfds; HB_FHANDLE fdMax; HB_SIZE ul; int n; if( nStdInLen == 0 && hStdin != FS_ERROR ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } if( hStdin != FS_ERROR ) hb_fsPipeUnblock( hStdin ); if( hStdout != FS_ERROR ) hb_fsPipeUnblock( hStdout ); if( hStderr != FS_ERROR ) hb_fsPipeUnblock( hStderr ); for( ;; ) { 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; n = select( fdMax + 1, prfds, pwfds, NULL, NULL ); if( n > 0 ) { if( hStdout != FS_ERROR && FD_ISSET( hStdout, &rfds ) ) { if( nOutBuf == nOutSize ) { nOutSize += HB_STD_BUFFER_SIZE; pOutBuf = ( char * ) hb_xrealloc( pOutBuf, nOutSize + 1 ); } ul = hb_fsReadLarge( hStdout, pOutBuf + nOutBuf, nOutSize - nOutBuf ); if( ul == 0 ) { /* zero bytes read after positive Select() * - writing process closed the pipe */ hb_fsClose( hStdout ); hStdout = FS_ERROR; } else nOutBuf += ul; } if( hStderr != FS_ERROR && FD_ISSET( hStderr, &rfds ) ) { if( nErrBuf == nErrSize ) { nErrSize += HB_STD_BUFFER_SIZE; pErrBuf = ( char * ) hb_xrealloc( pErrBuf, nErrSize + 1 ); } ul = hb_fsReadLarge( hStderr, pErrBuf + nErrBuf, nErrSize - nErrBuf ); if( ul == 0 ) { /* zero bytes read after positive Select() * - writing process closed the pipe */ hb_fsClose( hStderr ); hStderr = FS_ERROR; } else nErrBuf += ul; } if( hStdin != FS_ERROR && FD_ISSET( hStdin, &wfds ) ) { ul = hb_fsWriteLarge( hStdin, pStdInBuf, nStdInLen ); pStdInBuf += ul; nStdInLen -= ul; if( nStdInLen == 0 ) { hb_fsClose( hStdin ); hStdin = FS_ERROR; } } } else break; } 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 ); #endif hb_vmLock(); } } #endif if( phStdout ) { *pStdOutPtr = pOutBuf; *pulStdOut = nOutBuf; } if( phStderr && phStdout != phStderr ) { *pStdErrPtr = pErrBuf; *pulStdErr = nErrBuf; } return iResult; }
HB_FOFFSET hb_fsFSize( const char * pszFileName, HB_BOOL bUseDirEntry ) { if( bUseDirEntry ) { #if defined( HB_OS_WIN ) typedef BOOL ( WINAPI * _HB_GETFILEATTRIBUTESEX )( LPCTSTR, GET_FILEEX_INFO_LEVELS, LPVOID ); static _HB_GETFILEATTRIBUTESEX s_pGetFileAttributesEx = ( _HB_GETFILEATTRIBUTESEX ) -1; if( s_pGetFileAttributesEx == ( _HB_GETFILEATTRIBUTESEX ) -1 ) { HMODULE hModule = GetModuleHandle( TEXT( "kernel32.dll" ) ); if( hModule ) s_pGetFileAttributesEx = ( _HB_GETFILEATTRIBUTESEX ) HB_WINAPI_GETPROCADDRESST( hModule, "GetFileAttributesEx" ); else s_pGetFileAttributesEx = NULL; } if( s_pGetFileAttributesEx ) { LPCTSTR lpFileName; LPTSTR lpFree; WIN32_FILE_ATTRIBUTE_DATA attrex; HB_BOOL fResult; lpFileName = HB_FSNAMECONV( pszFileName, &lpFree ); memset( &attrex, 0, sizeof( attrex ) ); fResult = s_pGetFileAttributesEx( lpFileName, GetFileExInfoStandard, &attrex ) && ( attrex.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0; hb_fsSetIOError( fResult, 0 ); if( lpFree ) hb_xfree( lpFree ); if( fResult ) return ( HB_FOFFSET ) attrex.nFileSizeLow + ( ( HB_FOFFSET ) attrex.nFileSizeHigh << 32 ); } else { PHB_FFIND ffind = hb_fsFindFirst( pszFileName, HB_FA_ALL ); hb_fsSetIOError( ffind != NULL, 0 ); if( ffind ) { HB_FOFFSET size = ffind->size; hb_fsFindClose( ffind ); return size; } } #elif defined( HB_USE_LARGEFILE64 ) char * pszFree; HB_BOOL fResult; struct stat64 statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat64( pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #else char * pszFree; HB_BOOL fResult; struct stat statbuf; pszFileName = hb_fsNameConv( pszFileName, &pszFree ); statbuf.st_size = 0; hb_vmUnlock(); fResult = stat( ( char * ) pszFileName, &statbuf ) == 0; hb_fsSetIOError( fResult, 0 ); hb_vmLock(); if( pszFree ) hb_xfree( pszFree ); if( fResult ) return ( HB_FOFFSET ) statbuf.st_size; #endif } else { HB_FHANDLE hFileHandle = hb_fsOpen( pszFileName, FO_READ | FO_COMPAT ); if( hFileHandle != FS_ERROR ) { HB_FOFFSET nPos = hb_fsSeekLarge( hFileHandle, 0, FS_END ); hb_fsClose( hFileHandle ); return nPos; } } return 0; }