readcons.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
readcons.c (1653B) | |
--- | |
1 #include <u.h> | |
2 #define NOPLAN9DEFINES | |
3 #include <libc.h> | |
4 #include <termios.h> | |
5 | |
6 static int | |
7 rawx(int fd, int echoing) | |
8 { | |
9 int was; | |
10 static struct termios ttmode; | |
11 | |
12 if(echoing == -1) | |
13 return -1; | |
14 | |
15 if(tcgetattr(fd, &ttmode) < 0) | |
16 return -1; | |
17 was = (ttmode.c_lflag&(ECHO|ICANON)); | |
18 ttmode.c_lflag &= ~(ECHO|ICANON); | |
19 ttmode.c_lflag |= echoing; | |
20 if(tcsetattr(fd, TCSANOW, &ttmode) < 0) | |
21 return -1; | |
22 return was; | |
23 } | |
24 | |
25 char* | |
26 readcons(char *prompt, char *def, int secret) | |
27 { | |
28 int fd, n, raw; | |
29 char line[10]; | |
30 char *s, *t; | |
31 int l; | |
32 | |
33 if((fd = open("/dev/tty", ORDWR)) < 0) | |
34 return nil; | |
35 | |
36 raw = -1; | |
37 if(secret){ | |
38 raw = rawx(fd, 0); | |
39 if(raw == -1) | |
40 return nil; | |
41 } | |
42 | |
43 if(def) | |
44 fprint(fd, "%s[%s]: ", prompt, def); | |
45 else | |
46 fprint(fd, "%s: ", prompt); | |
47 | |
48 s = strdup(""); | |
49 if(s == nil) | |
50 return nil; | |
51 | |
52 for(;;){ | |
53 n = read(fd, line, 1); | |
54 if(n < 0){ | |
55 Error: | |
56 if(secret){ | |
57 rawx(fd, raw); | |
58 write(fd, "\n", 1); | |
59 } | |
60 close(fd); | |
61 free(s); | |
62 return nil; | |
63 } | |
64 if(n > 0 && line[0] == 0x7F) | |
65 goto Error; | |
66 if(n == 0 || line[0] == 0x04 || line[0] == '\n' || line[… | |
67 if(secret){ | |
68 rawx(fd, raw); | |
69 write(fd, "\n", 1); | |
70 } | |
71 close(fd); | |
72 if(*s == 0 && def){ | |
73 free(s); | |
74 s = strdup(def); | |
75 } | |
76 return s; | |
77 } | |
78 if(line[0] == '\b'){ | |
79 if(strlen(s) > 0) | |
80 s[strlen(s)-1] = 0; | |
81 }else if(line[0] == 0x15){ /* ^U: line kill */ | |
82 if(def != nil) | |
83 fprint(fd, "\n%s[%s]: ", prompt, def); | |
84 else | |
85 fprint(fd, "\n%s: ", prompt); | |
86 s[0] = 0; | |
87 }else{ | |
88 l = strlen(s); | |
89 t = malloc(l+2); | |
90 if(t) | |
91 memmove(t, s, l); | |
92 memset(s, 'X', l); | |
93 free(s); | |
94 if(t == nil) | |
95 return nil; | |
96 t[l] = line[0]; | |
97 t[l+1] = 0; | |
98 s = t; | |
99 } | |
100 } | |
101 } |