void main() { int handle; FILE *fp; fp = fopen( "file", "r" ); if( fp != NULL ) { handle = _os_handle( fileno( fp ) ); fclose( fp ); } }
/* * Return a pointer to a string containing information about currently open * POSIX-level file handles. If _fileinfo is non-zero, this string is * passed to child processes as an environment string. Each handle's data * is of the form "PPPPPPPP:OOOOOOOO:MMMMMMMM*", where the Ps represent the * POSIX-level file number, the Os represent the OS-level file number, and * the Ms represent the file's mode bits. The Ps, Os, and Ms are all hex * strings, without zero padding or 0x prefixes to conserve space. Returns * NULL if there is insufficient memory. The caller is responsible for * freeing the allocated memory. The returned string begins with * "C_FILE_INFO=", and so forms a valid environment string. */ _WCRTLINK CHAR_TYPE *__F_NAME(__FormPosixHandleStr,__wFormPosixHandleStr)( void ) /*******************************************************************************/ { extern unsigned __NFiles; CHAR_TYPE * p; int posixHandle, osHandle, mode; CHAR_TYPE curElem[MAX_ELEM_SIZE+1]; CHAR_TYPE buf[9]; size_t len; /*** Allocate memory for the string ***/ len = (__NFiles*MAX_ELEM_SIZE) + __F_NAME(strlen,wcslen)( STRING( "C_FILE_INFO=" ) ) + 1; p = lib_malloc( len * sizeof( CHAR_TYPE ) ); if( p == NULL ) return( NULL ); __F_NAME(strcpy,wcscpy)( p, STRING( "C_FILE_INFO=" ) ); /*** Process the open files ***/ for( posixHandle=0; posixHandle<__NFiles; posixHandle++ ) { __ChkTTYIOMode( posixHandle ); mode = __GetIOMode( posixHandle ); if( mode & _INITIALIZED ) { /* skip it if it's not open */ osHandle = _os_handle( posixHandle ); /*** Build the element string ***/ curElem[0] = NULLCHAR; __F_NAME(itoa,_itow)( posixHandle, buf, 16 ); /* POSIX handle */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( ":" ) ); /* separator */ __F_NAME(itoa,_itow)( osHandle, buf, 16 ); /* OS handle */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( ":" ) ); /* separator */ __F_NAME(itoa,_itow)( mode, buf, 16 ); /* file mode */ __F_NAME(strcat,wcscat)( curElem, buf ); __F_NAME(strcat,wcscat)( curElem, STRING( "*" ) ); /* terminator */ __F_NAME(strcat,wcscat)( p, curElem ); /* append it */ } } return( p ); }
_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 ); } }
static int connect_pipe( FILE *fp, const CHAR_TYPE *command, int *handles, int readOrWrite, int textOrBinary ) /************************************************************************/ { #if defined( __NT__ ) BOOL rc; HANDLE osHandle; HANDLE oldHandle; #elif defined( __WARP__ ) APIRET rc; HFILE osHandle; HFILE oldHandle; #elif defined( __OS2__ ) USHORT rc; HFILE osHandle; HFILE oldHandle; #endif if( readOrWrite == 'w' ) { /*** Change the standard input handle for process inheritance ***/ #if defined( __NT__ ) osHandle = GetStdHandle( STD_INPUT_HANDLE ); /* get old */ if( osHandle == INVALID_HANDLE_VALUE ) { return( 0 ); } oldHandle = osHandle; rc = SetStdHandle( STD_INPUT_HANDLE, /* set new */ (HANDLE)_os_handle(handles[0]) ); if( rc == FALSE ) { SetStdHandle( STD_INPUT_HANDLE, oldHandle ); return( 0 ); } #elif defined( __OS2__ ) oldHandle = (HFILE)0xFFFFFFFF; /* duplicate standard input */ rc = DosDupHandle( STDIN_HANDLE, &oldHandle ); if( rc != NO_ERROR ) return( 0 ); osHandle = STDIN_HANDLE; /* use new standard input */ rc = DosDupHandle( (HFILE)_os_handle(handles[0]), &osHandle ); if( rc != NO_ERROR ) { DosClose( oldHandle ); return( 0 ); } #endif /*** Spawn the process and go home ***/ if( spawn_it( fp, command ) == 0 ) { return( 0 ); } #if defined( __NT__ ) SetStdHandle( STD_INPUT_HANDLE, oldHandle ); #elif defined( __OS2__ ) osHandle = STDIN_HANDLE; rc = DosDupHandle( oldHandle, &osHandle ); #endif close( handles[0] ); /* parent process should close this */ } else { /*** Change the standard output handle for process inheritance ***/ #if defined( __NT__ ) osHandle = GetStdHandle( STD_OUTPUT_HANDLE ); /* get old */ if( osHandle == INVALID_HANDLE_VALUE ) { return( 0 ); } oldHandle = osHandle; rc = SetStdHandle( STD_OUTPUT_HANDLE, /* set new */ (HANDLE)_os_handle(handles[1]) ); if( rc == FALSE ) { SetStdHandle( STD_OUTPUT_HANDLE, oldHandle ); return( 0 ); } #elif defined( __OS2__ ) oldHandle = (HFILE)0xFFFFFFFF; /* duplicate standard input */ rc = DosDupHandle( STDOUT_HANDLE, &oldHandle ); if( rc != NO_ERROR ) { return( 0 ); } osHandle = STDOUT_HANDLE; /* use new standard input */ rc = DosDupHandle( (HFILE)_os_handle(handles[1]), &osHandle ); if( rc != NO_ERROR ) { DosClose( oldHandle ); return( 0 ); } #endif /*** Spawn the process and go home ***/ if( spawn_it( fp, command ) == 0 ) { return( 0 ); } #if defined( __NT__ ) SetStdHandle( STD_OUTPUT_HANDLE, oldHandle ); #elif defined( __OS2__ ) osHandle = STDOUT_HANDLE; rc = DosDupHandle( oldHandle, &osHandle ); #endif close( handles[1] ); /* parent process should close this */ } return( 1 ); }