static int hb_gt_std_ReadKey( PHB_GT pGT, int iEventMask ) { PHB_GTSTD pGTSTD; int ch = 0; HB_TRACE( HB_TR_DEBUG, ( "hb_gt_std_ReadKey(%p,%d)", pGT, iEventMask ) ); HB_SYMBOL_UNUSED( iEventMask ); pGTSTD = HB_GTSTD_GET( pGT ); #if defined( HB_HAS_TERMIOS ) { struct timeval tv; fd_set rfds; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO( &rfds ); FD_SET( pGTSTD->hStdin, &rfds ); if( select( pGTSTD->hStdin + 1, &rfds, NULL, NULL, &tv ) > 0 ) { HB_BYTE bChar; if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } } #elif defined( _MSC_VER ) && ! defined( HB_OS_WIN_CE ) if( pGTSTD->fStdinConsole ) { if( _kbhit() ) { ch = _getch(); if( ( ch == 0 || ch == 224 ) && _kbhit() ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ ch = _getch(); if( ch != -1 ) ch += 256; } ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! _eof( ( int ) pGTSTD->hStdin ) ) { HB_BYTE bChar; if( _read( ( int ) pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } #elif defined( HB_OS_WIN ) if( ! pGTSTD->fStdinConsole ) { HB_BYTE bChar; if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } else if( WaitForSingleObject( ( HANDLE ) hb_fsGetOsHandle( pGTSTD->hStdin ), 0 ) == WAIT_OBJECT_0 ) { #if defined( HB_OS_WIN_CE ) HB_BYTE bChar; if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; #else INPUT_RECORD ir; DWORD dwEvents; while( PeekConsoleInput( ( HANDLE ) hb_fsGetOsHandle( pGTSTD->hStdin ), &ir, 1, &dwEvents ) && dwEvents == 1 ) { if( ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown ) { HB_BYTE bChar; if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } else /* Remove from the input queue */ ReadConsoleInput( ( HANDLE ) hb_fsGetOsHandle( pGTSTD->hStdin ), &ir, 1, &dwEvents ); } #endif } #elif defined( __WATCOMC__ ) if( pGTSTD->fStdinConsole ) { if( kbhit() ) { ch = getch(); if( ch == 0 && kbhit() ) { /* It was a function key lead-in code, so read the actual function key and then offset it by 256 */ ch = getch(); if( ch != -1 ) ch += 256; } ch = hb_gt_dos_keyCodeTranslate( ch, 0, HB_GTSELF_CPIN( pGT ) ); } } else if( ! eof( pGTSTD->hStdin ) ) { HB_BYTE bChar; if( read( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } #else { if( ! pGTSTD->fStdinConsole ) { HB_BYTE bChar; if( hb_fsRead( pGTSTD->hStdin, &bChar, 1 ) == 1 ) ch = bChar; } else { int iTODO; /* TODO: */ } } #endif if( ch ) { int u = HB_GTSELF_KEYTRANS( pGT, ch ); if( u ) ch = HB_INKEY_NEW_UNICODE( u ); } return ch; }
static void hb_gt_std_Init( PHB_GT pGT, HB_FHANDLE hFilenoStdin, HB_FHANDLE hFilenoStdout, HB_FHANDLE hFilenoStderr ) { PHB_GTSTD pGTSTD; HB_TRACE( HB_TR_DEBUG, ( "hb_gt_std_Init(%p,%p,%p,%p)", pGT, ( void * ) ( HB_PTRDIFF ) hFilenoStdin, ( void * ) ( HB_PTRDIFF ) hFilenoStdout, ( void * ) ( HB_PTRDIFF ) hFilenoStderr ) ); HB_GTLOCAL( pGT ) = pGTSTD = ( PHB_GTSTD ) hb_xgrabz( sizeof( HB_GTSTD ) ); pGTSTD->hStdin = hFilenoStdin; pGTSTD->hStdout = hFilenoStdout; pGTSTD->hStderr = hFilenoStderr; pGTSTD->fStdinConsole = hb_fsIsDevice( pGTSTD->hStdin ); pGTSTD->fStdoutConsole = hb_fsIsDevice( pGTSTD->hStdout ); pGTSTD->fStderrConsole = hb_fsIsDevice( pGTSTD->hStderr ); pGTSTD->szCrLf = hb_strdup( hb_conNewLine() ); pGTSTD->nCrLf = strlen( pGTSTD->szCrLf ); hb_fsSetDevMode( pGTSTD->hStdout, FD_BINARY ); HB_GTSUPER_INIT( pGT, hFilenoStdin, hFilenoStdout, hFilenoStderr ); /* SA_NOCLDSTOP in #if is a hack to detect POSIX compatible environment */ #if defined( HB_HAS_TERMIOS ) && \ defined( SA_NOCLDSTOP ) if( pGTSTD->fStdinConsole ) { #if defined( SIGTTOU ) struct sigaction act, old; /* if( pGTSTD->saved_TIO.c_lflag & TOSTOP ) != 0 */ sigaction( SIGTTOU, NULL, &old ); memcpy( &act, &old, sizeof( struct sigaction ) ); act.sa_handler = sig_handler; /* do not use SA_RESTART - new Linux kernels will repeat the operation */ #if defined( SA_ONESHOT ) act.sa_flags = SA_ONESHOT; #elif defined( SA_RESETHAND ) act.sa_flags = SA_RESETHAND; #else act.sa_flags = 0; #endif sigaction( SIGTTOU, &act, 0 ); #endif s_fRestTTY = HB_TRUE; tcgetattr( pGTSTD->hStdin, &pGTSTD->saved_TIO ); memcpy( &pGTSTD->curr_TIO, &pGTSTD->saved_TIO, sizeof( struct termios ) ); /* atexit( restore_input_mode ); */ pGTSTD->curr_TIO.c_lflag &= ~( ICANON | ECHO ); pGTSTD->curr_TIO.c_iflag &= ~ICRNL; pGTSTD->curr_TIO.c_cc[ VMIN ] = 0; pGTSTD->curr_TIO.c_cc[ VTIME ] = 0; tcsetattr( pGTSTD->hStdin, TCSAFLUSH, &pGTSTD->curr_TIO ); #if defined( SIGTTOU ) act.sa_handler = SIG_DFL; sigaction( SIGTTOU, &old, NULL ); #endif pGTSTD->fRestTTY = s_fRestTTY; } #ifdef TIOCGWINSZ if( pGTSTD->fStdoutConsole ) { struct winsize win; if( ioctl( pGTSTD->hStdout, TIOCGWINSZ, ( char * ) &win ) != -1 ) { HB_GTSELF_RESIZE( pGT, win.ws_row, win.ws_col ); } } #endif #elif defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) if( pGTSTD->fStdinConsole ) { SetConsoleMode( ( HANDLE ) hb_fsGetOsHandle( pGTSTD->hStdin ), 0x0000 ); } #endif HB_GTSELF_SETFLAG( pGT, HB_GTI_STDOUTCON, pGTSTD->fStdoutConsole ); HB_GTSELF_SETFLAG( pGT, HB_GTI_STDERRCON, pGTSTD->fStderrConsole && pGTSTD->fStdoutConsole ); }
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, ( void * ) phStdin, ( void * ) phStdout, ( void * ) phStderr, fDetach, ( void * ) 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 ) 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( __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 } if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsCloseRaw( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsCloseRaw( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsCloseRaw( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsCloseRaw( 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(); HB_FAILURE_RETRY( iRetStatus, waitpid( pid, &iStatus, fWait ? 0 : WNOHANG ) ); #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; }
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)", pszFileName, ( const void * ) pStdInBuf, nStdInLen, ( void * ) pStdOutPtr, ( void * ) pulStdOut, ( void * ) pStdErrPtr, ( void * ) 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 ) 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 int hb_zipStoreFile( zipFile hZip, const char * szFileName, const char * szName, const char * szPassword, const char * szComment ) { char * szZipName, * pString; HB_FHANDLE hFile; HB_SIZE nLen; HB_FATTR ulExtAttr; zip_fileinfo zfi; int iResult; HB_BOOL fError; HB_BOOL fText; HB_U32 ulCRC; if( szName ) { /* change path separators to '/' */ szZipName = hb_strdup( szName ); nLen = strlen( szZipName ); pString = szZipName; while( nLen-- ) { if( pString[ nLen ] == '\\' ) pString[ nLen ] = '/'; } } else { /* get file name */ szZipName = hb_strdup( szFileName ); nLen = strlen( szZipName ); pString = szZipName; while( nLen-- ) { if( pString[ nLen ] == '/' || pString[ nLen ] == '\\' ) { memmove( szZipName, &pString[ nLen + 1 ], strlen( szZipName ) - nLen ); break; } } } memset( &zfi, 0, sizeof( zfi ) ); fError = HB_FALSE; ulExtAttr = 0; #if defined( HB_OS_WIN ) { LPTSTR lpFileNameFree; LPCTSTR lpFileName = HB_FSNAMECONV( szFileName, &lpFileNameFree ); DWORD attr = GetFileAttributes( lpFileName ); if( attr != INVALID_FILE_ATTRIBUTES ) { ulExtAttr = hb_translateExtAttr( szFileName, attr & ( FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE ) ); } else fError = HB_TRUE; if( lpFileNameFree ) hb_xfree( lpFileNameFree ); } #elif defined( HB_OS_UNIX ) { struct stat statbuf; struct tm st; char * pszFree; if( stat( hb_fsNameConv( szFileName, &pszFree ), &statbuf ) == 0 ) { if( S_ISDIR( statbuf.st_mode ) ) { ulExtAttr |= 0x40000000; ulExtAttr |= 0x10; /* FILE_ATTRIBUTE_DIRECTORY */ } else { ulExtAttr |= 0x80000000; ulExtAttr |= 0x20; /* FILE_ATTRIBUTE_ARCHIVE */ } ulExtAttr |= ( ( statbuf.st_mode & S_IXOTH ) ? 0x00010000 : 0 ) | ( ( statbuf.st_mode & S_IWOTH ) ? 0x00020000 : 0 ) | ( ( statbuf.st_mode & S_IROTH ) ? 0x00040000 : 0 ) | ( ( statbuf.st_mode & S_IXGRP ) ? 0x00080000 : 0 ) | ( ( statbuf.st_mode & S_IWGRP ) ? 0x00100000 : 0 ) | ( ( statbuf.st_mode & S_IRGRP ) ? 0x00200000 : 0 ) | ( ( statbuf.st_mode & S_IXUSR ) ? 0x00400000 : 0 ) | ( ( statbuf.st_mode & S_IWUSR ) ? 0x00800000 : 0 ) | ( ( statbuf.st_mode & S_IRUSR ) ? 0x01000000 : 0 ); # if defined( HB_HAS_LOCALTIME_R ) localtime_r( &statbuf.st_mtime, &st ); # else st = *localtime( &statbuf.st_mtime ); # endif zfi.tmz_date.tm_sec = st.tm_sec; zfi.tmz_date.tm_min = st.tm_min; zfi.tmz_date.tm_hour = st.tm_hour; zfi.tmz_date.tm_mday = st.tm_mday; zfi.tmz_date.tm_mon = st.tm_mon; zfi.tmz_date.tm_year = st.tm_year; } else fError = HB_TRUE; if( pszFree ) hb_xfree( pszFree ); } #elif defined( HB_OS_DOS ) { # if defined( __DJGPP__ ) || defined( __RSX32__ ) || defined( __GNUC__ ) int attr; char * pszFree; attr = _chmod( hb_fsNameConv( szFileName, &pszFree ), 0, 0 ); if( pszFree ) hb_xfree( pszFree ); if( attr != -1 ) # else HB_FATTR attr; if( hb_fsGetAttr( szFileName, &attr ) ) # endif { ulExtAttr = attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM | HB_FA_DIRECTORY | HB_FA_ARCHIVE ); ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr ); } else fError = HB_TRUE; } #elif defined( HB_OS_OS2 ) { FILESTATUS3 fs3; APIRET ulrc; HB_FATTR ulAttr; char * pszFree; ulrc = DosQueryPathInfo( ( PCSZ ) hb_fsNameConv( szFileName, &pszFree ), FIL_STANDARD, &fs3, sizeof( fs3 ) ); if( pszFree ) hb_xfree( pszFree ); if( ulrc == NO_ERROR ) { ulAttr = 0; if( fs3.attrFile & FILE_READONLY ) ulAttr |= HB_FA_READONLY; if( fs3.attrFile & FILE_HIDDEN ) ulAttr |= HB_FA_HIDDEN; if( fs3.attrFile & FILE_SYSTEM ) ulAttr |= HB_FA_SYSTEM; if( fs3.attrFile & FILE_DIRECTORY ) ulAttr |= HB_FA_DIRECTORY; if( fs3.attrFile & FILE_ARCHIVED ) ulAttr |= HB_FA_ARCHIVE; ulExtAttr = hb_translateExtAttr( szFileName, ulAttr ); zfi.tmz_date.tm_sec = fs3.ftimeLastWrite.twosecs * 2; zfi.tmz_date.tm_min = fs3.ftimeLastWrite.minutes; zfi.tmz_date.tm_hour = fs3.ftimeLastWrite.hours; zfi.tmz_date.tm_mday = fs3.fdateLastWrite.day; zfi.tmz_date.tm_mon = fs3.fdateLastWrite.month; zfi.tmz_date.tm_year = fs3.fdateLastWrite.year + 1980; } else fError = HB_TRUE; } #else { HB_FATTR attr; if( ! hb_fsGetAttr( szFileName, &attr ) ) ulExtAttr = 0x81B60020; /* FILE_ATTRIBUTE_ARCHIVE | rw-rw-rw- */ else { ulExtAttr = attr & ( HB_FA_READONLY | HB_FA_HIDDEN | HB_FA_SYSTEM | HB_FA_DIRECTORY | HB_FA_ARCHIVE ); ulExtAttr = hb_translateExtAttr( szFileName, ulExtAttr ); } } #endif if( fError ) { hb_xfree( szZipName ); return -200; } fText = HB_FALSE; ulCRC = 0; zfi.external_fa = ulExtAttr; /* TODO: zip.exe test: 0 for binary file, 1 for text. Does not depend on extension. We should analyse content of file to determine this??? */ zfi.internal_fa = 0; if( ulExtAttr & 0x40000000 ) { iResult = zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, szPassword, ulCRC ); if( iResult == 0 ) zipCloseFileInZip( hZip ); } else { hFile = hb_fsOpen( szFileName, FO_READ ); if( hFile != FS_ERROR ) { #if defined( HB_OS_WIN ) { FILETIME ftutc, ft; SYSTEMTIME st; if( GetFileTime( ( HANDLE ) hb_fsGetOsHandle( hFile ), NULL, NULL, &ftutc ) && FileTimeToLocalFileTime( &ftutc, &ft ) && FileTimeToSystemTime( &ft, &st ) ) { zfi.tmz_date.tm_sec = st.wSecond; zfi.tmz_date.tm_min = st.wMinute; zfi.tmz_date.tm_hour = st.wHour; zfi.tmz_date.tm_mday = st.wDay; zfi.tmz_date.tm_mon = st.wMonth - 1; zfi.tmz_date.tm_year = st.wYear; } } #endif if( szPassword ) { if( hb_zipGetFileInfo( szFileName, &ulCRC, &fText ) ) zfi.internal_fa = fText ? 1 : 0; } iResult = zipOpenNewFileInZip3( hZip, szZipName, &zfi, NULL, 0, NULL, 0, szComment, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, szPassword, ulCRC ); if( iResult == 0 ) { pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); while( ( nLen = hb_fsReadLarge( hFile, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) zipWriteInFileInZip( hZip, pString, ( unsigned ) nLen ); hb_xfree( pString ); zipCloseFileInZip( hZip ); } hb_fsClose( hFile ); } else iResult = -200 - hb_fsError(); } hb_xfree( szZipName ); return iResult; }
static int hb_unzipExtractCurrentFile( unzFile hUnzip, const char * szFileName, const char * szPassword ) { char szName[ HB_PATH_MAX ]; HB_SIZE nPos, nLen; char cSep, * pString; unz_file_info ufi; int iResult; HB_FHANDLE hFile; iResult = unzGetCurrentFileInfo( hUnzip, &ufi, szName, HB_PATH_MAX - 1, NULL, 0, NULL, 0 ); if( iResult != UNZ_OK ) return iResult; iResult = unzOpenCurrentFilePassword( hUnzip, szPassword ); if( iResult != UNZ_OK ) return iResult; if( szFileName ) hb_strncpy( szName, szFileName, sizeof( szName ) - 1 ); nLen = strlen( szName ); /* Test shows that files in subfolders can be stored to zip file without explicitly adding folder. So, let's create a required path */ nPos = 1; while( nPos < nLen ) { cSep = szName[ nPos ]; /* allow both path separators, ignore terminating path separator */ if( ( cSep == '\\' || cSep == '/' ) && nPos < nLen - 1 ) { szName[ nPos ] = '\0'; hb_fsMkDir( szName ); szName[ nPos ] = cSep; } nPos++; } if( ufi.external_fa & 0x40000000 ) /* DIRECTORY */ { hb_fsMkDir( szName ); iResult = UNZ_OK; } else { hFile = hb_fsCreate( szName, FC_NORMAL ); if( hFile != FS_ERROR ) { pString = ( char * ) hb_xgrab( HB_Z_IOBUF_SIZE ); while( ( iResult = unzReadCurrentFile( hUnzip, pString, HB_Z_IOBUF_SIZE ) ) > 0 ) hb_fsWriteLarge( hFile, pString, ( HB_SIZE ) iResult ); hb_xfree( pString ); #if defined( HB_OS_WIN ) { FILETIME ftutc, ft; SYSTEMTIME st; st.wSecond = ( WORD ) ufi.tmu_date.tm_sec; st.wMinute = ( WORD ) ufi.tmu_date.tm_min; st.wHour = ( WORD ) ufi.tmu_date.tm_hour; st.wDay = ( WORD ) ufi.tmu_date.tm_mday; st.wMonth = ( WORD ) ufi.tmu_date.tm_mon + 1; st.wYear = ( WORD ) ufi.tmu_date.tm_year; st.wMilliseconds = 0; if( SystemTimeToFileTime( &st, &ft ) && LocalFileTimeToFileTime( &ft, &ftutc ) ) { SetFileTime( ( HANDLE ) hb_fsGetOsHandle( hFile ), &ftutc, &ftutc, &ftutc ); } } #endif hb_fsClose( hFile ); } else iResult = -200 - hb_fsError(); } unzCloseCurrentFile( hUnzip ); #if defined( HB_OS_WIN ) { LPTSTR lpFileNameFree; LPCTSTR lpFileName = HB_FSNAMECONV( szName, &lpFileNameFree ); SetFileAttributes( ( LPCTSTR ) lpFileName, ufi.external_fa & 0xFF ); if( lpFileNameFree ) hb_xfree( lpFileNameFree ); } #elif defined( HB_OS_UNIX ) || defined( __DJGPP__ ) { struct utimbuf utim; struct tm st; time_t tim; char * pszFree; const char * szNameOS = hb_fsNameConv( szName, &pszFree ); # if defined( __DJGPP__ ) _chmod( szNameOS, 1, ufi.external_fa & 0xFF ); # else HB_FATTR ulAttr = ufi.external_fa; if( ( ulAttr & 0xFFFF0000 ) == 0 ) ulAttr = hb_translateExtAttr( szName, ulAttr ); chmod( szNameOS, ( ( ulAttr & 0x00010000 ) ? S_IXOTH : 0 ) | ( ( ulAttr & 0x00020000 ) ? S_IWOTH : 0 ) | ( ( ulAttr & 0x00040000 ) ? S_IROTH : 0 ) | ( ( ulAttr & 0x00080000 ) ? S_IXGRP : 0 ) | ( ( ulAttr & 0x00100000 ) ? S_IWGRP : 0 ) | ( ( ulAttr & 0x00200000 ) ? S_IRGRP : 0 ) | ( ( ulAttr & 0x00400000 ) ? S_IXUSR : 0 ) | ( ( ulAttr & 0x00800000 ) ? S_IWUSR : 0 ) | ( ( ulAttr & 0x01000000 ) ? S_IRUSR : 0 ) ); # endif memset( &st, 0, sizeof( st ) ); st.tm_sec = ufi.tmu_date.tm_sec; st.tm_min = ufi.tmu_date.tm_min; st.tm_hour = ufi.tmu_date.tm_hour; st.tm_mday = ufi.tmu_date.tm_mday; st.tm_mon = ufi.tmu_date.tm_mon; st.tm_year = ufi.tmu_date.tm_year - 1900; tim = mktime( &st ); # if defined( HB_HAS_LOCALTIME_R ) gmtime_r( &tim, &st ); # else st = *gmtime( &tim ); # endif utim.actime = utim.modtime = mktime( &st ); utime( szNameOS, &utim ); if( pszFree ) hb_xfree( pszFree ); } #elif defined( HB_OS_DOS ) { # if defined( __RSX32__ ) || defined( __GNUC__ ) char * pszFree; _chmod( hb_fsNameConv( szName, &pszFree ), 1, ufi.external_fa & 0xFF ); if( pszFree ) hb_xfree( pszFree ); # else hb_fsSetAttr( szName, ufi.external_fa & 0xFF ); # endif } #elif defined( HB_OS_OS2 ) { FILESTATUS3 fs3; APIRET ulrc; HB_FATTR ulAttr = FILE_NORMAL; int iAttr = ufi.external_fa & 0xFF; char * pszFree; const char * szNameOS = hb_fsNameConv( szName, &pszFree ); if( iAttr & HB_FA_READONLY ) ulAttr |= FILE_READONLY; if( iAttr & HB_FA_HIDDEN ) ulAttr |= FILE_HIDDEN; if( iAttr & HB_FA_SYSTEM ) ulAttr |= FILE_SYSTEM; if( iAttr & HB_FA_ARCHIVE ) ulAttr |= FILE_ARCHIVED; ulrc = DosQueryPathInfo( ( PCSZ ) szNameOS, FIL_STANDARD, &fs3, sizeof( fs3 ) ); if( ulrc == NO_ERROR ) { FDATE fdate; FTIME ftime; fdate.year = ufi.tmu_date.tm_year - 1980; fdate.month = ufi.tmu_date.tm_mon; fdate.day = ufi.tmu_date.tm_mday; ftime.hours = ufi.tmu_date.tm_hour; ftime.minutes = ufi.tmu_date.tm_min; ftime.twosecs = ufi.tmu_date.tm_sec / 2; fs3.attrFile = ulAttr; fs3.fdateCreation = fs3.fdateLastAccess = fs3.fdateLastWrite = fdate; fs3.ftimeCreation = fs3.ftimeLastAccess = fs3.ftimeLastWrite = ftime; ulrc = DosSetPathInfo( ( PCSZ ) szNameOS, FIL_STANDARD, &fs3, sizeof( fs3 ), DSPI_WRTTHRU ); } if( pszFree ) hb_xfree( pszFree ); } #else { hb_fsSetAttr( szName, ufi.external_fa ); } #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_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_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 */ ( void ) setuid( getuid() ); ( void ) 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; }