/* Closes/kills process. The handle is still valid until you * catch it with hb_fsProcessValue. */ HB_BOOL hb_fsProcessClose( HB_FHANDLE hProcess, HB_BOOL fGentle ) { HB_BOOL fResult = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessClose(%p, %d)", ( void * ) ( HB_PTRDIFF ) hProcess, fGentle ) ); #if defined( HB_OS_WIN ) { HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess ); if( hProc ) { if( TerminateProcess( hProc, fGentle ? 0 : 1 ) ) fResult = HB_TRUE; hb_fsSetIOError( fResult, 0 ); /* hProc has to be closed by hb_fsProcessValue() */ /* CloseHandle( hProc ); */ } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif ( defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) ) || \ ( defined( HB_OS_OS2 ) && defined( __GNUC__ ) ) { pid_t pid = ( pid_t ) hProcess; if( pid > 0 ) { if( kill( pid, fGentle ? SIGTERM : SIGKILL ) == 0 ) fResult = HB_TRUE; hb_fsSetIOError( fResult, 0 ); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif defined( HB_OS_OS2 ) { PID pid = ( PID ) hProcess; HB_SYMBOL_UNUSED( fGentle ); if( pid > 0 ) { if( DosKillProcess( DKP_PROCESS, pid ) == NO_ERROR ) fResult = HB_TRUE; hb_fsSetIOError( fResult, 0 ); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #else { int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( hProcess ); HB_SYMBOL_UNUSED( fGentle ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #endif return fResult; }
/* Closes/kills process. The handle is still valid until you * catch it with hb_fsProcessValue. */ HB_BOOL hb_fsProcessClose( HB_FHANDLE hProcess, HB_BOOL fGentle ) { HB_BOOL fResult = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessClose(%p, %d)", ( void * ) ( HB_PTRUINT ) hProcess, fGentle ) ); #if defined( HB_OS_WIN ) { HANDLE hProc = ( HANDLE ) hb_fsGetOsHandle( hProcess ); if( hProc ) { fResult = TerminateProcess( hProc, fGentle ? 0 : 1 ) != 0; hb_fsSetIOError( fResult, 0 ); /* hProc has to be closed by hb_fsProcessValue() */ #if 0 CloseHandle( hProc ); #endif } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif defined( HB_OS_OS2 ) { PID pid = ( PID ) hProcess; if( pid > 0 ) { APIRET ret = DosKillProcess( fGentle ? DKP_PROCESS : DKP_PROCESSTREE, pid ); fResult = ret == NO_ERROR; hb_fsSetError( ( HB_ERRCODE ) ret ); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #elif defined( HB_OS_UNIX ) && ! defined( HB_OS_SYMBIAN ) { pid_t pid = ( pid_t ) hProcess; if( pid > 0 ) { fResult = kill( pid, fGentle ? SIGTERM : SIGKILL ) == 0; hb_fsSetIOError( fResult, 0 ); } else hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #else { int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( hProcess ); HB_SYMBOL_UNUSED( fGentle ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); } #endif return fResult; }
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 BOOL hb_fsTempName( BYTE * pszBuffer, const BYTE * pszDir, const BYTE * pszPrefix ) { BOOL fResult; #if defined(HB_WIN32_IO) { char cTempDir[ _POSIX_PATH_MAX + 1 ]; if( pszDir && pszDir[ 0 ] != '\0' ) hb_strncpy( ( char * ) cTempDir, ( const char * ) pszDir, sizeof( cTempDir ) - 1 ); else { if( ! GetTempPathA( ( DWORD ) _POSIX_PATH_MAX + 1, cTempDir ) ) { hb_fsSetIOError( FALSE, 0 ); return FALSE; } } cTempDir[ _POSIX_PATH_MAX ] = '\0'; fResult = GetTempFileNameA( ( LPCSTR ) cTempDir, pszPrefix ? ( LPCSTR ) pszPrefix : ( LPCSTR ) "xht", 0, ( LPSTR ) pszBuffer ); } #else /* TODO: Implement these: */ HB_SYMBOL_UNUSED( pszDir ); HB_SYMBOL_UNUSED( pszPrefix ); /* TOFIX: The spec says to reserve L_tmpnam number of characters for the passed buffer. It will be needed to fix _POSIX_PATH_MAX to be at least this large. */ pszBuffer[ 0 ] = '\0'; fResult = ( tmpnam( ( char * ) pszBuffer ) != NULL ); #endif hb_fsSetIOError( fResult, 0 ); return fResult; }
HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFilename, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFilename ); # if ! defined( HB_OS_WIN_CE ) if( phStdin != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStdout != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStderr != NULL && phStdout != phStderr ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); # endif memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 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 */ setuid( getuid() ); setgid( getgid() ); /* execute command */ { char ** argv; argv = hb_buildArgs( pszFilename ); # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif hb_freeArgs( argv ); exit( -1 ); } } #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFilename ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFilename ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } hb_fsSetIOError( ! fError, 0 ); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } return hResult; }
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; }
HB_FHANDLE hb_fsProcessOpen( const char * pszFileName, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_ERRCODE errCode; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFileName, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFileName ); # if ! defined( HB_OS_WIN_CE ) if( phStdin != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 1 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStdout != NULL ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); if( phStderr != NULL && phStdout != phStderr ) SetHandleInformation( ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 0 ] ), HANDLE_FLAG_INHERIT, 0 ); # endif memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_OS2 ) HFILE hNull = ( HFILE ) FS_ERROR; ULONG ulState = 0; APIRET ret = NO_ERROR; PID pid = ( PID ) -1; PHB_GT pGT; if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hFile; ret = hb_fsOS2DosOpen( "NUL:", &hFile, &ulState, 0, FILE_NORMAL, OPEN_ACCESS_READWRITE, OPEN_ACTION_OPEN_IF_EXISTS ); if( ret == NO_ERROR ) hNull = ( HFILE ) hFile; } if( ret == NO_ERROR && phStdin != NULL ) { ret = DosQueryFHState( hPipeIn[ 1 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeIn[ 1 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStdout != NULL ) { ret = DosQueryFHState( hPipeOut[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeOut[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && phStderr != NULL && phStdout != phStderr ) { ret = DosQueryFHState( hPipeErr[ 0 ], &ulState ); if( ret == NO_ERROR && ( ulState & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hPipeErr[ 0 ], ( ulState & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); } if( ret == NO_ERROR && ( pGT = hb_gt_Base() ) != NULL ) { ULONG ulStateIn, ulStateOut, ulStateErr; HFILE hStdIn, hStdErr, hStdOut, hDup; ulStateIn = ulStateOut = ulStateErr = OPEN_FLAGS_NOINHERIT; hStdIn = hStdErr = hStdOut = ( HFILE ) FS_ERROR; if( ret == NO_ERROR && ( phStdin != NULL || fDetach ) ) { hDup = 0; ret = DosDupHandle( hDup, &hStdIn ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdIn, &ulStateIn ); if( ret == NO_ERROR && ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdIn, ( ulStateIn & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdin != NULL ? ( HFILE ) hPipeIn[ 0 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStdout != NULL || fDetach ) ) { hDup = 1; ret = DosDupHandle( hDup, &hStdOut ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdOut, &ulStateOut ); if( ret == NO_ERROR && ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdOut, ( ulStateOut & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStdout != NULL ? ( HFILE ) hPipeOut[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR && ( phStderr != NULL || fDetach ) ) { hDup = 2; ret = DosDupHandle( hDup, &hStdErr ); if( ret == NO_ERROR ) { ret = DosQueryFHState( hStdErr, &ulStateErr ); if( ret == NO_ERROR && ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) ret = DosSetFHState( hStdErr, ( ulStateErr & 0xFF00 ) | OPEN_FLAGS_NOINHERIT ); if( ret == NO_ERROR ) ret = DosDupHandle( phStderr != NULL ? ( HFILE ) hPipeErr[ 1 ] : hNull, &hDup ); } } if( ret == NO_ERROR ) { char * pArgs = hb_buildArgsOS2( pszFileName, &ret ); char uchLoadError[ CCHMAXPATH ] = { 0 }; RESULTCODES ChildRC = { 0, 0 }; if( pArgs ) { ret = DosExecPgm( uchLoadError, sizeof( uchLoadError ), fDetach ? EXEC_BACKGROUND : EXEC_ASYNCRESULT, ( PCSZ ) pArgs, NULL /* env */, &ChildRC, ( PCSZ ) pArgs ); if( ret == NO_ERROR ) pid = ChildRC.codeTerminate; hb_freeArgsOS2( pArgs ); } } if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( hStdIn != ( HFILE ) FS_ERROR ) { hDup = 0; DosDupHandle( hStdIn, &hDup ); DosClose( hStdIn ); if( ( ulStateIn & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateIn & 0xFF00 ); } if( hStdOut != ( HFILE ) FS_ERROR ) { hDup = 1; DosDupHandle( hStdOut, &hDup ); DosClose( hStdOut ); if( ( ulStateOut & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateOut & 0xFF00 ); } if( hStdErr != ( HFILE ) FS_ERROR ) { hDup = 2; DosDupHandle( hStdErr, &hDup ); DosClose( hStdErr ); if( ( ulStateErr & OPEN_FLAGS_NOINHERIT ) == 0 ) DosSetFHState( hDup, ulStateErr & 0xFF00 ); } hb_gt_BaseFree( pGT ); } else { if( hNull != ( HFILE ) FS_ERROR ) DosClose( hNull ); if( ret == NO_ERROR ) ret = ( APIRET ) FS_ERROR; } fError = ret != NO_ERROR; if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetError( ( HB_ERRCODE ) ret ); #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) char ** argv = hb_buildArgs( pszFileName ); pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 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 */ if( setuid( getuid() ) == -1 ) {} if( setgid( getgid() ) == -1 ) {} /* execute command */ { # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif exit( -1 ); } } hb_fsSetIOError( ! fError, 0 ); hb_freeArgs( argv ); #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFileName ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } hb_fsSetIOError( ! fError, 0 ); #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFileName ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } errCode = hb_fsError(); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } hb_fsSetError( errCode ); return hResult; }
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_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 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; }
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; }
static BOOL hb_fsFileStats( BYTE * pszFileName, BYTE * pszAttr, HB_FOFFSET * llSize, LONG * lcDate, LONG * lcTime, LONG * lmDate, LONG * lmTime ) { BOOL fResult = FALSE; #if defined( HB_OS_UNIX ) struct stat statbuf; if( stat( ( char * ) pszFileName, &statbuf ) == 0 ) { // determine if we can read/write/execute the file USHORT usAttr, ushbAttr = 0; time_t ftime; #if _POSIX_C_SOURCE >= 199506L struct tm tms; #endif struct tm * ptms; /* See which attribs are applicable */ if( statbuf.st_uid == geteuid() ) { usAttr = ( ( statbuf.st_mode & S_IRUSR ) ? 1 << 2 : 0 ) | ( ( statbuf.st_mode & S_IWUSR ) ? 1 << 1 : 0 ) | ( ( statbuf.st_mode & S_IXUSR ) ? 1 : 0 ); } else if( statbuf.st_gid == getegid() ) { usAttr = ( ( statbuf.st_mode & S_IRGRP ) ? 1 << 2 : 0 ) | ( ( statbuf.st_mode & S_IWGRP ) ? 1 << 1 : 0 ) | ( ( statbuf.st_mode & S_IXGRP ) ? 1 : 0 ); } else { usAttr = ( ( statbuf.st_mode & S_IROTH ) ? 1 << 2 : 0 ) | ( ( statbuf.st_mode & S_IWOTH ) ? 1 << 1 : 0 ) | ( ( statbuf.st_mode & S_IXOTH ) ? 1 : 0 ); } /* Standard characters */ if( ( usAttr & 4 ) == 0 ) /* Hidden (can't read)*/ ushbAttr |= HB_FA_HIDDEN; if( ( usAttr & 2 ) == 0 ) /* read only (can't write)*/ ushbAttr |= HB_FA_READONLY; if( ( usAttr & 1 ) == 1 ) /* executable? (xbit)*/ ushbAttr |= HB_FA_SYSTEM; /* Extension characters */ if( ( statbuf.st_mode & S_IFLNK ) == S_IFLNK ) *pszAttr++ = 'Z'; /* Xharbour extension */ if( ( statbuf.st_mode & S_IFSOCK ) == S_IFSOCK ) *pszAttr++ = 'K'; /* Xharbour extension */ /* device */ if( ( statbuf.st_mode & S_IFBLK ) == S_IFBLK || ( statbuf.st_mode & S_IFCHR ) == S_IFCHR ) ushbAttr |= HB_FA_DEVICE; /* Xharbour extension */ if( ( statbuf.st_mode & S_IFIFO ) == S_IFIFO ) *pszAttr++ = 'Y'; /* Xharbour extension */ if( S_ISDIR( statbuf.st_mode ) ) ushbAttr |= HB_FA_DIRECTORY; /* Xharbour extension */ /* Give the ARCHIVE if readwrite, not executable and not special */ else if( S_ISREG( statbuf.st_mode ) && ushbAttr == 0 ) ushbAttr |= HB_FA_ARCHIVE; *llSize = ( HB_FOFFSET ) statbuf.st_size; ftime = statbuf.st_mtime; #if _POSIX_C_SOURCE >= 199506L && ! defined( HB_OS_DARWIN_5 ) ptms = localtime_r( &ftime, &tms ); #else ptms = localtime( &ftime ); #endif *lcDate = hb_dateEncode( ptms->tm_year + 1900, ptms->tm_mon + 1, ptms->tm_mday ); *lcTime = ptms->tm_hour * 3600 + ptms->tm_min * 60 + ptms->tm_sec; ftime = statbuf.st_atime; #if _POSIX_C_SOURCE >= 199506L && ! defined( HB_OS_DARWIN_5 ) ptms = localtime_r( &ftime, &tms ); #else ptms = localtime( &ftime ); #endif *lmDate = hb_dateEncode( ptms->tm_year + 1900, ptms->tm_mon + 1, ptms->tm_mday ); *lmTime = ptms->tm_hour * 3600 + ptms->tm_min * 60 + ptms->tm_sec; hb_fsAttrDecode( ushbAttr, ( char * ) pszAttr ); fResult = TRUE; } #elif defined( HB_OS_WIN ) { DWORD dwAttribs; WIN32_FIND_DATAA ffind; HANDLE hFind; FILETIME filetime; SYSTEMTIME time; /* Get attributes... */ dwAttribs = GetFileAttributesA( ( char * ) pszFileName ); if( dwAttribs == INVALID_FILE_ATTRIBUTES ) { /* return */ return FALSE; } hb_fsAttrDecode( hb_fsAttrFromRaw( dwAttribs ), ( char * ) pszAttr ); /* If file existed, do a findfirst */ hFind = FindFirstFileA( ( char * ) pszFileName, &ffind ); if( hFind != INVALID_HANDLE_VALUE ) { FindClose( hFind ); /* get file times and work them out */ *llSize = ( HB_FOFFSET ) ffind.nFileSizeLow + ( ( HB_FOFFSET ) ffind.nFileSizeHigh << 32 ); if( FileTimeToLocalFileTime( &ffind.ftCreationTime, &filetime ) && FileTimeToSystemTime( &filetime, &time ) ) { *lcDate = hb_dateEncode( time.wYear, time.wMonth, time.wDay ); *lcTime = time.wHour * 3600 + time.wMinute * 60 + time.wSecond; } else { *lcDate = hb_dateEncode( 0, 0, 0 ); *lcTime = 0; } if( FileTimeToLocalFileTime( &ffind.ftLastAccessTime, &filetime ) && FileTimeToSystemTime( &filetime, &time ) ) { *lmDate = hb_dateEncode( time.wYear, time.wMonth, time.wDay ); *lmTime = time.wHour * 3600 + time.wMinute * 60 + time.wSecond; } else { *lcDate = hb_dateEncode( 0, 0, 0 ); *lcTime = 0; } fResult = TRUE; } } #else /* Generic algorithm based on findfirst */ { PHB_FFIND findinfo = hb_fsFindFirst( ( char * ) pszFileName, HB_FA_ALL ); if( findinfo ) { hb_fsAttrDecode( findinfo->attr, ( char * ) pszAttr ); *llSize = ( HB_FOFFSET ) findinfo->size; *lcDate = findinfo->lDate; *lcTime = ( findinfo->szTime[ 0 ] - '0' ) * 36000 + ( findinfo->szTime[ 1 ] - '0' ) * 3600 + ( findinfo->szTime[ 3 ] - '0' ) * 600 + ( findinfo->szTime[ 4 ] - '0' ) * 60 + ( findinfo->szTime[ 6 ] - '0' ) * 10 + ( findinfo->szTime[ 7 ] - '0' ); *lmDate = hb_dateEncode( 0, 0, 0 ); *lmTime = 0; hb_fsFindClose( findinfo ); fResult = TRUE; } } #endif hb_fsSetIOError( fResult, 0 ); return fResult; }
double hb_fsDiskSpace( const char * pszPath, HB_USHORT uiType ) { char szPathBuf[ 2 ]; double dSpace = 0.0; if( uiType > HB_DISK_TOTAL ) uiType = HB_DISK_AVAIL; if( ! pszPath ) { szPathBuf[ 0 ] = HB_OS_PATH_DELIM_CHR; szPathBuf[ 1 ] = '\0'; pszPath = szPathBuf; } #if defined( HB_OS_WIN ) { LPCTSTR lpPath; LPTSTR lpFree; lpPath = HB_FSNAMECONV( pszPath, &lpFree ); { UINT uiErrMode = SetErrorMode( SEM_FAILCRITICALERRORS ); HB_BOOL fResult; #if ! defined( HB_OS_WIN_CE ) && ! defined( HB_OS_WIN_64 ) /* NOTE: We need to call this function dynamically to maintain support Win95 first edition. It was introduced in Win95B (aka OSR2) [vszakats] */ typedef BOOL ( WINAPI * P_GDFSE )( LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER ); static P_GDFSE s_pGetDiskFreeSpaceEx = NULL; static HB_BOOL s_fInit = HB_FALSE; if( ! s_fInit ) { HMODULE hModule = GetModuleHandle( HB_WINAPI_KERNEL32_DLL() ); if( hModule ) s_pGetDiskFreeSpaceEx = ( P_GDFSE ) HB_WINAPI_GETPROCADDRESST( hModule, "GetDiskFreeSpaceEx" ); s_fInit = HB_TRUE; } if( ! s_pGetDiskFreeSpaceEx ) { DWORD dwSectorsPerCluster; DWORD dwBytesPerSector; DWORD dwNumberOfFreeClusters; DWORD dwTotalNumberOfClusters; fResult = GetDiskFreeSpace( lpPath, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters ) ? HB_TRUE : HB_FALSE; hb_fsSetIOError( fResult, 0 ); if( fResult ) { switch( uiType ) { case HB_DISK_AVAIL: case HB_DISK_FREE: dSpace = ( double ) dwNumberOfFreeClusters * ( double ) dwSectorsPerCluster * ( double ) dwBytesPerSector; break; case HB_DISK_USED: case HB_DISK_TOTAL: dSpace = ( double ) dwTotalNumberOfClusters * ( double ) dwSectorsPerCluster * ( double ) dwBytesPerSector; if( uiType == HB_DISK_USED ) dSpace -= ( double ) dwNumberOfFreeClusters * ( double ) dwSectorsPerCluster * ( double ) dwBytesPerSector; break; } } } else #endif { #if defined( _MSC_VER ) || defined( __LCC__ ) || \ ( defined( __GNUC__ ) && ! defined( __RSXNT__ ) ) # define HB_GET_LARGE_UINT( v ) ( ( double ) (v).LowPart + \ ( double ) (v).HighPart * \ ( ( ( double ) 0xFFFFFFFF ) + 1 ) ) #else /* NOTE: Borland doesn't seem to deal with the un-named struct that is part of ULARGE_INTEGER [pt] */ # define HB_GET_LARGE_UINT( v ) ( ( double ) (v).u.LowPart + \ ( double ) (v).u.HighPart * \ ( ( ( double ) 0xFFFFFFFF ) + 1 ) ) #endif ULARGE_INTEGER i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes; #if ! defined( HB_OS_WIN_CE ) && ! defined( HB_OS_WIN_64 ) fResult = s_pGetDiskFreeSpaceEx( lpPath, ( PULARGE_INTEGER ) &i64FreeBytesToCaller, ( PULARGE_INTEGER ) &i64TotalBytes, ( PULARGE_INTEGER ) &i64FreeBytes ); #else fResult = GetDiskFreeSpaceEx( lpPath, ( PULARGE_INTEGER ) &i64FreeBytesToCaller, ( PULARGE_INTEGER ) &i64TotalBytes, ( PULARGE_INTEGER ) &i64FreeBytes ); #endif hb_fsSetIOError( fResult, 0 ); if( fResult ) { switch( uiType ) { case HB_DISK_AVAIL: dSpace = HB_GET_LARGE_UINT( i64FreeBytesToCaller ); break; case HB_DISK_FREE: dSpace = HB_GET_LARGE_UINT( i64FreeBytes ); break; case HB_DISK_TOTAL: dSpace = HB_GET_LARGE_UINT( i64TotalBytes ); break; case HB_DISK_USED: dSpace = HB_GET_LARGE_UINT( i64TotalBytes ) - HB_GET_LARGE_UINT( i64FreeBytes ); break; } } } SetErrorMode( uiErrMode ); } if( lpFree ) hb_xfree( lpFree ); } #elif defined( HB_OS_DOS ) || defined( HB_OS_OS2 ) { HB_USHORT uiDrive; uiDrive = pszPath == NULL || pszPath[ 0 ] == 0 || pszPath[ 1 ] != HB_OS_DRIVE_DELIM_CHR ? 0 : ( pszPath[ 0 ] >= 'A' && pszPath[ 0 ] <= 'Z' ? pszPath[ 0 ] - 'A' + 1 : ( pszPath[ 0 ] >= 'a' && pszPath[ 0 ] <= 'z' ? pszPath[ 0 ] - 'a' + 1 : 0 ) ); #if defined( HB_OS_DOS ) for( ;; ) { union REGS regs; regs.HB_XREGS.dx = uiDrive; regs.h.ah = 0x36; HB_DOS_INT86( 0x21, ®s, ®s ); if( regs.HB_XREGS.ax != 0xFFFF ) { HB_USHORT uiClusterTotal = regs.HB_XREGS.dx; HB_USHORT uiClusterFree = regs.HB_XREGS.bx; HB_USHORT uiSecPerCluster = regs.HB_XREGS.ax; HB_USHORT uiSectorSize = regs.HB_XREGS.cx; switch( uiType ) { case HB_DISK_AVAIL: case HB_DISK_FREE: dSpace = ( double ) uiClusterFree * ( double ) uiSecPerCluster * ( double ) uiSectorSize; break; case HB_DISK_USED: case HB_DISK_TOTAL: dSpace = ( double ) uiClusterTotal * ( double ) uiSecPerCluster * ( double ) uiSectorSize; if( uiType == HB_DISK_USED ) dSpace -= ( double ) uiClusterFree * ( double ) uiSecPerCluster * ( double ) uiSectorSize; break; } } else { if( hb_errRT_BASE_Ext1( EG_OPEN, 2018, NULL, NULL, 0, ( EF_CANDEFAULT | EF_CANRETRY ), HB_ERR_ARGS_BASEPARAMS ) == E_RETRY ) continue; } break; } #else /* HB_OS_OS2 */ { struct _FSALLOCATE fsa; APIRET rc; /* Query level 1 info from filesystem */ while( ( rc = DosQueryFSInfo( uiDrive, 1, &fsa, sizeof( fsa ) ) ) != NO_ERROR ) { if( hb_errRT_BASE_Ext1( EG_OPEN, 2018, NULL, NULL, 0, ( EF_CANDEFAULT | EF_CANRETRY ), HB_ERR_ARGS_BASEPARAMS ) != E_RETRY ) break; } hb_fsSetError( ( HB_ERRCODE ) rc ); if( rc == NO_ERROR ) { switch( uiType ) { case HB_DISK_AVAIL: case HB_DISK_FREE: dSpace = ( double ) fsa.cUnitAvail * ( double ) fsa.cSectorUnit * ( double ) fsa.cbSector; break; case HB_DISK_USED: case HB_DISK_TOTAL: dSpace = ( double ) fsa.cUnit * ( double ) fsa.cSectorUnit * ( double ) fsa.cbSector; if( uiType == HB_DISK_USED ) dSpace -= ( double ) fsa.cUnitAvail * ( double ) fsa.cSectorUnit * ( double ) fsa.cbSector; break; } } } #endif } #elif defined( HB_OS_UNIX ) && \ !( defined( __WATCOMC__ ) || defined( __CEGCC__ ) || defined( HB_OS_SYMBIAN ) ) { #if defined( HB_OS_DARWIN ) || defined( HB_OS_ANDROID ) || \ defined( HB_OS_VXWORKS ) struct statfs sf; #else struct statvfs sf; #endif char * pszFree; pszPath = hb_fsNameConv( pszPath, &pszFree ); #if defined( HB_OS_DARWIN ) || defined( HB_OS_ANDROID ) || \ defined( HB_OS_VXWORKS ) if( statfs( pszPath, &sf ) == 0 ) #else if( statvfs( pszPath, &sf ) == 0 ) #endif { switch( uiType ) { case HB_DISK_AVAIL: dSpace = ( double ) sf.f_bavail * ( double ) sf.f_bsize; break; case HB_DISK_FREE: dSpace = ( double ) sf.f_bfree * ( double ) sf.f_bsize; break; case HB_DISK_USED: dSpace = ( double ) ( sf.f_blocks - sf.f_bfree ) * ( double ) sf.f_bsize; break; case HB_DISK_TOTAL: dSpace = ( double ) sf.f_blocks * ( double ) sf.f_bsize; break; } hb_fsSetIOError( HB_TRUE, 0 ); } else hb_fsSetIOError( HB_FALSE, 0 ); if( pszFree ) hb_xfree( pszFree ); } #else { int iTODO; HB_SYMBOL_UNUSED( uiType ); } #endif return dSpace; }
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; }
/* 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; }
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 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; }
static HB_FHANDLE hb_fsCreateTempLow( const BYTE * pszDir, const BYTE * pszPrefix, ULONG ulAttr, BYTE * pszName, const UCHAR * pszExt ) { /* less attemps */ int iAttemptLeft = 99, iLen; HB_FHANDLE fd; do { pszName[ 0 ] = '\0'; if( pszDir && pszDir[ 0 ] != '\0' ) { strncpy( ( char * ) pszName, ( char * ) pszDir, _POSIX_PATH_MAX ); } else { #if defined(HB_WIN32_IO) if( ! GetTempPathA( ( DWORD ) _POSIX_PATH_MAX, ( LPSTR ) pszName ) ) { pszName[ 0 ] = '.'; pszName[ 1 ] = '\0'; } #else char * pszTmpDir = hb_getenv( "TMPDIR" ); if( !fsGetTempDirByCase( pszName, pszTmpDir ) ) { #ifdef P_tmpdir if( !fsGetTempDirByCase( pszName, P_tmpdir ) ) #endif { pszName[ 0 ] = '.'; pszName[ 1 ] = '\0'; } } if( pszTmpDir ) hb_xfree( pszTmpDir ); #endif } if( pszName[0] != '\0' ) { int len = strlen( ( char * ) pszName ); if( pszName[ len - 1 ] != ( BYTE ) hb_set.HB_SET_DIRSEPARATOR ) { pszName[ len ] = ( BYTE ) hb_set.HB_SET_DIRSEPARATOR; pszName[ len + 1 ] = '\0'; } } if( pszPrefix ) strncat( ( char * ) pszName, ( char * ) pszPrefix, _POSIX_PATH_MAX ); iLen = ( int ) strlen( ( char * ) pszName ); if( iLen > _POSIX_PATH_MAX - 6 ) return FS_ERROR; #if !defined(__WATCOMC__) && ( defined( HB_OS_LINUX ) || defined( HB_OS_BSD ) ) if( hb_set.HB_SET_FILECASE != HB_SET_CASE_LOWER && hb_set.HB_SET_FILECASE != HB_SET_CASE_UPPER && hb_set.HB_SET_DIRCASE != HB_SET_CASE_LOWER && hb_set.HB_SET_DIRCASE != HB_SET_CASE_UPPER && pszExt == NULL ) { strncat( ( char * ) pszName, "XXXXXX", _POSIX_PATH_MAX ); fd = ( HB_FHANDLE ) mkstemp( ( char * ) pszName ); hb_fsSetIOError( fd != ( HB_FHANDLE ) -1, 0 ); } else #endif { 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++ ] = ( BYTE ) ( n + ( n > 9 ? 'a' - 10 : '0' ) ); } pszName[ iLen ] = '\0'; if( pszExt ) strncat( ( char * ) pszName, ( char * ) pszExt, _POSIX_PATH_MAX ); hb_fsNameConv( pszName, NULL ); fd = hb_fsCreateEx( pszName, ulAttr, FO_EXCLUSIVE | FO_EXCL ); } if( fd != ( HB_FHANDLE ) FS_ERROR ) return fd; } while( --iAttemptLeft ); return FS_ERROR; }
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; }
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; }