102 lines · 1.6 KB · C
RawDownload
#include <u.h>#define NOPLAN9DEFINES#include <libc.h>#include <termios.h>#include <sys/termios.h> static intrawx(int fd, int echoing){	int was;	static struct termios ttmode; 	if(echoing == -1)		return -1; 	if(tcgetattr(fd, &ttmode) < 0)		return -1;	was = (ttmode.c_lflag&(ECHO|ICANON));	ttmode.c_lflag &= ~(ECHO|ICANON);	ttmode.c_lflag |= echoing;	if(tcsetattr(fd, TCSANOW, &ttmode) < 0)		return -1;	return was;} char*readcons(char *prompt, char *def, int secret){	int fd, n, raw;	char line[10];	char *s, *t;	int l; 	if((fd = open("/dev/tty", ORDWR)) < 0)		return nil; 	raw = -1;	if(secret){		raw = rawx(fd, 0);		if(raw == -1)			return nil;	} 	if(def)		fprint(fd, "%s[%s]: ", prompt, def);	else		fprint(fd, "%s: ", prompt); 	s = strdup("");	if(s == nil)		return nil; 	for(;;){		n = read(fd, line, 1);		if(n < 0){		Error:			if(secret){				rawx(fd, raw);				write(fd, "\n", 1);			}			close(fd);			free(s);			return nil;		}		if(n > 0 && line[0] == 0x7F)			goto Error;		if(n == 0 || line[0] == 0x04 || line[0] == '\n' || line[0] == '\r'){			if(secret){				rawx(fd, raw);				write(fd, "\n", 1);			}			close(fd);			if(*s == 0 && def){				free(s);				s = strdup(def);			}			return s;		}		if(line[0] == '\b'){			if(strlen(s) > 0)				s[strlen(s)-1] = 0;		}else if(line[0] == 0x15){	/* ^U: line kill */			if(def != nil)				fprint(fd, "\n%s[%s]: ", prompt, def);			else				fprint(fd, "\n%s: ", prompt);			s[0] = 0;		}else{			l = strlen(s);			t = malloc(l+2);			if(t)				memmove(t, s, l);			memset(s, 'X', l);			free(s);			if(t == nil)				return nil;			t[l] = line[0];			t[l+1] = 0;			s = t;		}	}}