📄 execute.c
字号:
/*--------------------------------------------------------------------*/
/* e x e c u t e . C */
/* */
/* Execute an external command for UUPC/extended functions */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* Changes Copyright (c) 1989-1993 by Kendra Electronic */
/* Wonderworks. */
/* */
/* All rights reserved except those explicitly granted by */
/* the UUPC/extended license agreement. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* RCS Information */
/*--------------------------------------------------------------------*/
/*
* $Id: execute.c 1.11 1993/10/03 22:09:09 ahd Exp $
*
* Revision history:
* $Log: execute.c $
* Revision 1.11 1993/10/03 22:09:09 ahd
* Change debugging messages
*
* Revision 1.10 1993/10/02 22:56:59 ahd
* Suppress compile warning
*
* Revision 1.9 1993/10/02 19:07:49 ahd
* Suppress compiler warning
*
* Revision 1.8 1993/09/27 00:45:20 ahd
* Fix Windows compile, add debug to OS/2 and DOS version
*
* Revision 1.7 1993/09/26 03:32:27 dmwatt
* Use Standard Windows NT error message module
*
* Revision 1.6 1993/09/23 03:26:51 ahd
* Use common file search routine
*
* Revision 1.5 1993/09/20 04:38:11 ahd
* TCP/IP support from Dave Watt
* 't' protocol support
* OS/2 2.x support
*
* Revision 1.4 1993/08/08 17:39:09 ahd
* Denormalize path for opening on selected networks
*
* Revision 1.3 1993/08/03 03:11:49 ahd
* Further Windows 3.x fixes
*
* Revision 1.2 1993/08/02 03:24:59 ahd
* Further changes in support of Robert Denny's Windows 3.x support
*
* Revision 1.1 1993/07/31 16:22:16 ahd
* Initial revision
*
*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <process.h>
#include <io.h>
#ifdef WIN32
#include <windows.h>
#include <signal.h>
#elif defined(_Windows)
#include <windows.h>
#include <shellapi.h>
#endif
#include <direct.h>
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "hlib.h"
#include "execute.h"
#ifdef _Windows
#include "winutil.h"
#endif
#ifdef WIN32
#include "pnterr.h"
#endif
/*--------------------------------------------------------------------*/
/* Local variables */
/*--------------------------------------------------------------------*/
currentfile();
/*--------------------------------------------------------------------*/
/* Internal function prototypes */
/*--------------------------------------------------------------------*/
static boolean internal( const char *command );
static boolean batch( const char *input, char *output);
#ifdef _Windows
/*--------------------------------------------------------------------*/
/* e x e c u t e (Windows 3.x version) */
/* */
/* execute external command under Windows */
/*--------------------------------------------------------------------*/
int execute( const char *command,
const char *parameters,
const char *input,
const char *output,
const boolean synchronous,
const boolean foreground )
{
int result;
boolean useBat = (input != NULL) || (output != NULL );
char path[FILENAME_MAX]; /* String for executable file */
char batchFile[FILENAME_MAX]; /* String for batch driver file */
char perfect[FILENAME_MAX]; /* String for results test file */
/*--------------------------------------------------------------------*/
/* Locate the command */
/*--------------------------------------------------------------------*/
if ( internal( command ) )
{
strcpy( path , command );
useBat = TRUE;
}
else if (batch( command, path ))
{
if (useBat) // Using redirection?
{
printmsg(0,"Cannot use redirection with batch file %s",
path );
return -2;
}
} /* else */
else if ( !*path ) // Error returned from search?
return -1; // Yes --> Error already reported
/*--------------------------------------------------------------------*/
/* Generate a batch file for redirected DOS programs, if needed */
/*--------------------------------------------------------------------*/
if ( useBat )
{
FILE *stream ;
mktempname( batchFile, "BAT");
mktempname( perfect, "TMP");
stream = FOPEN( batchFile, "w", TEXT_MODE );
if ( stream == NULL )
{
printerr( batchFile );
panic();
}
fprintf( stream ,
"@echo off\n%s %s",
path,
parameters == NULL ? "" : parameters );
if ( input != NULL )
fprintf( stream, " < %s", input );
if ( output != NULL )
fprintf( stream, " < %s", output );
fprintf( stream,
"\nif errorlevel 1 erase %s\n",
perfect );
fclose ( stream );
stream = FOPEN( perfect, "w", TEXT_MODE );
if ( stream == NULL )
{
printerr( perfect );
panic();
}
fclose( stream );
strcpy( path, batchFile ); // Run the batch command
} /* if ( useBat ) */
/*--------------------------------------------------------------------*/
/* Actually run the command */
/*--------------------------------------------------------------------*/
result = SpawnWait( path,
parameters,
synchronous,
foreground ? SW_MAXIMIZE : SW_SHOWMINNOACTIVE );
/*--------------------------------------------------------------------*/
/* For batch files, we can only report zero/non-zero */
/* results. Do so, and clean up our input file at the same */
/* time. */
/*--------------------------------------------------------------------*/
if ( useBat )
{
int unlinkResult = unlink( perfect );
if (( result == 0 ) && (unlinkResult != 0))
result = 255;
if (unlink( batchFile ))
printerr( batchFile );
} /* if ( useBat ) */
/*--------------------------------------------------------------------*/
/* Report results of command */
/*--------------------------------------------------------------------*/
printmsg( 4,"Result of spawn %s is ... %d", command, result);
return result;
} /* execute */
#elif defined(WIN32)
/*--------------------------------------------------------------------*/
/* e x e c u t e (Windows NT version) */
/* */
/* Execute an external program */
/*--------------------------------------------------------------------*/
int execute( const char *command,
const char *parameters,
const char *input,
const char *output,
const boolean synchronous,
const boolean foreground )
{
int result;
char path[BUFSIZ];
/*--------------------------------------------------------------------*/
/* Redirect STDIN and STDOUT as required */
/*--------------------------------------------------------------------*/
if ((input != NULL) && (freopen(input , "rb", stdin) == NULL))
{
printerr(input);
return -2;
}
if ((output != NULL) && (freopen(output, "wt", stdout) == NULL))
{
printerr( output );
if ( input != NULL )
{
FILE *temp = freopen("con", "rt", stdin);
if ( (temp == NULL) && (errno != 0) )
{
printerr("stdin");
panic();
}
setvbuf( stdin, NULL, _IONBF, 0);
} /* if ( input != NULL ) */
return -2;
}
/*--------------------------------------------------------------------*/
/* Execute the command in question */
/*--------------------------------------------------------------------*/
if (internal(strcpy(path,command)) ||
batch(command, path)) // Internal or batch command?
{
if ( parameters == NULL )
result = system( path );
else {
strcat( path, " ");
strcat( path, parameters );
result = system( path );
} /* else */
} /* if (internal(command)) */
else { /* No --> Invoke normally */
STARTUPINFO si;
PROCESS_INFORMATION pi;
void *oldCtrlCHandler;
if ( ! *path ) // Did search fail?
return -2; // Yes --> Msg issued, just return
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpTitle = (LPSTR)command;
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = foreground ? SW_MAXIMIZE : SW_SHOWMINNOACTIVE;
if (parameters != NULL)
{
strcat( path, " ");
strcat( path, parameters );
}
result = CreateProcess(NULL,
path,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi);
if (!result) // Did CreateProcess() fail?
{ // Yes --> Report error
DWORD dwError = GetLastError();
printmsg(0, "execute: CreateProcess failed");
printNTerror("CreateProcess", dwError);
}
else {
if (synchronous)
{
/*--------------------------------------------------------------------*/
/* Set things up so that we ignore Ctrl-C's coming in to the */
/* child, and wait for other application to finish. */
/*--------------------------------------------------------------------*/
oldCtrlCHandler = signal(SIGINT, SIG_IGN);
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &result);
signal(SIGINT, oldCtrlCHandler); // Re-enable Ctrl-C handling
} /* if (synchronous) */
else
result = 0;
/*--------------------------------------------------------------------*/
/* If we're spawning asynchronously, we assume that we don't */
/* care about the exit code from the spawned process. */
/* Closing these makes it impossible to get at the old */
/* process's exit code. */
/*--------------------------------------------------------------------*/
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} /* else !result */
} /* else internal command */
/*--------------------------------------------------------------------*/
/* Re-open our standard i/o streams */
/*--------------------------------------------------------------------*/
if ( output != NULL )
{
freopen("con", "wt", stdout);
setvbuf( stdout, NULL, _IONBF, 0);
}
if ( input != NULL )
{
FILE *temp = freopen("con", "rt", stdin);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -