commit - a208917e7a935c019095acd1acd8165f08a54b7a
commit + ef5c6a6edaf3dcf2cddd46841dc0dd8fce2bf967
blob - 92b253d33af5c1f4468edcf1b97f25416e717713
blob + 806215df06f9c856bd899bea59955a9a45a3eadd
--- src/cmd/9term/9term.c
+++ src/cmd/9term/9term.c
int rcpid;
int rcfd;
int sfd;
-int noecho;
Window *w;
char *fontname;
fprint(2, "9term: rc read error: %r\n");
threadexitsall("eof on rc output");
}
+ n = echocancel(data+cnt, n);
+ if(n == 0)
+ continue;
cnt += n;
r = runemalloc(cnt);
cvttorunes(data, cnt-UTFmax, r, &nb, &nr, nil);
nr = label(r, nr);
if(nr == 0)
continue;
-
+
recv(w->conswrite, &cwm);
pair.s = r;
pair.ns = nr;
rcinputproc(void *arg)
{
static char data[9000];
- int s;
Consreadmesg crm;
Channel *c1, *c2;
Stringpair pair;
pair.ns = sizeof data;
send(c1, &pair);
recv(c2, &pair);
-
- s = setecho(sfd, 0);
+
+ if(isecho(sfd))
+ echoed(pair.s, pair.ns);
if(write(rcfd, pair.s, pair.ns) < 0)
threadexitsall(nil);
- if(s)
- setecho(sfd, s);
}
}
blob - ac1432ded5a3172b8a2d01ba23774148f1dc561c
blob + e0f866ab51f93d0754fbd725e2183a74e44e546a
--- src/cmd/9term/SunOS.c
+++ src/cmd/9term/SunOS.c
}
int
-setecho(int fd, int newe)
-{
- int old;
-
- if(tcgetattr(fd, &ttmode) < 0)
- fprint(2, "tcgetattr: %r\n");
- old = (ttmode.c_lflag&ECHO)==ECHO;
- if(old != newe){
- if(newe)
- ttmode.c_lflag |= ECHO;
- else
- ttmode.c_lflag &= ~ECHO;
- if(tcsetattr(fd, TCSANOW, &ttmode) < 0)
- fprint(2, "tcsetattr: %r\n");
- }
- return old;
-}
-
-int
getintr(int fd)
{
if(tcgetattr(fd, &ttmode) < 0)
blob - 52b9bb8a0daa6b07f74522d0ef53d4b4216ad995
blob + 4836d24d25337697fbbea51e382c84647ac7758a
--- src/cmd/9term/bsdpty.c
+++ src/cmd/9term/bsdpty.c
}
int
-setecho(int fd, int newe)
-{
- int old;
-
- if(tcgetattr(fd, &ttmode) < 0)
- fprint(2, "tcgetattr: %r\n");
- old = ttmode.c_lflag & ECHO;
- if(old != newe){
- ttmode.c_lflag &= ~ECHO;
- ttmode.c_lflag |= newe;
- /*
- * I tried using TCSADRAIN here, but that causes
- * hangs if there is any output waiting for us.
- * I guess TCSADRAIN is intended for use by our
- * clients, not by us.
- */
- if(tcsetattr(fd, 0, &ttmode) < 0)
- fprint(2, "tcsetattr: %r\n");
- }
- return old;
-}
-
-int
getintr(int fd)
{
if(tcgetattr(fd, &ttmode) < 0)
blob - 4d64349c6b48faa56fe11c7d2a8281b093e22725
blob + 6b91c8698380a0c1aacb8ec7c13bcf7115c62fc3
--- src/cmd/9term/rcstart.c
+++ src/cmd/9term/rcstart.c
dup(sfd, 2);
sys("stty tabs -onlcr icanon echo erase '^h' intr '^?'", 0);
sys("stty onocr", 1); /* not available on mac */
- if(noecho)
- sys("stty -echo", 0);
for(i=3; i<100; i++)
close(i);
signal(SIGINT, SIG_DFL);
return pid;
}
+struct {
+ Lock l;
+ char buf[1<<20];
+ int r, w;
+} echo;
+
+void
+echoed(char *p, int n)
+{
+ lock(&echo.l);
+ if(echo.r > 0) {
+ memmove(echo.buf, echo.buf+echo.r, echo.w-echo.r);
+ echo.w -= echo.r;
+ echo.r = 0;
+ }
+ if(echo.w+n > sizeof echo.buf)
+ echo.r = echo.w = 0;
+ if(echo.w+n > sizeof echo.buf)
+ n = 0;
+ memmove(echo.buf+echo.w, p, n);
+ echo.w += n;
+ unlock(&echo.l);
+}
+
+int
+echocancel(char *p, int n)
+{
+ int i;
+
+ lock(&echo.l);
+ for(i=0; i<n; i++) {
+ if(echo.r < echo.w) {
+ if(echo.buf[echo.r] == p[i]) {
+ echo.r++;
+ continue;
+ }
+ if(echo.buf[echo.r] == '\n' && p[i] == '\r')
+ continue;
+ if(p[i] == 0x08) {
+ if(i+2 <= n && p[i+1] == ' ' && p[i+2] == 0x08)
+ i += 2;
+ continue;
+ }
+ }
+ echo.r = echo.w;
+ break;
+ }
+ unlock(&echo.l);
+ if(i > 0)
+ memmove(p, p+i, n-i);
+ return n-i;
+}
+
+int
+dropcrnl(char *p, int n)
+{
+ char *r, *w;
+
+ for(r=w=p; r<p+n; r++) {
+ if(r+1<p+n && *r == '\r' && *(r+1) == '\n')
+ continue;
+ if(*r == 0x08) {
+ if(r+2<=p+n && *(r+1) == ' ' && *(r+2) == 0x08)
+ r += 2;
+ continue;
+ }
+ *w++ = *r;
+ }
+ return w-p;
+}
blob - c8d9926f705e7eb714562da1eba77a0095a4cfec
blob + e7a1f6b24de43d657aeb4aaa69e59be6b95f50e5
--- src/cmd/9term/term.h
+++ src/cmd/9term/term.h
extern int rcfd;
extern int rcstart(int, char*[], int*, int*);
extern int isecho(int);
-extern int setecho(int, int);
extern int noecho;
extern int getintr(int);
extern int loginshell;
+extern void echoed(char*, int);
+extern int echocancel(char*, int);
+extern int dropcrnl(char*, int);
blob - bed7f2aae93aaf0f1c69873148f221b1e60484f8
blob + 25dfccc96b9120098a526970df19b8c29f52ecb4
--- src/cmd/9term/win.c
+++ src/cmd/9term/win.c
#include <9pclient.h>
#include "term.h"
-int noecho = 1;
#define EVENTSIZE 256
#define STACK 32768
char *onestring(int, char**);
int delete(Event*);
void deltype(uint, uint);
+void sendbs(int, int);
void runproc(void*);
int
CFid *afd = addrfd;
int fd0 = rcfd;
Event e, e2, e3, e4;
+ int n;
USED(v);
break;
case 'D':
- q.p -= delete(&e);
+ n = delete(&e);
+ q.p -= n;
+ if(!isecho(fd0))
+ sendbs(fd0, n);
break;
case 'x':
n = read(fd1, buf+npart, 8192);
if(n <= 0)
error(nil);
+
+ n = echocancel(buf+npart, n);
+ if(n == 0)
+ continue;
+
+ n = dropcrnl(buf+npart, n);
+ if(n == 0)
+ continue;
/* squash NULs */
s = memchr(buf+npart, 0, n);
qlock(&q.lk);
m = sprint(x, "#%d", q.p);
if(fswrite(afd, x, m) != m){
- fprint(2, "stdout writing address: %r; resetting\n");
- fswrite(afd, "$", 1);
+ fprint(2, "stdout writing address %s: %r; resetting\n", x);
+ if(fswrite(afd, "$", 1) < 0)
+ fprint(2, "reset: %r\n");
+ fsseek(afd, 0, 0);
m = fsread(afd, x, sizeof x-1);
if(m >= 0){
x[m] = 0;
void
sendtype(int fd0)
{
- int i, n, nr;
-
- while(ntypebreak){
+ int i, n, nr, raw;
+
+ raw = !isecho(fd0);
+ while(ntypebreak || (raw && ntypeb > 0)){
for(i=0; i<ntypeb; i++)
- if(typing[i]=='\n' || typing[i]==0x04){
+ if(typing[i]=='\n' || typing[i]==0x04 || (i==ntypeb-1 && raw)){
+ if((typing[i] == '\n' || typing[i] == 0x04) && ntypebreak > 0)
+ ntypebreak--;
n = i+1;
i++;
+ if(isecho(fd0))
+ echoed(typing, n);
if(write(fd0, typing, n) != n)
error("sending to program");
nr = nrunes(typing, i);
ntyper -= nr;
ntypeb -= i;
memmove(typing, typing+i, ntypeb);
- ntypebreak--;
goto cont2;
}
print("no breakchar\n");
}
void
+sendbs(int fd0, int n)
+{
+ char buf[128];
+ int m;
+
+ memset(buf, 0x08, sizeof buf);
+ while(n > 0) {
+ m = sizeof buf;
+ if(m > n)
+ m = n;
+ n -= m;
+ write(fd0, buf, m);
+ }
+}
+
+void
deltype(uint p0, uint p1)
{
int w;
m += nr;
}
}
+ if(!isecho(fd0)) {
+ n = sprint(buf, "#%d,#%d", e->q0, e->q1);
+ fswrite(afd, buf, n);
+ fswrite(dfd, "", 0);
+ q.p -= e->q1 - e->q0;
+ }
sendtype(fd0);
}