]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libauthsrv/readcons.c
vt: handle insert/delete/home/end keys for vt220/xterm
[plan9front.git] / sys / src / libauthsrv / readcons.c
1 #include <u.h>
2 #include <libc.h>
3
4 /*
5  *  prompt for a string with a possible default response
6  */
7 char*
8 readcons(char *prompt, char *def, int raw)
9 {
10         int fdin, fdout, ctl, n;
11         char *s, *p;
12
13         s = p = nil;
14         fdout = ctl = -1;
15
16         if((fdin = open("/dev/cons", OREAD)) < 0)
17                 goto Out;
18         if((fdout = open("/dev/cons", OWRITE)) < 0)
19                 goto Out;
20
21         if(raw){
22                 if((ctl = open("/dev/consctl", OWRITE)) < 0)
23                         goto Out;
24                 write(ctl, "rawon", 5);
25         }
26
27         if(def != nil)
28                 fprint(fdout, "%s[%s]: ", prompt, def);
29         else
30                 fprint(fdout, "%s: ", prompt);
31
32         for(;;){
33                 n = p - s;
34                 if((n % 32) == 0){
35                         if((p = realloc(s, n+32)) == nil)
36                                 break;
37                         s = p, p += n;
38                 }
39
40                 if(read(fdin, p, 1) <= 0 || *p == 0x7f)
41                         break;
42
43                 if(*p == '\n' || *p == '\r'){
44                         if(p == s && def != nil){
45                                 free(s);
46                                 s = strdup(def);
47                         } else
48                                 *p = 0;
49                         if(raw)
50                                 write(fdout, "\n", 1);
51                         goto Out;
52                 } else if(*p == '\b') {
53                         while(p > s && (p[-1] & 0xc0) == 0x80)
54                                 *p-- = 0;
55                         if(p > s)
56                                 *p-- = 0;
57                 } else if(*p == 0x15) { /* ^U: line kill */
58                         if(def != nil)
59                                 fprint(fdout, "\n%s[%s]: ", prompt, def);
60                         else
61                                 fprint(fdout, "\n%s: ", prompt);
62                         while(p > s)
63                                 *p-- = 0;
64                 } else if(*p >= ' ')
65                         p++;
66         }
67         free(s);
68         s = nil;
69         if(raw)
70                 write(fdout, "\n", 1);
71 Out:
72         if(ctl >= 0){
73                 write(ctl, "rawoff", 6);
74                 close(ctl);
75         }
76         if(fdin >= 0)
77                 close(fdin);
78         if(fdout >= 0)
79                 close(fdout);
80
81         return s;
82 }