mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
102 lines
1.6 KiB
C
102 lines
1.6 KiB
C
#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;
|
|
}
|
|
}
|
|
}
|