remove tty(1) command as kbdfs now handles interrupts
This commit is contained in:
parent
2c4a77f21f
commit
479ea049e3
2 changed files with 0 additions and 332 deletions
|
@ -1,26 +0,0 @@
|
|||
.TH TTY 1
|
||||
.SH NAME
|
||||
tty \- cooked mode emulator
|
||||
.SH SYNOPSIS
|
||||
.B tty
|
||||
[-D]
|
||||
.I cmd
|
||||
.I arg1
|
||||
.I arg2
|
||||
.I ...
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I Tty
|
||||
binds an intermediate "cooked mode" layer between
|
||||
.I cmd
|
||||
and
|
||||
.I /dev/cons.
|
||||
.SH EXAMPLE
|
||||
.LP
|
||||
Provide <DEL> support for a command run on the text console:
|
||||
.sp 1
|
||||
.EX
|
||||
% tty import -c cirno / /n/cirno
|
||||
.EE
|
||||
.SH SOURCE
|
||||
.B /sys/src/cmd/tty.c
|
|
@ -1,306 +0,0 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <auth.h>
|
||||
#include <thread.h>
|
||||
#include <fcall.h>
|
||||
#include <9p.h>
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
enum {
|
||||
Stacksz = 8192,
|
||||
};
|
||||
|
||||
typedef struct Prog {
|
||||
Channel *pidc;
|
||||
char **argv;
|
||||
} Prog;
|
||||
|
||||
typedef struct Line {
|
||||
uchar *buf;
|
||||
int x, len;
|
||||
} Line;
|
||||
|
||||
int cons, consctl;
|
||||
Channel *rchan, *wchan, *ichan;
|
||||
File *devcons;
|
||||
|
||||
static void
|
||||
killer(void *arg)
|
||||
{
|
||||
int *pid = arg;
|
||||
ulong yes;
|
||||
for(;;){
|
||||
yes = recvul(ichan);
|
||||
if(yes)
|
||||
postnote(PNGROUP, *pid, "interrupt");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sendline(Channel *c, Line *L)
|
||||
{
|
||||
int n, k;
|
||||
Req *r;
|
||||
uchar *s;
|
||||
|
||||
s = L->buf;
|
||||
n = L->x;
|
||||
do{
|
||||
while(!(r = recvp(c)));
|
||||
k = MIN(n, r->ifcall.count);
|
||||
memcpy(r->ofcall.data, s, k);
|
||||
r->ofcall.count = k;
|
||||
respond(r, nil);
|
||||
s += k;
|
||||
n -= k;
|
||||
}while(n > 0);
|
||||
L->x = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
senderr(Channel *c, char *err)
|
||||
{
|
||||
Req *r;
|
||||
while(!(r = recvp(c)));
|
||||
respond(r, err);
|
||||
}
|
||||
|
||||
static void
|
||||
echo(uchar c)
|
||||
{
|
||||
write(cons, &c, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
addchar(Line *L, uchar c)
|
||||
{
|
||||
int send;
|
||||
|
||||
send = 0;
|
||||
switch(c){
|
||||
case '\n':
|
||||
send = 1;
|
||||
break;
|
||||
case 4:
|
||||
return 1;
|
||||
case 8:
|
||||
if(L->x > 0){
|
||||
echo(8);
|
||||
L->x--;
|
||||
}
|
||||
return 0;
|
||||
case 21:
|
||||
while(L->x > 0){
|
||||
echo(8);
|
||||
L->x--;
|
||||
}
|
||||
return 0;
|
||||
case 23:
|
||||
while(L->x > 0){
|
||||
c = L->buf[--L->x];
|
||||
echo(8);
|
||||
if(c == ' ' || c == '\t')
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case 127:
|
||||
L->x = 0;
|
||||
sendul(ichan, 1);
|
||||
return 1;
|
||||
}
|
||||
echo(c);
|
||||
L->buf[L->x++] = c;
|
||||
if(L->x == L->len)
|
||||
send = 1;
|
||||
return send;
|
||||
}
|
||||
|
||||
static Line *
|
||||
makeline(int len)
|
||||
{
|
||||
Line *L;
|
||||
L = malloc(sizeof(*L));
|
||||
L->buf = malloc(len);
|
||||
L->x = 0;
|
||||
L->len = len;
|
||||
return L;
|
||||
}
|
||||
|
||||
static void
|
||||
reader(void *)
|
||||
{
|
||||
int n;
|
||||
uchar c;
|
||||
Line *L;
|
||||
char err[ERRMAX];
|
||||
|
||||
L = makeline(128);
|
||||
for(;;){
|
||||
n = read(cons, &c, 1);
|
||||
if(n < 0){
|
||||
rerrstr(err, sizeof(err));
|
||||
if(L->x > 0)
|
||||
sendline(rchan, L);
|
||||
senderr(rchan, err);
|
||||
continue;
|
||||
}
|
||||
if(addchar(L, c))
|
||||
sendline(rchan, L);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
writer(void *)
|
||||
{
|
||||
Req *r;
|
||||
int n;
|
||||
char err[ERRMAX];
|
||||
|
||||
for(;;){
|
||||
do
|
||||
r = recvp(wchan);
|
||||
while(!r);
|
||||
|
||||
n = write(cons, r->ifcall.data, r->ifcall.count);
|
||||
if(n < 0){
|
||||
rerrstr(err, sizeof(err));
|
||||
respond(r, err);
|
||||
}else{
|
||||
r->ofcall.count = n;
|
||||
respond(r, nil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fsread(Req *r)
|
||||
{
|
||||
sendp(rchan, r);
|
||||
}
|
||||
|
||||
static void
|
||||
fswrite(Req *r)
|
||||
{
|
||||
sendp(wchan, r);
|
||||
}
|
||||
|
||||
/* adapted from acme/win */
|
||||
int
|
||||
lookinbin(char *s)
|
||||
{
|
||||
if(s[0] == '/')
|
||||
return 0;
|
||||
if(s[0]=='.' && s[1]=='/')
|
||||
return 0;
|
||||
if(s[0]=='.' && s[1]=='.' && s[2]=='/')
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
char*
|
||||
estrstrdup(char *s, char *t)
|
||||
{
|
||||
char *u;
|
||||
|
||||
u = malloc(strlen(s)+strlen(t)+1);
|
||||
sprint(u, "%s%s", s, t);
|
||||
return u;
|
||||
}
|
||||
|
||||
void
|
||||
cmdproc(void *arg)
|
||||
{
|
||||
Prog *p = arg;
|
||||
char **av = p->argv;
|
||||
char *cmd;
|
||||
|
||||
rfork(RFCFDG | RFNOTEG);
|
||||
open("/dev/cons", OREAD);
|
||||
open("/dev/cons", OWRITE);
|
||||
dup(1, 2);
|
||||
procexec(p->pidc, av[0], av);
|
||||
if(lookinbin(av[0])){
|
||||
cmd = estrstrdup("/bin/", av[0]);
|
||||
procexec(p->pidc, cmd, av);
|
||||
}
|
||||
threadexitsall("exec");
|
||||
}
|
||||
|
||||
void
|
||||
runcmd(char **argv)
|
||||
{
|
||||
Channel *waitc;
|
||||
Channel *pidc;
|
||||
Waitmsg *w;
|
||||
Prog prog;
|
||||
int pid;
|
||||
|
||||
waitc = threadwaitchan();
|
||||
pidc = chancreate(sizeof(int), 0);
|
||||
prog.argv = argv;
|
||||
prog.pidc = pidc;
|
||||
proccreate(cmdproc, &prog, Stacksz);
|
||||
while(recv(pidc, &pid) == -1 || pid == -1);
|
||||
threadcreate(killer, &pid, Stacksz);
|
||||
while(recv(waitc, &w) == -1);
|
||||
free(w);
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
print("usage: tty [-D] cmd arg1 arg2 ...\n");
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
Srv fs = {
|
||||
.read = fsread,
|
||||
.write = fswrite,
|
||||
};
|
||||
|
||||
void
|
||||
threadmain(int argc, char *argv[])
|
||||
{
|
||||
char *user;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'D':
|
||||
chatty9p++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}ARGEND;
|
||||
|
||||
if(argc == 0)
|
||||
usage();
|
||||
|
||||
rfork(RFNAMEG);
|
||||
|
||||
cons = open("/dev/cons", ORDWR);
|
||||
if(cons < 0)
|
||||
sysfatal("cons: %r");
|
||||
consctl = open("/dev/consctl", OWRITE);
|
||||
if(consctl < 0)
|
||||
sysfatal("ctl: %r");
|
||||
fprint(consctl, "rawon\n");
|
||||
|
||||
rchan = chancreate(sizeof(void *), 8);
|
||||
wchan = chancreate(sizeof(void *), 8);
|
||||
ichan = chancreate(sizeof(ulong), 8);
|
||||
|
||||
proccreate(reader, nil, Stacksz);
|
||||
proccreate(writer, nil, Stacksz);
|
||||
|
||||
user = getuser();
|
||||
fs.tree = alloctree(user, getuser(), DMDIR|0555, nil);
|
||||
devcons = createfile(fs.tree->root, "cons", user, 0666, nil);
|
||||
threadpostmountsrv(&fs, nil, "/dev", MBEFORE);
|
||||
|
||||
runcmd(argv);
|
||||
|
||||
close(consctl);
|
||||
close(cons);
|
||||
threadexitsall(nil);
|
||||
}
|
Loading…
Reference in a new issue