URI:
       treadcons.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       treadcons.c (1708B)
       ---
            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
            8 
            9 static int
           10 rawx(int fd, int echoing)
           11 {
           12         int was;
           13         static struct termios ttmode;
           14 
           15         if(echoing == -1)
           16                 return -1;
           17 
           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 }
           27 
           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;
           35 
           36         if((fd = open("/dev/tty", ORDWR)) < 0)
           37                 return nil;
           38 
           39         raw = -1;
           40         if(secret){
           41                 raw = rawx(fd, 0);
           42                 if(raw == -1)
           43                         return nil;
           44         }
           45 
           46         if(def)
           47                 fprint(fd, "%s[%s]: ", prompt, def);
           48         else
           49                 fprint(fd, "%s: ", prompt);
           50 
           51         s = strdup("");
           52         if(s == nil)
           53                 return nil;
           54 
           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;
          102                 }
          103         }
          104 }