Blob


1 #include <u.h>
2 #define NOPLAN9DEFINES
3 #include <libc.h>
4 #include <termios.h>
5 #ifdef HAS_SYS_TERMIOS
6 #include <sys/termios.h>
7 #endif
9 static int
10 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 else
49 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 else
88 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;