aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/readcons.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-02-11 16:58:23 +0000
committerrsc <devnull@localhost>2005-02-11 16:58:23 +0000
commitb589fce2fbf05ae18a6f015240f87ce2a163521f (patch)
tree872dbf6e2c6f7be43971b6097f8bb15379e1379e /src/lib9/readcons.c
parent26a5fd572556f6d875c18fff8e83ed5eed6cf8fa (diff)
downloadplan9port-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.c102
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;
+ }
+ }
+}