By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

How to? ^C echo

Hi Rex, I'm a long time user of TCC and love it. I've had this issue for years, and was wondering what can be done about it. Essentially, after pressing Ctrl-Break. in a console app launched from TCC, upon exit TCC echos ^C. CMD.EXE does not do this:

BASIC-x86 Rev. 1.62
[Windows Version]
Copyright 1990,2011-2017 (c) by S.Pagliarulo
Created: 22-Aug-2017
126971 Bytes free
[Press Ctrl-Break]
^C <- echoed by TCC

Some additional info, my console app installs a handler routine and catches CTRL_BREAK_EVENT and CTRL_C_EVENT. Inside the handler, not much is done other than record the event and return TRUE.

I'm pretty sure that if TCC sees the signal, it will echo "^C". But if your app's handler returns TRUE, TCC shouldn't see the signal.
I'm pretty sure that if TCC sees the signal, it will echo "^C". But if your app's handler returns TRUE, TCC shouldn't see the signal.
I don't think that was correct. TCC will get the signal anyway.
BREAK OFF will work but it's taking a sledgehammer to the problem. Perhaps an easy fix is to provide a configuration option to disable the ^C echo.
I can't reproduce that here. TCC will only display ^C if its exception handler is called. If you have your own handler TCC won't see it (unless your handler is forwarding it to all other handlers).

Can you send an example app to [email protected]?
That's what I thought at first (being plugin-minded). But doesn't handling the signal (returning TRUE) only prevent other handlers from the same process, and the default handler, from seeing the signal? I tested with this code. I see the message immediately upon pressing Ctrl-C and I see "^C" 5 seconds later, when test.exe has exited. I'm not doing it.
 DWORD WINAPI thread ( LPVOID foo )
    Sleep(5000); // give handler time to return TRUE
    return 0;

BOOL WINAPI CtrlHandler ( DWORD dwSignal )
   CreateThread(NULL, 0, thread, NULL, 0, NULL);
   wprintf(L"Handler returns TRUE\n");
   return TRUE;

int wmain( INT argc, WCHAR **argv )
   SetConsoleCtrlHandler(CtrlHandler, TRUE);
   return 0;
Last edited:
Hers is code similar to what I use.

#include <windows.h>
#include <stdio.h>

static LONG g_lBreakEvent;

static BOOL WINAPI HandlerRoutine(DWORD dwCtrlType)
    BOOL bHandled = FALSE;

    if (dwCtrlType == CTRL_BREAK_EVENT || dwCtrlType == CTRL_C_EVENT)
        // set global flag
        InterlockedExchange(&g_lBreakEvent, TRUE);
        bHandled = TRUE;

    printf("Thread: %d, Returning %d\n", GetCurrentThreadId(), bHandled);
    return bHandled;

void main(int argc, char *argv[])
    // install our handler
    SetConsoleCtrlHandler(HandlerRoutine, TRUE);

    // ignore CTRL+C
    SetConsoleCtrlHandler(NULL, TRUE);

    printf("Thread: %d, Press Control Break\n", GetCurrentThreadId());

    for (;;)

        if (InterlockedExchange(&g_lBreakEvent, FALSE))

    SetConsoleCtrlHandler(NULL, FALSE);
    SetConsoleCtrlHandler(HandlerRoutine, FALSE);

    printf("Thread: %d, Exiting application\n", GetCurrentThreadId());

Similar threads