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; }
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; }