fconfigure stdin -echo false -canonicalize falseIt's slightly messy that configuring these flags might apply to several channels at once, but that's no worse than the bucket of options we already have on ttys:
-mode / -handshake / -xchar / -timeout / -ttycontrolall potentially have the same cross-channel effects.
#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <string.h> #include <sys/syslimits.h> /*For MAX_CANON -- Linux: use <limits.h> instead */ #include <tcl.h> #define CMD_ARGS (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) int TerminalEchoOff CMD_ARGS { struct termios terminal; int fid = fileno (stdout); if (objc != 1) { Tcl_WrongNumArgs (interp, 0, NULL, "terminal:echoOff"); return TCL_ERROR; } tcgetattr (fid, &terminal); terminal.c_lflag &= (~ECHO); tcsetattr (fid, TCSANOW, &terminal); return TCL_OK; } int TerminalEchoOn CMD_ARGS { struct termios terminal; int fid = fileno (stdout); if (objc != 1) { Tcl_WrongNumArgs (interp, 0, NULL, "terminal:echoOn"); return TCL_ERROR; } tcgetattr (fid, &terminal); terminal.c_lflag |= (ECHO); tcsetattr (fid, TCSANOW, &terminal); return TCL_OK; } int TerminalCanonicalOff CMD_ARGS { struct termios terminal; int fid = fileno (stdin); if (objc != 1) { Tcl_WrongNumArgs (interp, 0, NULL, "terminal:canonicalOff"); return TCL_ERROR; } tcgetattr (fid, &terminal); terminal.c_lflag &= (~ICANON); terminal.c_cc[VTIME] = 0; terminal.c_cc[VMIN] = 1; tcsetattr (fid, TCSANOW, &terminal); return TCL_OK; } int TerminalCanonicalOn CMD_ARGS { struct termios terminal; int fid = fileno (stdin); if (objc != 1) { Tcl_WrongNumArgs (interp, 0, NULL, "terminal:canonicalOn"); return TCL_ERROR; } tcgetattr (fid, &terminal); terminal.c_lflag |= (ICANON); terminal.c_cc[VTIME] = 0; terminal.c_cc[VMIN] = MAX_CANON; tcsetattr (fid, TCSANOW, &terminal); return TCL_OK; } int Terminal_Init (Tcl_Interp *interp) { #define OBJ_CMD(name,func) Tcl_CreateObjCommand(interp, name, func, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL) OBJ_CMD ("terminal:echoOff", TerminalEchoOff); OBJ_CMD ("terminal:echoOn", TerminalEchoOn); OBJ_CMD ("terminal:canonicalOff", TerminalCanonicalOff); OBJ_CMD ("terminal:canonicalOn", TerminalCanonicalOn); #undef OBJ_CMD return TCL_OK; }
GPS Oct 23, 2003 - Compile with:
cc -shared terminal.c -o terminal.soYou may also need to add a -l flag to link with the terminal library needed. Use nm in /usr/lib to findout which library has the required symbols. Then load it into your tclsh like so:
load ./terminal.soExample usage:
terminal:echoOff #now we can read characters or lines without having them echo terminal:echoOn #now we see each character entered terminal:canonicalOff #now we can read a character at a time terminal:canonicalOn #now we read only when \r is received