Search code examples
ccallsystemresetstty

Reset after using system call (stty raw)


I am using the following code to read and output each keystroke without having to press enter each time.

system("\bin\stty raw");

Right after I finish reading, the program does another system call to reset the terminal behaviour.

system("\bin\stty cooked");

The thing is, the last line is not resetting the terminal behavior as it should. Everything gets messed up once this program terminates. It continues to read input and does not do anything once an enter or CTRL C or anything else is pressed.

How can I reset the terminal behavior to the one it initially was please?


Solution

  • Use popen() and pclose() to run "/bin/stty -g". Read the output from stty -g] and save it for later.

    When you want to reset the terminal, use "/bin/stty the-string-from-stty-g".

    The mechanics are fiddly but doable.

    The whole point of the -g option to stty is to give a string that can be passed back to stty to reinstate the current settings. You can then run your stty raw, ensuring that you reset the terminal before you exit using the string from stty -g.

    Note, too, that stty sane does a good job of resetting aberrant terminals to a known state. You may need to run: Control-Jstty saneControl-J at the terminal command line to make it work.

    You can also do it without running external programs. You'll need to look at tcgetattr() and tcsetattr() and related functions. Again, you read the current settings (tcgetattr() et al), change a copy of them and set those as the new values, and ensure that you reset the original settings on exit (maybe with atexit()?).