Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com X-Apparently-From: From: "bucweat_20657" To: Subject: control-c issue when running VC++ console programs in bash.exe Date: Fri, 24 Aug 2001 17:25:14 -0400 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 Importance: Normal Hi, I've been having problems figuring out how to correctly handle control-c for Visual C++ console programs run in cygwin bash.exe shell. After a related post to this list, Troy Noble responded and we've been playing around with some examples. Below is an example that illustrates some issues. I send this to the list in the hopes that one of the cygwin gurus might be able to help explain this behavior. Try this experiment: 1. compile the program listing below using both g++ and VC++ (command line is fine). 2. open up your NT/Win2k task manager. 3. open a bash window and then start up ctrlhandler.exe (the one compiled with VC++) 4. see how another bash.exe now shows up in your task manager processes list? 5. start up another bash window and run 'ps' 6. see how ctrlhandler shows up with the same PID in the 'ps' list as the bash.exe's PID in task manager? That's not right. And the WINPID matches PID in the ps listing, which isn't right either I don't think. Also notice that this extra bash.exe is hidden and doesn't show up in the 'ps' process list. 7. control-c and watch output. 7. Repeat with cygwin compiled program. Notice task in task manager, and no "hidden" bash process. 8. control-c and compare output to VC++ program. For the VC++ compiled program, When you press CTRL-C in the window this results in the original bash.exe eventually calling into signals.cc:kill_pgrp. It sends a kill(pid, SIGINT) to the hidden bash.exe, which exits causing your win32 to exit immediately. Hence things like destructors and other clean up functions don't get to execute. Note that I've also tried POSIX signals. While this works great for cygwin g++ programs run in bash.exe and VC++ compiled programs in DOS shell, it does not work correctly for VC++ compiled programs run in bash.exe. You basically end up with similar behavior to that mentioned above. So, is this the expected behavior for running VC++ compiled program in bash.exe? Can someone explain why VC++ compiled programs seem to run inside a "hidden" bash.exe shell when viewed via Win NT/2K taskmanager? Is there a correct way to handle control-c in VC++ compiled programs run in bash.exe? VR, Charlie PS thanks to Troy for his help in working on this issue. ------------- program ctrlhandler.cpp -------------------- // ctrlhandler.cpp // // Original program by Troy Noble [troy DOT noble AT channelpoint DOT com] // Some minor changes by Charlie Buckheit [bucweat_20657 AT yahoo DOT com] // // A program that sets up two WIN32 signal handlers to test // how control-c is handled for a VC++ compiled program // by cygwin as compared to one compiled with g++ // // How to compile: // For cygwin use "g++ ctrlhandler.cpp -o cygwin_ctrlhandler" // For VC++ use "vcvars32", then "cl -GX ctrlhandler.cpp" // // Options: // -b swaps order that the control-c handlers are setup // #if defined (_WIN32) && !defined (__CYGWIN__) #pragma warning(disable:4786) #else #include #endif #include #include #include static BOOL WINAPI ctrl_c_handler (DWORD); static BOOL WINAPI ctrl_c_handler2 (DWORD); static int bRun = true; // Keyboard interrupt handler. static BOOL WINAPI ctrl_c_handler (DWORD type) { cout << "ctrl_c_handler type=" << type << " pid=" << _getpid() << endl; // If I got a CTRL-C or CTRL-BREAK I want to do my // cleanup and exit gracefully now if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) { // do your cleanup code cout << "cleanup time. set bRun=false" << endl; bRun = false; cout << "ctrl_c_handler done." << endl; int count = 0; while( ++count < 10 ) { cerr << " " << count; Sleep(1000); } return TRUE; // Notify not to call other handlers. } // Note: you want want to handle CTRL_LOGOFF_EVENT, // CTRL_CLOSE_EVENT, or CTRL_SHUTDOWN_EVENT in // some form or another as well here. See MSDN // docs on SetConsoleCtrlHandler & friends as well // as winsup/cygwin/exceptions.cc:ctrl_c_handler // which is a pretty good example. // Otherwise let other ctrl handler have crack at it return FALSE; } // Keyboard interrupt handler. static BOOL WINAPI ctrl_c_handler2 (DWORD type) { // If I got a CTRL-C or CTRL-BREAK I want to do my cout << "ctrl_c_handler#2 type=" << type << " pid=" << _getpid() << endl; int count = 64; while( ++count <= 74 ) { cerr << " " << (char)count; Sleep(1000); } // Always let other ctrl handler have a crack at it return FALSE; } int main(int argc, char* argv[]) { // variable declarations and whatnot ... bool bBefore = (argc > 1 && stricmp(argv[1], "-b") == 0); if (bBefore) { // Setup SECOND console ctrl handler BEFORE if (!SetConsoleCtrlHandler (ctrl_c_handler2, TRUE)) cerr << "SetConsoleCtrlHandler #2 failed." << endl; cout << "Second control handler registered first." << endl; } // Setup SECOND console ctrl handler BEFORE if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE)) cerr << "SetConsoleCtrlHandler failed." << endl; // your code here if (!bBefore) { // Setup SECOND console ctrl handler AFTER if (!SetConsoleCtrlHandler (ctrl_c_handler2, TRUE)) cerr << "SetConsoleCtrlHandler #2 failed." << endl; cout << "Second control handler registered second." << endl; } cout << endl; while (bRun) { cout << endl << "Sleep a little. "; Sleep(2000); } cout << "bRun is false. Exiting." << endl; return 0; } _________________________________________________________ Do You Yahoo!? Get your free @yahoo.com address at http://mail.yahoo.com -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Bug reporting: http://cygwin.com/bugs.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/