I\'m working on a program which will be taking in user input from the console as well as printfing out in a separate thread. I want to avoid situations where the user is hal
Here's an example of how to turn off echo from C, taken directly from an HP forum (and I haven't personally tested it):
Okay this should be a simple example of turning off echo:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <termios.h> #define STDIN_FDES 0 struct termios save; int main(int argc, char *argv[]) { int cc = 0; char s_tmp[80],*p = NULL; struct termios work; cc = tcgetattr(STDIN_FDES,&save); work = save; work.c_lflag &= ~(ECHO); cc = tcsetattr(STDIN_FDES,TCSANOW,&work); (void) printf("\nEnter value: "); (void) fflush(stdout); p = fgets(s_tmp,sizeof(s_tmp),stdin); if (p != NULL) (void) printf("Out -> %s\n",p); cc = tcsetattr(STDIN_FDES,TCSANOW,&save); return(cc); }
NOTE: It is very important that you have signal handlers to catch SIGINT, SIGTERM, ... and reset the terminal using the original termios because the last tcsetattr() wins and this applies to the terminal device NOT simply the process. If you leave the process with echo off, it will be off in the shell as well.
Otherwise, if Bash is a suitable approach, apparently you can just do stty -echo.
using termios
you can disable terminal echoing:
#include <termios.h>
struct termios oflags, nflags;
tcgetattr(fileno(stdin), &oflags);
nflags = oflags;
nflags.c_lflag &= ~ECHO;
nflags.c_lflag |= ECHONL;
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
/* handle error */
}
then before exit (use atexit
) you must restore the terminal:
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
/* handle error */
}
Turning off echo or using non-blocking I/O isn't the answer, if I understand your question correctly. Rather, you want to prevent a background thread from interrupting a user input thread, right?
For that, you'll need access to raw keypresses instead of line-buffered input. I don't know why you're allergic to ncurses or similar libraries; that's what they're for! I guess you could do it with termios or ioctl calls, if that's how you roll....
But to solve your multi-threaded TTY output problem, you could do this:
1) Create a mutex to control who can access the console
In the background thread, to output a message:
Grab the mutex; write the message; release the mutex; go back to sleep!
In the user input thread:
Grab the mutex when new input is detected. Keep exclusive access until the user hits enter, then release the mutex and give the background thread a chance to talk.
Does that help?