1 #include <u.h> 2 #include <libc.h> 3 #include "drawterm.h" 4 5 void* 6 erealloc(void *v, ulong n) 7 { 8 v = realloc(v, n); 9 if(v == nil) 10 sysfatal("out of memory"); 11 return v; 12 } 13 14 char* 15 estrdup(char *s) 16 { 17 s = strdup(s); 18 if(s == nil) 19 sysfatal("out of memory"); 20 return s; 21 } 22 23 char* 24 estrappend(char *s, char *fmt, ...) 25 { 26 char *t; 27 va_list arg; 28 29 va_start(arg, fmt); 30 t = vsmprint(fmt, arg); 31 if(t == nil) 32 sysfatal("out of memory"); 33 va_end(arg); 34 s = erealloc(s, strlen(s)+strlen(t)+1); 35 strcat(s, t); 36 free(t); 37 return s; 38 } 39 40 /* 41 * prompt for a string with a possible default response 42 */ 43 char* 44 readcons(char *prompt, char *def, int raw) 45 { 46 int fdin, fdout, ctl, n; 47 char line[10]; 48 char *s; 49 50 fdin = open("/dev/cons", OREAD); 51 if(fdin < 0) 52 fdin = 0; 53 fdout = open("/dev/cons", OWRITE); 54 if(fdout < 0) 55 fdout = 1; 56 if(def != nil) 57 fprint(fdout, "%s[%s]: ", prompt, def); 58 else 59 fprint(fdout, "%s: ", prompt); 60 if(raw){ 61 ctl = open("/dev/consctl", OWRITE); 62 if(ctl >= 0) 63 write(ctl, "rawon", 5); 64 } else 65 ctl = -1; 66 s = estrdup(""); 67 for(;;){ 68 n = read(fdin, line, 1); 69 if(n == 0){ 70 Error: 71 close(fdin); 72 close(fdout); 73 if(ctl >= 0) 74 close(ctl); 75 free(s); 76 return nil; 77 } 78 if(n < 0) 79 goto Error; 80 if(line[0] == 0x7f) 81 goto Error; 82 if(n == 0 || line[0] == '\n' || line[0] == '\r'){ 83 if(raw){ 84 write(ctl, "rawoff", 6); 85 write(fdout, "\n", 1); 86 } 87 close(ctl); 88 close(fdin); 89 close(fdout); 90 if(*s == 0 && def != nil) 91 s = estrappend(s, "%s", def); 92 return s; 93 } 94 if(line[0] == '\b'){ 95 if(strlen(s) > 0) 96 s[strlen(s)-1] = 0; 97 } else if(line[0] == 0x15) { /* ^U: line kill */ 98 if(def != nil) 99 fprint(fdout, "\n%s[%s]: ", prompt, def); 100 else 101 fprint(fdout, "\n%s: ", prompt); 102 103 s[0] = 0; 104 } else { 105 s = estrappend(s, "%c", line[0]); 106 } 107 } 108 return nil; /* not reached */ 109 } 110 111