Blob
1 #include <u.h>2 #define NOPLAN9DEFINES3 #include <libc.h>4 #include <termios.h>5 #include <sys/termios.h>7 static int8 rawx(int fd, int echoing)9 {10 int was;11 static struct termios ttmode;13 if(echoing == -1)14 return -1;16 if(tcgetattr(fd, &ttmode) < 0)17 return -1;18 was = (ttmode.c_lflag&(ECHO|ICANON));19 ttmode.c_lflag &= ~(ECHO|ICANON);20 ttmode.c_lflag |= echoing;21 if(tcsetattr(fd, TCSANOW, &ttmode) < 0)22 return -1;23 return was;24 }26 char*27 readcons(char *prompt, char *def, int secret)28 {29 int fd, n, raw;30 char line[10];31 char *s, *t;32 int l;34 if((fd = open("/dev/tty", ORDWR)) < 0)35 return nil;37 raw = -1;38 if(secret){39 raw = rawx(fd, 0);40 if(raw == -1)41 return nil;42 }44 if(def)45 fprint(fd, "%s[%s]: ", prompt, def);46 else47 fprint(fd, "%s: ", prompt);49 s = strdup("");50 if(s == nil)51 return nil;53 for(;;){54 n = read(fd, line, 1);55 if(n < 0){56 Error:57 if(secret){58 rawx(fd, raw);59 write(fd, "\n", 1);60 }61 close(fd);62 free(s);63 return nil;64 }65 if(n > 0 && line[0] == 0x7F)66 goto Error;67 if(n == 0 || line[0] == 0x04 || line[0] == '\n' || line[0] == '\r'){68 if(secret){69 rawx(fd, raw);70 write(fd, "\n", 1);71 }72 close(fd);73 if(*s == 0 && def){74 free(s);75 s = strdup(def);76 }77 return s;78 }79 if(line[0] == '\b'){80 if(strlen(s) > 0)81 s[strlen(s)-1] = 0;82 }else if(line[0] == 0x15){ /* ^U: line kill */83 if(def != nil)84 fprint(fd, "\n%s[%s]: ", prompt, def);85 else86 fprint(fd, "\n%s: ", prompt);87 s[0] = 0;88 }else{89 l = strlen(s);90 t = malloc(l+2);91 if(t)92 memmove(t, s, l);93 memset(s, 'X', l);94 free(s);95 if(t == nil)96 return nil;97 t[l] = line[0];98 t[l+1] = 0;99 s = t;100 }101 }102 }