@@ 37,7 37,7 @@ enum
MSL2 = 10,
MSPTICK = 50, /* Milliseconds per timer tick */
DEF_MSS = 1460, /* Default mean segment */
- DEF_RTT = 1000, /* Default round trip */
+ DEF_RTT = 500, /* Default round trip */
DEF_KAT = 30000, /* Default time ms) between keep alives */
TCP_LISTEN = 0, /* Listen connection */
TCP_CONNECT = 1, /* Outgoing connection */
@@ 659,7 659,10 @@ inittcpctl(Conv *s, int mode)
memset(tcb, 0, sizeof(Tcpctl));
tcb->ssthresh = 65535;
+ tcb->srtt = tcp_irtt<<LOGAGAIN;
+ tcb->mdev = 0;
+ /* setup timers */
tcb->timer.start = tcp_irtt / MSPTICK;
tcb->timer.func = tcptimeout;
tcb->timer.arg = s;
@@ 1788,12 1791,6 @@ tcpoutput(Conv *s)
x = backoff(tcb->backoff) *
(tcb->mdev + (tcb->srtt>>LOGAGAIN) + MSPTICK) / MSPTICK;
- /* allow for slow initial response
- * (miller@hamnavoe.demon.co.uk)
- */
- if(tcb->state == Syn_sent && x < 500/MSPTICK)
- x = 500/MSPTICK;
-
/* take into account delayed ack */
if(sent <= 2*tcb->mss)
x += TCP_ACK/MSPTICK;
@@ 659,11 659,6 @@ consread(Chan *c, void *buf, long n, vlong off)
while(!qcanread(lineq)) {
qread(kbdq, &kbd.line[kbd.x], 1);
ch = kbd.line[kbd.x];
- if(kbd.raw){
- qiwrite(lineq, kbd.line, kbd.x+1);
- kbd.x = 0;
- continue;
- }
eol = 0;
switch(ch){
case '\b':
@@ 856,8 851,10 @@ conswrite(Chan *c, void *va, long n, vlong off)
kbd.raw = 1;
qunlock(&kbd);
} else if(strncmp(a, "rawoff", 6) == 0){
+ qlock(&kbd);
kbd.raw = 0;
kbd.x = 0;
+ qunlock(&kbd);
} else if(strncmp(a, "ctlpon", 6) == 0){
kbd.ctlpoff = 0;
} else if(strncmp(a, "ctlpoff", 7) == 0){
@@ 43,6 43,8 @@ static int percent(va_list*, Fconv*);
extern int numbconv(va_list*, Fconv*);
/* extern int fltconv(va_list*, Fconv*); */
+extern int quotestrconv(va_list*, Fconv*);
+extern int quoterunestrconv(va_list*, Fconv*);
static void
@@ 90,6 92,13 @@ initfmt(void)
fmtalloc.index['r'] = cc;
cc++;
*/
+ fmtalloc.conv[cc] = quotestrconv;
+ fmtalloc.index['q'] = cc;
+ cc++;
+
+ fmtalloc.conv[cc] = quoterunestrconv;
+ fmtalloc.index['Q'] = cc;
+ cc++;
fmtalloc.conv[cc] = sconv;
fmtalloc.index['s'] = cc;
@@ 624,6 633,222 @@ flags(va_list*, Fconv *fp)
return -f;
}
+static void
+qchar(Rune c, Fconv *fp, int hold, int *closed)
+{
+ int n;
+
+ if(*closed)
+ return;
+ n = fp->eout - fp->out - hold;
+ if(n > 0) {
+ if(c < Runeself) {
+ *fp->out++ = c;
+ return;
+ }
+ if(n >= UTFmax || n >= runelen(c)) {
+ n = runetochar(fp->out, &c);
+ fp->out += n;
+ return;
+ }
+ }
+ if(hold)
+ *closed = 1;
+ else
+ fp->eout = fp->out;
+}
+
+static int
+needsquotes(char *s, int *quotelenp)
+{
+ char *t;
+ int nextra, ok, w;
+ Rune r;
+
+ nextra = 0;
+ ok = 1;
+ for(t=s; *t; t+=w){
+ w = chartorune(&r, t);
+ if(r <= L' ')
+ ok = 0;
+ else if(r == L'\''){
+ ok = 0;
+ nextra++; /* ' becomes '' */
+ }
+ }
+
+ if(ok){
+ *quotelenp = t-s;
+ return 0;
+ }
+ *quotelenp = 1+ t-s + nextra +1;
+ return 1;
+}
+
+static int
+runeneedsquotes(Rune *s, int *quotelenp)
+{
+ Rune *t;
+ int nextra, ok;
+ Rune r;
+
+ nextra = 0;
+ ok = 1;
+ for(t=s; *t; t++){
+ r = *t;
+ if(r <= L' ')
+ ok = 0;
+ else if(r == L'\''){
+ ok = 0;
+ nextra++; /* ' becomes '' */
+ }
+ }
+
+ if(ok){
+ *quotelenp = t-s;
+ return 0;
+ }
+ *quotelenp = 1+ t-s + nextra +1;
+ return 1;
+}
+
+void
+qadv(Rune c, Fconv *fp, int hold, int *np, int *closedp)
+{
+ if(fp->f2 == NONE || fp->f2 > 0) {
+ qchar(c, fp, hold, closedp);
+ (*np)++;
+ if(fp->f2 != NONE)
+ fp->f2--;
+ switch(c) {
+ default:
+ printcol++;
+ break;
+ case '\n':
+ printcol = 0;
+ break;
+ case '\t':
+ printcol = (printcol+8) & ~7;
+ break;
+ }
+ }
+}
+
+static int
+qstrconv(char *s, Rune *r, int quotelen, Fconv *fp)
+{
+ int closed, i, n, c;
+ Rune rune;
+
+ closed = 0;
+ if(fp->f3 & FMINUS)
+ fp->f1 = -fp->f1;
+ n = 0;
+ if(fp->f1 != NONE && fp->f1 >= 0) {
+ n = quotelen;
+ while(n < fp->f1) {
+ qchar(' ', fp, 0, &closed);
+ printcol++;
+ n++;
+ }
+ }
+
+ if(fp->eout - fp->out < 2) /* 2 because need at least '' */
+ return 0;
+
+ qchar('\'', fp, 0, &closed);
+ n++;
+
+ for(;;) {
+ if(s){
+ c = *s & 0xff;
+ if(c >= Runeself) {
+ i = chartorune(&rune, s);
+ s += i;
+ c = rune;
+ } else
+ s++;
+ }else
+ c = *r++;
+
+ if(c == 0)
+ break;
+ if(c == '\'')
+ qadv(c, fp, 2, &n, &closed); /* '' plus closing quote */
+ qadv(c, fp, 1, &n, &closed);
+ }
+ closed = 0; /* there will always be room for closing quote */
+ qchar('\'', fp, 0, &closed);
+ n++;
+
+ if(fp->f1 != NONE && fp->f1 < 0) {
+ fp->f1 = -fp->f1;
+ while(n < fp->f1) {
+ qchar(' ', fp, 0, &closed);
+ printcol++;
+ n++;
+ }
+ }
+
+ return 0;
+
+}
+
+int
+quotestrconv(va_list *arg, Fconv *fp)
+{
+ char *s;
+ int quotelen;
+
+ s = va_arg(*arg, char*);
+ if(s == nil){
+ strconv("<null>", fp);
+ return 0;
+ }
+
+ if(needsquotes(s, "elen) == 0){
+ strconv(s, fp);
+ va_end(arg);
+ return 0;
+ }
+
+ qstrconv(s, nil, quotelen, fp);
+
+ va_end(arg);
+ return 0;
+}
+
+int
+quoterunestrconv(va_list *arg, Fconv *fp)
+{
+ Rune *r;
+ int quotelen;
+
+ r = va_arg(*arg, Rune*);
+ if(r == nil){
+ strconv("<null>", fp);
+ return 0;
+ }
+
+ if(runeneedsquotes(r, "elen) == 0){
+ Strconv(r, fp);
+ va_end(arg);
+ return 0;
+ }
+
+ qstrconv(nil, r, quotelen, fp);
+
+ va_end(arg);
+ return 0;
+}
+
+void
+quotefmtinstall(void)
+{
+ fmtinstall('q', quotestrconv);
+ fmtinstall('Q', quoterunestrconv);
+}
+
#ifdef NOTDEF
int
fltconv(va_list *arg, Fconv *fp)