unsigned SysRunCommandPipe( const char *cmd, int *readpipe ) { int rc; HANDLE pipe_input; HANDLE pipe_output; HANDLE pipe_input_dup; SECURITY_ATTRIBUTES sa; sa.nLength = sizeof( sa ); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; if( !CreatePipe( &pipe_input, &pipe_output, &sa, 0 ) ) { return( GetLastError() ); } SetStdHandle( STD_OUTPUT_HANDLE, pipe_output ); SetStdHandle( STD_ERROR_HANDLE, pipe_output ); DuplicateHandle( GetCurrentProcess(), pipe_input, GetCurrentProcess(), &pipe_input_dup, 0, FALSE, DUPLICATE_SAME_ACCESS ); CloseHandle( pipe_input ); rc = RunChildProcessCmdl( cmd ); CloseHandle( pipe_output ); *readpipe = _hdopen( ( int ) pipe_input_dup, O_RDONLY ); return( rc ); }
_WCRTLINK int _pipe( int *phandles, unsigned psize, int textmode ) /****************************************************************/ { #if defined(__NT__) HANDLE hRead, hWrite; // HANDLE osHandle; // removed by JBS BOOL rc; SECURITY_ATTRIBUTES sa; #elif defined(__OS2__) && defined(__386__) HFILE hRead, hWrite; APIRET rc; #elif defined(__OS2__) && !defined(__386__) HFILE hRead, hWrite; USHORT rc; #endif int hReadPosix, hWritePosix; // removed by JBS - allow O_NOINHERIT // /*** Sanity check ***/ // if( textmode != 0 && textmode != _O_TEXT && textmode != _O_BINARY ) { // return( -1 ); // } /*** Create the pipes (note that psize==0 ==> use default size) ***/ #if defined(__NT__) sa.nLength = sizeof( SECURITY_ATTRIBUTES ); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = (((textmode & O_NOINHERIT)==O_NOINHERIT)?FALSE:TRUE); rc = CreatePipe( &hRead, &hWrite, &sa, psize ); if( rc == FALSE ) { return( __set_errno_nt() ); } #elif defined(__OS2__) if( psize == 0 ) psize = 4096; #ifdef __386__ rc = DosCreatePipe( &hRead, &hWrite, psize ); #else rc = DosMakePipe( &hRead, &hWrite, psize ); #endif if( rc != NO_ERROR ) { __set_errno( ENOMEM ); return( -1 ); } #endif // removed by JBS - used sa struct instead // /*** Make read handle inheritable ***/ // #ifdef __NT__ // rc = DuplicateHandle( GetCurrentProcess(), hRead, GetCurrentProcess(), // &osHandle, 0, TRUE, DUPLICATE_SAME_ACCESS ); // if( rc == FALSE ) { // CloseHandle( hRead ); // CloseHandle( hWrite ); // return( -1 ); // } // CloseHandle( hRead ); // hRead = osHandle; // #elif defined(__OS2__) // /* Handle is inheritable by default */ // #endif // // /*** Make write handle inheritable ***/ // #ifdef __NT__ // rc = DuplicateHandle( GetCurrentProcess(), hWrite, GetCurrentProcess(), // &osHandle, 0, TRUE, DUPLICATE_SAME_ACCESS ); // if( rc == FALSE ) { // CloseHandle( hRead ); // CloseHandle( hWrite ); // return( -1 ); // } // CloseHandle( hWrite ); // hWrite = osHandle; // #elif defined(__OS2__) // /* Handle is inheritable by default */ // #endif /*** Initialize the POSIX-level handles ***/ hReadPosix = _hdopen( (int)hRead, textmode|_O_RDONLY ); hWritePosix = _hdopen( (int)hWrite, textmode|_O_WRONLY ); if( hReadPosix == -1 || hWritePosix == -1 ) { if( hReadPosix != -1 ) { close( hReadPosix ); } else { #if defined(__NT__) CloseHandle( hRead ); #elif defined(__OS2__) DosClose( hRead ); #endif } if( hWritePosix != -1 ) { close( hWritePosix ); } else { #if defined(__NT__) CloseHandle( hWrite ); #elif defined(__OS2__) DosClose( hWrite ); #endif } return( -1 ); } /*** Store the new POSIX handles in return buffer ***/ phandles[0] = hReadPosix; phandles[1] = hWritePosix; return( 0 ); }
_WCRTLINK FILE *__F_NAME(_popen,_wpopen)( const CHAR_TYPE *command, const CHAR_TYPE *mode ) /*****************************************************************************************/ { #if defined(__NT__) HANDLE osHandle; BOOL rc; int handleMode; #elif defined(__OS2__) && defined(__386__) APIRET rc; ULONG handleState; #elif defined(__OS2__) && !defined(__386__) USHORT rc; USHORT handleState; #endif FILE * fp; int handles[2]; CHAR_TYPE textOrBinary; CHAR_TYPE readOrWrite; /*** Parse the mode string ***/ switch( mode[0] ) { /* read or write */ case 'r': readOrWrite = 'r'; break; case 'w': readOrWrite = 'w'; break; default: return( NULL ); } switch( mode[1] ) { /* text or binary */ case 't': textOrBinary = 't'; break; case 'b': textOrBinary = 'b'; break; default: textOrBinary = _RWD_fmode == _O_BINARY ? 'b' : 't'; } /*** Create the pipe at the OS level ***/ if( _pipe( handles, 0, textOrBinary == 't' ? _O_TEXT : _O_BINARY ) == -1 ) { return( NULL ); } /*** Make read handle non-inheritable if reading ***/ if( readOrWrite == 'r' ) { #if defined( __NT__ ) rc = DuplicateHandle( GetCurrentProcess(), (HANDLE)_os_handle(handles[0]), GetCurrentProcess(), &osHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if( rc == FALSE ) { return( 0 ); } close( handles[0] ); /* don't need this any more */ handleMode = _O_RDONLY | (textOrBinary == 't' ? _O_TEXT : _O_BINARY); handles[0] = _hdopen( (int)osHandle, handleMode ); if( handles[0] == -1 ) { CloseHandle( osHandle ); close( handles[1] ); return( 0 ); } #elif defined( __OS2__ ) rc = DosQFHandState( (HFILE)_os_handle(handles[0]), &handleState ); if( rc != NO_ERROR ) { return( 0 ); } handleState |= OPEN_FLAGS_NOINHERIT; handleState &= 0x00007F88; /* some bits must be zero */ rc = DosSetFHandState( (HFILE)_os_handle(handles[0]), handleState ); if( rc != NO_ERROR ) { return( 0 ); } #endif } /*** Make write handle non-inheritable if writing ***/ else { #if defined (__NT__ ) rc = DuplicateHandle( GetCurrentProcess(), (HANDLE)_os_handle(handles[1]), GetCurrentProcess(), &osHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if( rc == FALSE ) { return( 0 ); } close( handles[1] ); /* don't need this any more */ handleMode = _O_WRONLY | (textOrBinary == 't' ? _O_TEXT : _O_BINARY); handles[1] = _hdopen( (int)osHandle, handleMode ); if( handles[1] == -1 ) { CloseHandle( osHandle ); close( handles[0] ); return( 0 ); } #elif defined( __OS2__ ) rc = DosQFHandState( (HFILE)_os_handle(handles[1]), &handleState ); if( rc != NO_ERROR ) { return( 0 ); } handleState |= OPEN_FLAGS_NOINHERIT; handleState &= 0x00007F88; /* some bits must be zero */ rc = DosSetFHandState( (HFILE)_os_handle(handles[1]), handleState ); if( rc != NO_ERROR ) { return( 0 ); } #endif } /*** Create the pipe's FILE* ***/ fp = __F_NAME(fdopen,_wfdopen)( handles[readOrWrite == 'r' ? 0 : 1], mode ); if( fp == NULL ) { close( handles[0] ); close( handles[1] ); return( NULL ); } _FP_PIPEDATA(fp).isPipe = 1; _FP_PIPEDATA(fp).pid = -1; /*** Spawn the process ***/ if( connect_pipe( fp, command, handles, readOrWrite, textOrBinary ) ) { return( fp ); } else { close( handles[0] ); close( handles[1] ); return( NULL ); } }