home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_08_07
/
8n07033a
< prev
next >
Wrap
Text File
|
1990-06-19
|
5KB
|
182 lines
/****************************************************************************/
/* */
/* ROUTEMSG.C - OS/2 utility to invoke a child process and route its STDOUT */
/* and STRERR streams to both the video display as well as an */
/* ASCII file. */
/* */
/****************************************************************************/
/* Modification Log */
/****************************************************************************/
/* --Date-- ----Programmer---- -------------Comments------------------- */
/* */
/* 06/10/89 Bob Withers Program originally complete */
/* */
/****************************************************************************/
#pragma check_stack(off)
#define INCL_DOS
#define INCL_VIO
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <os2.h>
#define STDOUT_HANDLE 1
#define STDERR_HANDLE 2
#define STATIC static
#ifndef FILE_NORMAL
#define FILE_NORMAL 0x0000
#define FILE_CREATE 0x0010
#define FILE_TRUNCATE 0x0002
#define OPEN_ACCESS_WRITEONLY 0x0001
#define OPEN_SHARE_DENYWRITE 0x0020
#define OPEN_FLAGS_NOINHERIT 0x0080
#endif
STATIC VOID NEAR _CDECL ErrorMsg(CHAR *str, ...);
static HFILE fh_stdout = STDOUT_HANDLE;
static HFILE fh_stderr = STDERR_HANDLE;
static CHAR acBuffer[1024];
static CHAR szPgmName[128];
INT _CDECL main(INT argc, CHAR **argv)
{
register SHORT i;
register CHAR *p;
auto SHORT sLen;
auto HFILE fh_output;
auto HFILE fh_piperead, fh_pipewrite;
auto USHORT usRetCode, usAction;
auto RESULTCODES rc;
auto CHAR szFailName[64];
/* (A) verify we have the minimum number of command line arguments */
if (argc < 3)
{
ErrorMsg("Usage: %s <filename> <pgmname> [<args> ...]\n", argv[0]);
DosExit(EXIT_PROCESS, 1);
}
/* (B) open the output file, truncate it if it exists otherwise create */
usRetCode = DosOpen(argv[1], &fh_output,
&usAction, 0L,
FILE_NORMAL,
FILE_CREATE | FILE_TRUNCATE,
OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE
| OPEN_FLAGS_NOINHERIT,
0L);
if (usRetCode)
{
ErrorMsg("Unable to open file %s (Error status = %u)\n",
argv[1], usRetCode);
DosExit(EXIT_PROCESS, 2);
}
/* (C) create the pipe to be inherited by the child process */
usRetCode = DosMakePipe(&fh_piperead, &fh_pipewrite, 0);
if (usRetCode)
{
DosClose(fh_output);
ErrorMsg("Unable to create pipe (Error status = %u)\n", usRetCode);
DosExit(EXIT_PROCESS, 3);
}
/* (D) no longer need original STDOUT and STDERR so close them */
DosClose(fh_stdout);
DosClose(fh_stderr);
/* (E) redirect STDOUT and STDERR to the pipe's write file handle */
DosDupHandle(fh_pipewrite, &fh_stdout);
DosDupHandle(fh_pipewrite, &fh_stderr);
/* (F) set pipe read handle to NOINHERIT so that it will not reduce the */
/* number of handles available to the child process */
DosSetFHandState(fh_piperead, OPEN_FLAGS_NOINHERIT);
/* (G) the pipe write handle has been redirected, no longer needed */
DosClose(fh_pipewrite);
/* (H) format the program name to execute as the child process */
if (NULL == strchr(strupr(strcpy(szPgmName, argv[2])), '.'))
strcat(szPgmName, ".EXE");
/* (I) format the command line to be passed to the child process */
strcpy(acBuffer, argv[2]);
p = acBuffer + strlen(acBuffer) + 1;
for (i = 3; i < argc; ++i)
{
sLen = strlen(argv[i]);
memcpy(p, argv[i], sLen);
p += sLen;
*p++ = ' ';
}
*p++ = '\0';
*p = '\0';
/* (J) try to execute the child process */
usRetCode = DosExecPgm(szFailName, sizeof(szFailName),
EXEC_ASYNC,
acBuffer,
NULL,
&rc,
szPgmName);
if (usRetCode)
{
ErrorMsg("Unable to bid child %s (Error status = %u [%s])\n",
szPgmName, usRetCode, szFailName);
DosExit(EXIT_PROCESS, 4);
}
/* (K) no longer need the pipe write handles so close them now */
DosClose(fh_stdout);
DosClose(fh_stderr);
/* (L) read data from the pipe and route it to screen and file */
while (TRUE)
{
auto USHORT usBytesRead, usBytesWritten;
static BOOL bError = FALSE;
usRetCode = DosRead(fh_piperead, acBuffer,
sizeof(acBuffer), &usBytesRead);
if (usRetCode || 0 == usBytesRead)
break;
VioWrtTTY(acBuffer, usBytesRead, 0);
if (!bError)
{
DosWrite(fh_output, acBuffer, usBytesRead, &usBytesWritten);
if (usBytesWritten != usBytesRead)
{
ErrorMsg("Unable to write to output file, disk full?\n");
bError = TRUE;
}
}
}
/* (M) close the pipe read handle and the output file handle */
DosClose(fh_piperead);
DosClose(fh_output);
return(0);
}
STATIC VOID NEAR _CDECL ErrorMsg(CHAR *str, ...)
{
auto va_list va;
va_start(va, str);
VioWrtTTY(acBuffer, vsprintf(acBuffer, str, va), 0);
va_end(va);
return;
}