236 lines
6.5 KiB
C
236 lines
6.5 KiB
C
/*++
|
|
|
|
Copyright (c) 1988-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
csig.c
|
|
|
|
Abstract:
|
|
|
|
Interrupt (^C) processing
|
|
|
|
--*/
|
|
|
|
#include "cmd.h"
|
|
|
|
//
|
|
// console mode at program startup time. Used to reset mode
|
|
// after running another process.
|
|
//
|
|
extern DWORD dwCurInputConMode;
|
|
extern DWORD dwCurOutputConMode;
|
|
|
|
extern int Ctrlc;
|
|
|
|
VOID ResetCtrlC();
|
|
int SigHandFlag = FALSE ;
|
|
|
|
/* Commands that temporarily change directories, save a ptr to the original
|
|
* directory string here so that it can be restored by SigHand() if the
|
|
* command is interrupted before it has a chance to do it, itself.
|
|
*/
|
|
TCHAR *SaveDir = NULL ;
|
|
unsigned SIGNALcnt = 0;
|
|
|
|
extern int PipeCnt ; /* M016 - Cnt of active pipes */
|
|
|
|
extern int LastRetCode ;
|
|
|
|
extern jmp_buf MainEnv ;
|
|
extern jmp_buf CmdJBuf1 ;
|
|
|
|
extern unsigned long OHTbl[] ; /* M024 - Revised to be bit map */
|
|
|
|
extern PHANDLE FFhandles; /* @@1 */
|
|
extern unsigned FFhndlsaved; /* @@1 */
|
|
|
|
extern struct sellist *prexxsellist;
|
|
|
|
extern struct rio *rioCur ; /* M000 */
|
|
extern TCHAR *Fvars ; /* M026 */
|
|
extern TCHAR **Fsubs ; /* M026 */
|
|
extern TCHAR *save_Fvars ; /* @@ */
|
|
extern TCHAR **save_Fsubs ; /* @@ */
|
|
extern int FvarsSaved; /* @@ */
|
|
|
|
extern TCHAR InternalError[] ;
|
|
extern int EchoFlag ;
|
|
extern int EchoSave ; /* M013 - Used to restore echo status */
|
|
extern TCHAR ComSpec[] ; /* M008 - For clearing SM shared memory */
|
|
extern TCHAR ComSpecStr[] ; /* M026 - Use ComSpec for SM memory */
|
|
extern TCHAR *CmdSpec ; /* M026 */
|
|
|
|
extern unsigned Heof;
|
|
extern unsigned start_type ; /* Flag to indicate which API started the */
|
|
/* program. D64 */
|
|
|
|
extern BOOL CtrlCSeen;
|
|
extern PTCHAR pszTitleCur;
|
|
extern BOOLEAN fTitleChanged;
|
|
|
|
void
|
|
Abort( void )
|
|
{
|
|
|
|
DEBUG((SHGRP, MSLVL, "SIGHAND: Aborting Command")) ;
|
|
SigCleanUp();
|
|
longjmp(MainEnv, 1) ;
|
|
|
|
CMDexit( FAILURE );
|
|
}
|
|
|
|
void
|
|
CtrlCAbort( ) {
|
|
|
|
struct batdata *bdat;
|
|
|
|
if (CurrentBatchFile) {
|
|
|
|
if (PromptUser(NULL, MSG_BATCH_TERM, MSG_NOYES_RESPONSE_DATA) != 1) {
|
|
ResetCtrlC();
|
|
return;
|
|
|
|
}
|
|
|
|
//
|
|
// End local environments ( Otherwise we can end up with garbage
|
|
// in the main environment if any batch file used the setlocal
|
|
// command ).
|
|
//
|
|
bdat = CurrentBatchFile;
|
|
while ( bdat ) {
|
|
EndAllLocals( bdat );
|
|
bdat = bdat->backptr;
|
|
}
|
|
}
|
|
|
|
SigCleanUp();
|
|
longjmp(MainEnv, 1) ;
|
|
|
|
}
|
|
|
|
void
|
|
CheckCtrlC (
|
|
) {
|
|
|
|
if (CtrlCSeen) {
|
|
|
|
CtrlCAbort();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ExitAbort(
|
|
IN ULONG rcExitCode
|
|
)
|
|
{
|
|
|
|
SigCleanUp();
|
|
longjmp(MainEnv, rcExitCode) ;
|
|
|
|
CMDexit( FAILURE );
|
|
}
|
|
|
|
|
|
|
|
/*** SigCleanUp - close files and reset I/O after a signal
|
|
*
|
|
* Purpose:
|
|
* This function is called to finish the cleanup after an int 23 or 24.
|
|
* It resets all redirection back to the main level and it closes all
|
|
* files except those for stdin, stdout, stderr, stdaux and stdprint.
|
|
*
|
|
* void SigCleanUp()
|
|
*
|
|
* Args:
|
|
* None.
|
|
*
|
|
* Returns:
|
|
* Nothing.
|
|
*
|
|
* Notes:
|
|
* - M024 * Revised handle closing to be bit map based rather than struct.
|
|
*
|
|
*/
|
|
|
|
void SigCleanUp() /* M000 - Now void */
|
|
{
|
|
int cnt, cnt2 ;
|
|
unsigned long mask;
|
|
|
|
Heof = FALSE;
|
|
|
|
#ifndef WIN95_CMD
|
|
if (CurrentBatchFile) {
|
|
|
|
// Following CmdBatNotification call is a cleanup for the
|
|
// same call made from BatProc (in cbatch.c).
|
|
|
|
CmdBatNotification (CMD_BAT_OPERATION_TERMINATING);
|
|
EchoFlag = EchoSave ;
|
|
GotoFlag = FALSE ;
|
|
eEndlocal( NULL ) ;
|
|
CurrentBatchFile = NULL ;
|
|
} ;
|
|
#endif // WIN95_CMD
|
|
|
|
if (!FvarsSaved) { /* @WM If already saved, don't save again */
|
|
save_Fvars = Fvars; /* @@ */
|
|
save_Fsubs = Fsubs; /* @@ */
|
|
FvarsSaved = TRUE; /* @@ */
|
|
}
|
|
Fvars = NULL ; /* M026 - Must kill FOR */
|
|
Fsubs = NULL ; /* ...variable subst's */
|
|
|
|
/* M000 - New method is simpler. If redirection has been done, the highest
|
|
* numbered handle resulting from redirection is saved, then the linked
|
|
* riodata list is unlinked until the first (main) level of redirection is
|
|
* reached at which time ResetRedir is used to reset it. Then all open
|
|
* handles from 5 to the highest numbered redirection handle (minimum of
|
|
* 19) are freed.
|
|
* M014 - Altered this to use actual global pointer when unwinding the
|
|
* riodata list to fix bug. Also revised the ->stdio element to conform
|
|
* to new data structure. Note that ResetRedir automatically resets the
|
|
* rioCur pointer to the last valid riodata structure before returning;
|
|
* same as if "rioCur=rioCur->back" was in the while loop.
|
|
*/
|
|
DEBUG((SHGRP, MSLVL, "SCLEANUP: Resetting redirection.")) ;
|
|
|
|
while (rioCur)
|
|
ResetRedir() ;
|
|
|
|
DEBUG((SHGRP, MSLVL, "SCLEANUP: Breaking pipes.")) ;
|
|
|
|
BreakPipes() ;
|
|
|
|
DEBUG((SHGRP, MSLVL, "SCLEANUP: Now closing extra handles.")) ;
|
|
|
|
for (cnt = 0; cnt < 3; cnt++) {
|
|
if (OHTbl[cnt]) { /* Any handles to reset? */
|
|
mask = 1; /* @@1 */
|
|
for (cnt2 = 0; cnt2 < 32; cnt2++, mask <<= 1) { /* @@1 */
|
|
if ((OHTbl[cnt] & mask) && /* @@1 */
|
|
((cnt == 0 && cnt2 > 2) || cnt != 0) ) { /* @@1 */
|
|
/* Don't close STDIN, STDOUT, STDERR */ /* @@1 */
|
|
Cclose(cnt2 + 32*cnt); /* @@1 */
|
|
} /* @@1 */
|
|
} /* @@1 */
|
|
} /* @@1 */
|
|
}
|
|
|
|
/* Close find first handles */ /* @@1 */
|
|
|
|
while (FFhndlsaved) { /* findclose will dec this @@1 */
|
|
findclose(FFhandles[FFhndlsaved - 1]); /* @@1 */
|
|
} /* @@1 */
|
|
|
|
ResetConTitle( pszTitleCur );
|
|
|
|
ResetConsoleMode();
|
|
|
|
DEBUG((SHGRP, MSLVL, "SCLEANUP: Returning.")) ;
|
|
}
|