diff options
author | rsc <devnull@localhost> | 2005-02-11 16:58:23 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-02-11 16:58:23 +0000 |
commit | b589fce2fbf05ae18a6f015240f87ce2a163521f (patch) | |
tree | 872dbf6e2c6f7be43971b6097f8bb15379e1379e /src/lib9/readcons.c | |
parent | 26a5fd572556f6d875c18fff8e83ed5eed6cf8fa (diff) | |
download | plan9port-b589fce2fbf05ae18a6f015240f87ce2a163521f.tar.gz plan9port-b589fce2fbf05ae18a6f015240f87ce2a163521f.tar.bz2 plan9port-b589fce2fbf05ae18a6f015240f87ce2a163521f.zip |
hard code list of plan 9 services in case they are not in /etc/services
Diffstat (limited to 'src/lib9/readcons.c')
-rw-r--r-- | src/lib9/readcons.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/lib9/readcons.c b/src/lib9/readcons.c new file mode 100644 index 00000000..8de44b8f --- /dev/null +++ b/src/lib9/readcons.c @@ -0,0 +1,102 @@ +#include <u.h> +#define NOPLAN9DEFINES +#include <libc.h> +#include <termios.h> +#include <sys/termios.h> + +static int +rawx(int fd, int echoing) +{ + int was; + static struct termios ttmode; + + if(echoing == -1) + return -1; + + if(tcgetattr(fd, &ttmode) < 0) + return -1; + was = (ttmode.c_lflag&(ECHO|ICANON)); + ttmode.c_lflag &= ~(ECHO|ICANON); + ttmode.c_lflag |= echoing; + if(tcsetattr(fd, TCSANOW, &ttmode) < 0) + return -1; + return was; +} + +char* +readcons(char *prompt, char *def, int secret) +{ + int fd, n, raw; + char line[10]; + char *s, *t; + int l; + + if((fd = open("/dev/tty", ORDWR)) < 0) + return nil; + + raw = -1; + if(secret){ + raw = rawx(fd, 0); + if(raw == -1) + return nil; + } + + if(def) + fprint(fd, "%s[%s]: ", prompt, def); + else + fprint(fd, "%s: ", prompt); + + s = strdup(""); + if(s == nil) + return nil; + + for(;;){ + n = read(fd, line, 1); + if(n < 0){ + Error: + if(secret){ + rawx(fd, raw); + write(fd, "\n", 1); + } + close(fd); + free(s); + return nil; + } + if(n > 0 && line[0] == 0x7F) + goto Error; + if(n == 0 || line[0] == 0x04 || line[0] == '\n' || line[0] == '\r'){ + if(secret){ + rawx(fd, raw); + write(fd, "\n", 1); + } + close(fd); + if(*s == 0 && def){ + free(s); + s = strdup(def); + } + return s; + } + if(line[0] == '\b'){ + if(strlen(s) > 0) + s[strlen(s)-1] = 0; + }else if(line[0] == 0x15){ /* ^U: line kill */ + if(def != nil) + fprint(fd, "\n%s[%s]: ", prompt, def); + else + fprint(fd, "\n%s: ", prompt); + s[0] = 0; + }else{ + l = strlen(s); + t = malloc(l+2); + if(t) + memmove(t, s, l); + memset(s, 'X', l); + free(s); + if(t == nil) + return nil; + t[l] = line[0]; + t[l+1] = 0; + s = t; + } + } +} |