/*++ 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.")) ; }