Notes on Open Watcom _popen

The synopsis is at the bottom of page and I am only concern with OS2 __386__.

Create pipe using OW _pipe:

_pipe( handles, 0, textOrBinary == ‘t’ ? _O_TEXT : _O_BINARY)

Make handle non-inheritable if read or write:

rc = DosQFHandState( (HFILE)_os_handle(handles[0 read or 1 for write]), &handleState );
 
NOTE:
Search in API for DosQueryFHState instead of DosQFHandState
16-bit DosQFHandState 32-bit DosQueryFHState 
They are both the same function, see bsedos.h.
 
handleState |= OPEN_FLAGS_NOINHERIT;
handleState &= 0x00007F88; /* some bits must be zero */ 0111111110001000

rc = DosSetFHandState( (HFILE)_os_handle(handles[0]), handleState );

 
NOTE:
Search in API for DosSetFHState instead of DosSetFHandState
16-bit DosSetFHandState 32-bit DosSetFHState 
They are both the same function, see bsedos.h.

Create the pipe’s FILE:

fp = __F_NAME(fdopen,_wfdopen)( handles[readOrWrite == ‘r’ ? 0 : 1], mode );
_FP_PIPEDATA(fp).isPipe = 1;
_FP_PIPEDATA(fp).pid = -1;
/lib_misc/h/rtdata.h: #define _FP_PIPEDATA(__fp) ((__fp)->_link->pipeInfo)

Spawn the process:

if( connect_pipe( fp, command, handles, readOrWrite, textOrBinary ) ) 
 
connect_pipe is static function:
static int connect_pipe( FILE *fp, const CHAR_TYPE *command, int *handles,
int readOrWrite, int textOrBinary )

If write – 
oldHandle = 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 );
}

 
if read –
oldHandle = 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 );
}
 
/* Spawn the process and go home */
if( spawn_it( fp, command ) == 0 ) {
return( 0 );
}
spawn_it summary:
Sets up spawnvp (P_NOWAIT) for execution. Problem here is that uses CMD.EXE under NT and OS/2, and COMMAND.COM under Win95. 
After executing spawnvp _FP_PIPEDATA(fp).pid to set pid.
 
back to connect_pipe –> 
osHandle = STDOUT_HANDLE;
rc = DosDupHandle( oldHandle, &osHandle );
close( handles[1] ); /* parent process should close this */
 
return from _popen
return( fp )

 


Synopsis: 

#include <stdio.h> 
FILE *_popen( const char *command, const char *mode ); 
FILE *_wpopen( const wchar_t *command, const wchar_t *mode ); 

Description: 
The _popen function executes the command specified by command and creates a pipe between the calling process and the executed command. 

Depending on the mode argument, the stream pointer returned may be used to read from or write to the pipe. 

The executed command has an environment the same as its parents. The command will be started as follows: spawnl(<shell_path>, <shell>, “-c”, command, (char *)NULL); 

where <shell_path> is an unspecified path for the shell utility and <shell> is one of “command.com” (DOS, Windows 95) or “cmd.exe” (Windows NT/2000, OS/2). 

The mode argument to _popen is a string that specifies an I/O mode for the pipe. 

Mode Meaning 

“r” 
The calling process will read from the standard output of the child process using the stream pointer returned by _popen. 

“w” 
The calling process will write to the standard input of the child process using the stream pointer returned by _popen. 
The letter “t” may be added to any of the above modes to indicate that the file is (or must be) a text file (i.e., CR/LF pairs are converted to newline characters). 

The letter “b” may be added to any of the above modes to indicate that the file is (or must be) a binary file (an ANSI requirement for portability to systems that make a distinction between text and binary files). 

When default file translation is specified (i.e., no “t” or “b” is specified), the value of the global variable _fmode establishes whether the file is to treated as a binary or a text file. Unless this value is changed by the program, the default will be text mode. 

A stream opened by _popen should be closed by the pclose function. 

Returns: 
The _popen function returns a non-NULL stream pointer upon successful completion. If _popen is unable to create either the pipe or the subprocess, a NULL stream pointer is returned and errno is set appropriately. 

Errors: 
When an error has occurred, errno contains a value indicating the type of error that has been detected. 

Constant 
Meaning 

EINVAL 
The mode argument is invalid. 
_popen may also set errno values as described by the _pipe and spawnl functions.