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