views:

299

answers:

1

I've written a simple command line tool that uses getchar to wait for a termination signal (something like: 'Press enter to stop'). I however also want to handle the SC_CLOSE case (clicking the 'close' button). I did this by using SetConsoleCtrlHandler. But how do I cancel my getchar?

  • I tried doing fputc('\n', stdin);, but that results in a deadlock.
  • I can call ExitProcess, but then I get a crash in CThreadLocalObject::GetData when deleting a global CWnd, because the CThreadLocalObject is already deleted (okay, maybe I was lying when claiming it was a simple console application). I guess this might have something to do with the fact that the HandlerRoutine is called from a separate thread (not the main thread).
  • Maybe there's some sort of getchar with a timeout that I can call instead?
+2  A: 

Maybe there's some sort of getchar with a timeout that I can call instead?

You can read console input asynchronously:

#ifdef WIN32
 #include <conio.h>
#else
 #include <sys/time.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
#endif
int main(int argc, char* argv[])
{
 while(1)
 {
#ifdef WIN32
  if (kbhit()){
   return getc(stdin);
  }else{
   Sleep(1000);
   printf("I am still waiting for your input...\n");
  }
#else
  struct timeval tWaitTime;
  tWaitTime.tv_sec = 1;   //seconds
  tWaitTime.tv_usec = 0;  //microseconds
  fd_set fdInput;
  FD_ZERO(&fdInput);
  FD_SET(STDIN_FILENO, &fdInput);
  int n = (int) STDIN_FILENO + 1;
  if (!select(n, &fdInput, NULL, NULL, &tWaitTime))
  {
   printf("I am still waiting for your input...\n");
  }else
  {
   return getc(stdin);
  }
#endif
 }
 return 0;
}

In such a way, you can introduce bool bExit flag which indicates if your programs is required to terminate. You can read input in specialized thread or wrap this code into the function and call it periodically.

AlexKR
kbhit is exactly what I needed. Thx.
crimson13