1*8ccd4a63SDavid du Colombier #include "u.h" 2*8ccd4a63SDavid du Colombier #include "lib.h" 3*8ccd4a63SDavid du Colombier #include "dat.h" 4*8ccd4a63SDavid du Colombier #include "fns.h" 5*8ccd4a63SDavid du Colombier #include "error.h" 6*8ccd4a63SDavid du Colombier 7*8ccd4a63SDavid du Colombier #include "keyboard.h" 8*8ccd4a63SDavid du Colombier 9*8ccd4a63SDavid du Colombier void (*consdebug)(void) = nil; 10*8ccd4a63SDavid du Colombier void (*screenputs)(char*, int) = nil; 11*8ccd4a63SDavid du Colombier 12*8ccd4a63SDavid du Colombier Queue* kbdq; /* unprocessed console input */ 13*8ccd4a63SDavid du Colombier Queue* lineq; /* processed console input */ 14*8ccd4a63SDavid du Colombier Queue* serialoq; /* serial console output */ 15*8ccd4a63SDavid du Colombier Queue* kprintoq; /* console output, for /dev/kprint */ 16*8ccd4a63SDavid du Colombier long kprintinuse; /* test and set whether /dev/kprint is open */ 17*8ccd4a63SDavid du Colombier int iprintscreenputs = 0; 18*8ccd4a63SDavid du Colombier 19*8ccd4a63SDavid du Colombier int panicking; 20*8ccd4a63SDavid du Colombier 21*8ccd4a63SDavid du Colombier struct 22*8ccd4a63SDavid du Colombier { 23*8ccd4a63SDavid du Colombier int exiting; 24*8ccd4a63SDavid du Colombier int machs; 25*8ccd4a63SDavid du Colombier } active; 26*8ccd4a63SDavid du Colombier 27*8ccd4a63SDavid du Colombier static struct 28*8ccd4a63SDavid du Colombier { 29*8ccd4a63SDavid du Colombier QLock lk; 30*8ccd4a63SDavid du Colombier 31*8ccd4a63SDavid du Colombier int raw; /* true if we shouldn't process input */ 32*8ccd4a63SDavid du Colombier int ctl; /* number of opens to the control file */ 33*8ccd4a63SDavid du Colombier int x; /* index into line */ 34*8ccd4a63SDavid du Colombier char line[1024]; /* current input line */ 35*8ccd4a63SDavid du Colombier 36*8ccd4a63SDavid du Colombier int count; 37*8ccd4a63SDavid du Colombier int ctlpoff; 38*8ccd4a63SDavid du Colombier 39*8ccd4a63SDavid du Colombier /* a place to save up characters at interrupt time before dumping them in the queue */ 40*8ccd4a63SDavid du Colombier Lock lockputc; 41*8ccd4a63SDavid du Colombier char istage[1024]; 42*8ccd4a63SDavid du Colombier char *iw; 43*8ccd4a63SDavid du Colombier char *ir; 44*8ccd4a63SDavid du Colombier char *ie; 45*8ccd4a63SDavid du Colombier } kbd = { 46*8ccd4a63SDavid du Colombier { 0 }, 47*8ccd4a63SDavid du Colombier 0, 48*8ccd4a63SDavid du Colombier 0, 49*8ccd4a63SDavid du Colombier 0, 50*8ccd4a63SDavid du Colombier { 0 }, 51*8ccd4a63SDavid du Colombier 0, 52*8ccd4a63SDavid du Colombier 0, 53*8ccd4a63SDavid du Colombier { 0 }, 54*8ccd4a63SDavid du Colombier { 0 }, 55*8ccd4a63SDavid du Colombier kbd.istage, 56*8ccd4a63SDavid du Colombier kbd.istage, 57*8ccd4a63SDavid du Colombier kbd.istage + sizeof(kbd.istage), 58*8ccd4a63SDavid du Colombier }; 59*8ccd4a63SDavid du Colombier 60*8ccd4a63SDavid du Colombier char *sysname; 61*8ccd4a63SDavid du Colombier vlong fasthz; 62*8ccd4a63SDavid du Colombier 63*8ccd4a63SDavid du Colombier static int readtime(ulong, char*, int); 64*8ccd4a63SDavid du Colombier static int readbintime(char*, int); 65*8ccd4a63SDavid du Colombier static int writetime(char*, int); 66*8ccd4a63SDavid du Colombier static int writebintime(char*, int); 67*8ccd4a63SDavid du Colombier 68*8ccd4a63SDavid du Colombier enum 69*8ccd4a63SDavid du Colombier { 70*8ccd4a63SDavid du Colombier CMreboot, 71*8ccd4a63SDavid du Colombier CMpanic, 72*8ccd4a63SDavid du Colombier }; 73*8ccd4a63SDavid du Colombier 74*8ccd4a63SDavid du Colombier Cmdtab rebootmsg[] = 75*8ccd4a63SDavid du Colombier { 76*8ccd4a63SDavid du Colombier CMreboot, "reboot", 0, 77*8ccd4a63SDavid du Colombier CMpanic, "panic", 0, 78*8ccd4a63SDavid du Colombier }; 79*8ccd4a63SDavid du Colombier 80*8ccd4a63SDavid du Colombier int 81*8ccd4a63SDavid du Colombier return0(void *v) 82*8ccd4a63SDavid du Colombier { 83*8ccd4a63SDavid du Colombier return 0; 84*8ccd4a63SDavid du Colombier } 85*8ccd4a63SDavid du Colombier 86*8ccd4a63SDavid du Colombier void 87*8ccd4a63SDavid du Colombier printinit(void) 88*8ccd4a63SDavid du Colombier { 89*8ccd4a63SDavid du Colombier lineq = qopen(2*1024, 0, nil, nil); 90*8ccd4a63SDavid du Colombier if(lineq == nil) 91*8ccd4a63SDavid du Colombier panic("printinit"); 92*8ccd4a63SDavid du Colombier qnoblock(lineq, 1); 93*8ccd4a63SDavid du Colombier 94*8ccd4a63SDavid du Colombier kbdq = qopen(4*1024, 0, 0, 0); 95*8ccd4a63SDavid du Colombier if(kbdq == nil) 96*8ccd4a63SDavid du Colombier panic("kbdinit"); 97*8ccd4a63SDavid du Colombier qnoblock(kbdq, 1); 98*8ccd4a63SDavid du Colombier } 99*8ccd4a63SDavid du Colombier 100*8ccd4a63SDavid du Colombier int 101*8ccd4a63SDavid du Colombier consactive(void) 102*8ccd4a63SDavid du Colombier { 103*8ccd4a63SDavid du Colombier if(serialoq) 104*8ccd4a63SDavid du Colombier return qlen(serialoq) > 0; 105*8ccd4a63SDavid du Colombier return 0; 106*8ccd4a63SDavid du Colombier } 107*8ccd4a63SDavid du Colombier 108*8ccd4a63SDavid du Colombier void 109*8ccd4a63SDavid du Colombier prflush(void) 110*8ccd4a63SDavid du Colombier { 111*8ccd4a63SDavid du Colombier /* 112*8ccd4a63SDavid du Colombier ulong now; 113*8ccd4a63SDavid du Colombier 114*8ccd4a63SDavid du Colombier now = m->ticks; 115*8ccd4a63SDavid du Colombier while(consactive()) 116*8ccd4a63SDavid du Colombier if(m->ticks - now >= HZ) 117*8ccd4a63SDavid du Colombier break; 118*8ccd4a63SDavid du Colombier */ 119*8ccd4a63SDavid du Colombier } 120*8ccd4a63SDavid du Colombier 121*8ccd4a63SDavid du Colombier /* 122*8ccd4a63SDavid du Colombier * Print a string on the console. Convert \n to \r\n for serial 123*8ccd4a63SDavid du Colombier * line consoles. Locking of the queues is left up to the screen 124*8ccd4a63SDavid du Colombier * or uart code. Multi-line messages to serial consoles may get 125*8ccd4a63SDavid du Colombier * interspersed with other messages. 126*8ccd4a63SDavid du Colombier */ 127*8ccd4a63SDavid du Colombier static void 128*8ccd4a63SDavid du Colombier putstrn0(char *str, int n, int usewrite) 129*8ccd4a63SDavid du Colombier { 130*8ccd4a63SDavid du Colombier /* 131*8ccd4a63SDavid du Colombier * if someone is reading /dev/kprint, 132*8ccd4a63SDavid du Colombier * put the message there. 133*8ccd4a63SDavid du Colombier * if not and there's an attached bit mapped display, 134*8ccd4a63SDavid du Colombier * put the message there. 135*8ccd4a63SDavid du Colombier * 136*8ccd4a63SDavid du Colombier * if there's a serial line being used as a console, 137*8ccd4a63SDavid du Colombier * put the message there. 138*8ccd4a63SDavid du Colombier */ 139*8ccd4a63SDavid du Colombier if(kprintoq != nil && !qisclosed(kprintoq)){ 140*8ccd4a63SDavid du Colombier if(usewrite) 141*8ccd4a63SDavid du Colombier qwrite(kprintoq, str, n); 142*8ccd4a63SDavid du Colombier else 143*8ccd4a63SDavid du Colombier qiwrite(kprintoq, str, n); 144*8ccd4a63SDavid du Colombier }else if(screenputs != nil) 145*8ccd4a63SDavid du Colombier screenputs(str, n); 146*8ccd4a63SDavid du Colombier } 147*8ccd4a63SDavid du Colombier 148*8ccd4a63SDavid du Colombier void 149*8ccd4a63SDavid du Colombier putstrn(char *str, int n) 150*8ccd4a63SDavid du Colombier { 151*8ccd4a63SDavid du Colombier putstrn0(str, n, 0); 152*8ccd4a63SDavid du Colombier } 153*8ccd4a63SDavid du Colombier 154*8ccd4a63SDavid du Colombier int noprint; 155*8ccd4a63SDavid du Colombier 156*8ccd4a63SDavid du Colombier int 157*8ccd4a63SDavid du Colombier print(char *fmt, ...) 158*8ccd4a63SDavid du Colombier { 159*8ccd4a63SDavid du Colombier int n; 160*8ccd4a63SDavid du Colombier va_list arg; 161*8ccd4a63SDavid du Colombier char buf[PRINTSIZE]; 162*8ccd4a63SDavid du Colombier 163*8ccd4a63SDavid du Colombier if(noprint) 164*8ccd4a63SDavid du Colombier return -1; 165*8ccd4a63SDavid du Colombier 166*8ccd4a63SDavid du Colombier va_start(arg, fmt); 167*8ccd4a63SDavid du Colombier n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 168*8ccd4a63SDavid du Colombier va_end(arg); 169*8ccd4a63SDavid du Colombier putstrn(buf, n); 170*8ccd4a63SDavid du Colombier 171*8ccd4a63SDavid du Colombier return n; 172*8ccd4a63SDavid du Colombier } 173*8ccd4a63SDavid du Colombier 174*8ccd4a63SDavid du Colombier void 175*8ccd4a63SDavid du Colombier panic(char *fmt, ...) 176*8ccd4a63SDavid du Colombier { 177*8ccd4a63SDavid du Colombier int n; 178*8ccd4a63SDavid du Colombier va_list arg; 179*8ccd4a63SDavid du Colombier char buf[PRINTSIZE]; 180*8ccd4a63SDavid du Colombier 181*8ccd4a63SDavid du Colombier kprintoq = nil; /* don't try to write to /dev/kprint */ 182*8ccd4a63SDavid du Colombier 183*8ccd4a63SDavid du Colombier if(panicking) 184*8ccd4a63SDavid du Colombier for(;;); 185*8ccd4a63SDavid du Colombier panicking = 1; 186*8ccd4a63SDavid du Colombier 187*8ccd4a63SDavid du Colombier splhi(); 188*8ccd4a63SDavid du Colombier strcpy(buf, "panic: "); 189*8ccd4a63SDavid du Colombier va_start(arg, fmt); 190*8ccd4a63SDavid du Colombier n = vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg) - buf; 191*8ccd4a63SDavid du Colombier va_end(arg); 192*8ccd4a63SDavid du Colombier buf[n] = '\n'; 193*8ccd4a63SDavid du Colombier uartputs(buf, n+1); 194*8ccd4a63SDavid du Colombier if(consdebug) 195*8ccd4a63SDavid du Colombier (*consdebug)(); 196*8ccd4a63SDavid du Colombier spllo(); 197*8ccd4a63SDavid du Colombier prflush(); 198*8ccd4a63SDavid du Colombier putstrn(buf, n+1); 199*8ccd4a63SDavid du Colombier dumpstack(); 200*8ccd4a63SDavid du Colombier 201*8ccd4a63SDavid du Colombier exit(1); 202*8ccd4a63SDavid du Colombier } 203*8ccd4a63SDavid du Colombier 204*8ccd4a63SDavid du Colombier int 205*8ccd4a63SDavid du Colombier pprint(char *fmt, ...) 206*8ccd4a63SDavid du Colombier { 207*8ccd4a63SDavid du Colombier int n; 208*8ccd4a63SDavid du Colombier Chan *c; 209*8ccd4a63SDavid du Colombier va_list arg; 210*8ccd4a63SDavid du Colombier char buf[2*PRINTSIZE]; 211*8ccd4a63SDavid du Colombier 212*8ccd4a63SDavid du Colombier if(up == nil || up->fgrp == nil) 213*8ccd4a63SDavid du Colombier return 0; 214*8ccd4a63SDavid du Colombier 215*8ccd4a63SDavid du Colombier c = up->fgrp->fd[2]; 216*8ccd4a63SDavid du Colombier if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) 217*8ccd4a63SDavid du Colombier return 0; 218*8ccd4a63SDavid du Colombier n = sprint(buf, "%s %lud: ", up->text, up->pid); 219*8ccd4a63SDavid du Colombier va_start(arg, fmt); 220*8ccd4a63SDavid du Colombier n = vseprint(buf+n, buf+sizeof(buf), fmt, arg) - buf; 221*8ccd4a63SDavid du Colombier va_end(arg); 222*8ccd4a63SDavid du Colombier 223*8ccd4a63SDavid du Colombier if(waserror()) 224*8ccd4a63SDavid du Colombier return 0; 225*8ccd4a63SDavid du Colombier devtab[c->type]->write(c, buf, n, c->offset); 226*8ccd4a63SDavid du Colombier poperror(); 227*8ccd4a63SDavid du Colombier 228*8ccd4a63SDavid du Colombier lock(&c->ref.lk); 229*8ccd4a63SDavid du Colombier c->offset += n; 230*8ccd4a63SDavid du Colombier unlock(&c->ref.lk); 231*8ccd4a63SDavid du Colombier 232*8ccd4a63SDavid du Colombier return n; 233*8ccd4a63SDavid du Colombier } 234*8ccd4a63SDavid du Colombier 235*8ccd4a63SDavid du Colombier static void 236*8ccd4a63SDavid du Colombier echoscreen(char *buf, int n) 237*8ccd4a63SDavid du Colombier { 238*8ccd4a63SDavid du Colombier char *e, *p; 239*8ccd4a63SDavid du Colombier char ebuf[128]; 240*8ccd4a63SDavid du Colombier int x; 241*8ccd4a63SDavid du Colombier 242*8ccd4a63SDavid du Colombier p = ebuf; 243*8ccd4a63SDavid du Colombier e = ebuf + sizeof(ebuf) - 4; 244*8ccd4a63SDavid du Colombier while(n-- > 0){ 245*8ccd4a63SDavid du Colombier if(p >= e){ 246*8ccd4a63SDavid du Colombier screenputs(ebuf, p - ebuf); 247*8ccd4a63SDavid du Colombier p = ebuf; 248*8ccd4a63SDavid du Colombier } 249*8ccd4a63SDavid du Colombier x = *buf++; 250*8ccd4a63SDavid du Colombier if(x == 0x15){ 251*8ccd4a63SDavid du Colombier *p++ = '^'; 252*8ccd4a63SDavid du Colombier *p++ = 'U'; 253*8ccd4a63SDavid du Colombier *p++ = '\n'; 254*8ccd4a63SDavid du Colombier } else 255*8ccd4a63SDavid du Colombier *p++ = x; 256*8ccd4a63SDavid du Colombier } 257*8ccd4a63SDavid du Colombier if(p != ebuf) 258*8ccd4a63SDavid du Colombier screenputs(ebuf, p - ebuf); 259*8ccd4a63SDavid du Colombier } 260*8ccd4a63SDavid du Colombier 261*8ccd4a63SDavid du Colombier static void 262*8ccd4a63SDavid du Colombier echoserialoq(char *buf, int n) 263*8ccd4a63SDavid du Colombier { 264*8ccd4a63SDavid du Colombier char *e, *p; 265*8ccd4a63SDavid du Colombier char ebuf[128]; 266*8ccd4a63SDavid du Colombier int x; 267*8ccd4a63SDavid du Colombier 268*8ccd4a63SDavid du Colombier p = ebuf; 269*8ccd4a63SDavid du Colombier e = ebuf + sizeof(ebuf) - 4; 270*8ccd4a63SDavid du Colombier while(n-- > 0){ 271*8ccd4a63SDavid du Colombier if(p >= e){ 272*8ccd4a63SDavid du Colombier qiwrite(serialoq, ebuf, p - ebuf); 273*8ccd4a63SDavid du Colombier p = ebuf; 274*8ccd4a63SDavid du Colombier } 275*8ccd4a63SDavid du Colombier x = *buf++; 276*8ccd4a63SDavid du Colombier if(x == '\n'){ 277*8ccd4a63SDavid du Colombier *p++ = '\r'; 278*8ccd4a63SDavid du Colombier *p++ = '\n'; 279*8ccd4a63SDavid du Colombier } else if(x == 0x15){ 280*8ccd4a63SDavid du Colombier *p++ = '^'; 281*8ccd4a63SDavid du Colombier *p++ = 'U'; 282*8ccd4a63SDavid du Colombier *p++ = '\n'; 283*8ccd4a63SDavid du Colombier } else 284*8ccd4a63SDavid du Colombier *p++ = x; 285*8ccd4a63SDavid du Colombier } 286*8ccd4a63SDavid du Colombier if(p != ebuf) 287*8ccd4a63SDavid du Colombier qiwrite(serialoq, ebuf, p - ebuf); 288*8ccd4a63SDavid du Colombier } 289*8ccd4a63SDavid du Colombier 290*8ccd4a63SDavid du Colombier static void 291*8ccd4a63SDavid du Colombier echo(char *buf, int n) 292*8ccd4a63SDavid du Colombier { 293*8ccd4a63SDavid du Colombier static int ctrlt; 294*8ccd4a63SDavid du Colombier int x; 295*8ccd4a63SDavid du Colombier char *e, *p; 296*8ccd4a63SDavid du Colombier 297*8ccd4a63SDavid du Colombier e = buf+n; 298*8ccd4a63SDavid du Colombier for(p = buf; p < e; p++){ 299*8ccd4a63SDavid du Colombier switch(*p){ 300*8ccd4a63SDavid du Colombier case 0x10: /* ^P */ 301*8ccd4a63SDavid du Colombier if(cpuserver && !kbd.ctlpoff){ 302*8ccd4a63SDavid du Colombier active.exiting = 1; 303*8ccd4a63SDavid du Colombier return; 304*8ccd4a63SDavid du Colombier } 305*8ccd4a63SDavid du Colombier break; 306*8ccd4a63SDavid du Colombier case 0x14: /* ^T */ 307*8ccd4a63SDavid du Colombier ctrlt++; 308*8ccd4a63SDavid du Colombier if(ctrlt > 2) 309*8ccd4a63SDavid du Colombier ctrlt = 2; 310*8ccd4a63SDavid du Colombier continue; 311*8ccd4a63SDavid du Colombier } 312*8ccd4a63SDavid du Colombier 313*8ccd4a63SDavid du Colombier if(ctrlt != 2) 314*8ccd4a63SDavid du Colombier continue; 315*8ccd4a63SDavid du Colombier 316*8ccd4a63SDavid du Colombier /* ^T escapes */ 317*8ccd4a63SDavid du Colombier ctrlt = 0; 318*8ccd4a63SDavid du Colombier switch(*p){ 319*8ccd4a63SDavid du Colombier case 'S': 320*8ccd4a63SDavid du Colombier x = splhi(); 321*8ccd4a63SDavid du Colombier dumpstack(); 322*8ccd4a63SDavid du Colombier procdump(); 323*8ccd4a63SDavid du Colombier splx(x); 324*8ccd4a63SDavid du Colombier return; 325*8ccd4a63SDavid du Colombier case 's': 326*8ccd4a63SDavid du Colombier dumpstack(); 327*8ccd4a63SDavid du Colombier return; 328*8ccd4a63SDavid du Colombier case 'x': 329*8ccd4a63SDavid du Colombier xsummary(); 330*8ccd4a63SDavid du Colombier ixsummary(); 331*8ccd4a63SDavid du Colombier mallocsummary(); 332*8ccd4a63SDavid du Colombier pagersummary(); 333*8ccd4a63SDavid du Colombier return; 334*8ccd4a63SDavid du Colombier case 'd': 335*8ccd4a63SDavid du Colombier if(consdebug == nil) 336*8ccd4a63SDavid du Colombier consdebug = rdb; 337*8ccd4a63SDavid du Colombier else 338*8ccd4a63SDavid du Colombier consdebug = nil; 339*8ccd4a63SDavid du Colombier print("consdebug now 0x%p\n", consdebug); 340*8ccd4a63SDavid du Colombier return; 341*8ccd4a63SDavid du Colombier case 'D': 342*8ccd4a63SDavid du Colombier if(consdebug == nil) 343*8ccd4a63SDavid du Colombier consdebug = rdb; 344*8ccd4a63SDavid du Colombier consdebug(); 345*8ccd4a63SDavid du Colombier return; 346*8ccd4a63SDavid du Colombier case 'p': 347*8ccd4a63SDavid du Colombier x = spllo(); 348*8ccd4a63SDavid du Colombier procdump(); 349*8ccd4a63SDavid du Colombier splx(x); 350*8ccd4a63SDavid du Colombier return; 351*8ccd4a63SDavid du Colombier case 'q': 352*8ccd4a63SDavid du Colombier scheddump(); 353*8ccd4a63SDavid du Colombier return; 354*8ccd4a63SDavid du Colombier case 'k': 355*8ccd4a63SDavid du Colombier killbig(); 356*8ccd4a63SDavid du Colombier return; 357*8ccd4a63SDavid du Colombier case 'r': 358*8ccd4a63SDavid du Colombier exit(0); 359*8ccd4a63SDavid du Colombier return; 360*8ccd4a63SDavid du Colombier } 361*8ccd4a63SDavid du Colombier } 362*8ccd4a63SDavid du Colombier 363*8ccd4a63SDavid du Colombier qproduce(kbdq, buf, n); 364*8ccd4a63SDavid du Colombier if(kbd.raw) 365*8ccd4a63SDavid du Colombier return; 366*8ccd4a63SDavid du Colombier if(screenputs != nil) 367*8ccd4a63SDavid du Colombier echoscreen(buf, n); 368*8ccd4a63SDavid du Colombier if(serialoq) 369*8ccd4a63SDavid du Colombier echoserialoq(buf, n); 370*8ccd4a63SDavid du Colombier } 371*8ccd4a63SDavid du Colombier 372*8ccd4a63SDavid du Colombier /* 373*8ccd4a63SDavid du Colombier * Called by a uart interrupt for console input. 374*8ccd4a63SDavid du Colombier * 375*8ccd4a63SDavid du Colombier * turn '\r' into '\n' before putting it into the queue. 376*8ccd4a63SDavid du Colombier */ 377*8ccd4a63SDavid du Colombier int 378*8ccd4a63SDavid du Colombier kbdcr2nl(Queue *q, int ch) 379*8ccd4a63SDavid du Colombier { 380*8ccd4a63SDavid du Colombier char *next; 381*8ccd4a63SDavid du Colombier 382*8ccd4a63SDavid du Colombier USED(q); 383*8ccd4a63SDavid du Colombier ilock(&kbd.lockputc); /* just a mutex */ 384*8ccd4a63SDavid du Colombier if(ch == '\r' && !kbd.raw) 385*8ccd4a63SDavid du Colombier ch = '\n'; 386*8ccd4a63SDavid du Colombier next = kbd.iw+1; 387*8ccd4a63SDavid du Colombier if(next >= kbd.ie) 388*8ccd4a63SDavid du Colombier next = kbd.istage; 389*8ccd4a63SDavid du Colombier if(next != kbd.ir){ 390*8ccd4a63SDavid du Colombier *kbd.iw = ch; 391*8ccd4a63SDavid du Colombier kbd.iw = next; 392*8ccd4a63SDavid du Colombier } 393*8ccd4a63SDavid du Colombier iunlock(&kbd.lockputc); 394*8ccd4a63SDavid du Colombier return 0; 395*8ccd4a63SDavid du Colombier } 396*8ccd4a63SDavid du Colombier static 397*8ccd4a63SDavid du Colombier void 398*8ccd4a63SDavid du Colombier _kbdputc(int c) 399*8ccd4a63SDavid du Colombier { 400*8ccd4a63SDavid du Colombier Rune r; 401*8ccd4a63SDavid du Colombier char buf[UTFmax]; 402*8ccd4a63SDavid du Colombier int n; 403*8ccd4a63SDavid du Colombier 404*8ccd4a63SDavid du Colombier r = c; 405*8ccd4a63SDavid du Colombier n = runetochar(buf, &r); 406*8ccd4a63SDavid du Colombier if(n == 0) 407*8ccd4a63SDavid du Colombier return; 408*8ccd4a63SDavid du Colombier echo(buf, n); 409*8ccd4a63SDavid du Colombier // kbd.c = r; 410*8ccd4a63SDavid du Colombier // qproduce(kbdq, buf, n); 411*8ccd4a63SDavid du Colombier } 412*8ccd4a63SDavid du Colombier 413*8ccd4a63SDavid du Colombier /* _kbdputc, but with compose translation */ 414*8ccd4a63SDavid du Colombier int 415*8ccd4a63SDavid du Colombier kbdputc(Queue *q, int c) 416*8ccd4a63SDavid du Colombier { 417*8ccd4a63SDavid du Colombier int i; 418*8ccd4a63SDavid du Colombier static int collecting, nk; 419*8ccd4a63SDavid du Colombier static Rune kc[5]; 420*8ccd4a63SDavid du Colombier 421*8ccd4a63SDavid du Colombier if(c == Kalt){ 422*8ccd4a63SDavid du Colombier collecting = 1; 423*8ccd4a63SDavid du Colombier nk = 0; 424*8ccd4a63SDavid du Colombier return 0; 425*8ccd4a63SDavid du Colombier } 426*8ccd4a63SDavid du Colombier 427*8ccd4a63SDavid du Colombier if(!collecting){ 428*8ccd4a63SDavid du Colombier _kbdputc(c); 429*8ccd4a63SDavid du Colombier return 0; 430*8ccd4a63SDavid du Colombier } 431*8ccd4a63SDavid du Colombier 432*8ccd4a63SDavid du Colombier kc[nk++] = c; 433*8ccd4a63SDavid du Colombier c = latin1(kc, nk); 434*8ccd4a63SDavid du Colombier if(c < -1) /* need more keystrokes */ 435*8ccd4a63SDavid du Colombier return 0; 436*8ccd4a63SDavid du Colombier if(c != -1) /* valid sequence */ 437*8ccd4a63SDavid du Colombier _kbdputc(c); 438*8ccd4a63SDavid du Colombier else 439*8ccd4a63SDavid du Colombier for(i=0; i<nk; i++) 440*8ccd4a63SDavid du Colombier _kbdputc(kc[i]); 441*8ccd4a63SDavid du Colombier nk = 0; 442*8ccd4a63SDavid du Colombier collecting = 0; 443*8ccd4a63SDavid du Colombier 444*8ccd4a63SDavid du Colombier return 0; 445*8ccd4a63SDavid du Colombier } 446*8ccd4a63SDavid du Colombier 447*8ccd4a63SDavid du Colombier 448*8ccd4a63SDavid du Colombier enum{ 449*8ccd4a63SDavid du Colombier Qdir, 450*8ccd4a63SDavid du Colombier Qbintime, 451*8ccd4a63SDavid du Colombier Qcons, 452*8ccd4a63SDavid du Colombier Qconsctl, 453*8ccd4a63SDavid du Colombier Qcpunote, 454*8ccd4a63SDavid du Colombier Qcputime, 455*8ccd4a63SDavid du Colombier Qdrivers, 456*8ccd4a63SDavid du Colombier Qkprint, 457*8ccd4a63SDavid du Colombier Qhostdomain, 458*8ccd4a63SDavid du Colombier Qhostowner, 459*8ccd4a63SDavid du Colombier Qnull, 460*8ccd4a63SDavid du Colombier Qosversion, 461*8ccd4a63SDavid du Colombier Qpgrpid, 462*8ccd4a63SDavid du Colombier Qpid, 463*8ccd4a63SDavid du Colombier Qppid, 464*8ccd4a63SDavid du Colombier Qrandom, 465*8ccd4a63SDavid du Colombier Qreboot, 466*8ccd4a63SDavid du Colombier Qsecstore, 467*8ccd4a63SDavid du Colombier Qsnarf, 468*8ccd4a63SDavid du Colombier Qswap, 469*8ccd4a63SDavid du Colombier Qsysname, 470*8ccd4a63SDavid du Colombier Qsysstat, 471*8ccd4a63SDavid du Colombier Qtime, 472*8ccd4a63SDavid du Colombier Quser, 473*8ccd4a63SDavid du Colombier Qzero, 474*8ccd4a63SDavid du Colombier }; 475*8ccd4a63SDavid du Colombier 476*8ccd4a63SDavid du Colombier enum 477*8ccd4a63SDavid du Colombier { 478*8ccd4a63SDavid du Colombier VLNUMSIZE= 22, 479*8ccd4a63SDavid du Colombier }; 480*8ccd4a63SDavid du Colombier 481*8ccd4a63SDavid du Colombier static Dirtab consdir[]={ 482*8ccd4a63SDavid du Colombier ".", {Qdir, 0, QTDIR}, 0, DMDIR|0555, 483*8ccd4a63SDavid du Colombier "bintime", {Qbintime}, 24, 0664, 484*8ccd4a63SDavid du Colombier "cons", {Qcons}, 0, 0660, 485*8ccd4a63SDavid du Colombier "consctl", {Qconsctl}, 0, 0220, 486*8ccd4a63SDavid du Colombier "cpunote", {Qcpunote}, 0, 0444, 487*8ccd4a63SDavid du Colombier "cputime", {Qcputime}, 6*NUMSIZE, 0444, 488*8ccd4a63SDavid du Colombier "drivers", {Qdrivers}, 0, 0444, 489*8ccd4a63SDavid du Colombier "hostdomain", {Qhostdomain}, DOMLEN, 0664, 490*8ccd4a63SDavid du Colombier "hostowner", {Qhostowner}, 0, 0664, 491*8ccd4a63SDavid du Colombier "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, 492*8ccd4a63SDavid du Colombier "null", {Qnull}, 0, 0666, 493*8ccd4a63SDavid du Colombier "osversion", {Qosversion}, 0, 0444, 494*8ccd4a63SDavid du Colombier "pgrpid", {Qpgrpid}, NUMSIZE, 0444, 495*8ccd4a63SDavid du Colombier "pid", {Qpid}, NUMSIZE, 0444, 496*8ccd4a63SDavid du Colombier "ppid", {Qppid}, NUMSIZE, 0444, 497*8ccd4a63SDavid du Colombier "random", {Qrandom}, 0, 0444, 498*8ccd4a63SDavid du Colombier "reboot", {Qreboot}, 0, 0664, 499*8ccd4a63SDavid du Colombier "secstore", {Qsecstore}, 0, 0666, 500*8ccd4a63SDavid du Colombier "snarf", {Qsnarf}, 0, 0666, 501*8ccd4a63SDavid du Colombier "swap", {Qswap}, 0, 0664, 502*8ccd4a63SDavid du Colombier "sysname", {Qsysname}, 0, 0664, 503*8ccd4a63SDavid du Colombier "sysstat", {Qsysstat}, 0, 0666, 504*8ccd4a63SDavid du Colombier "time", {Qtime}, NUMSIZE+3*VLNUMSIZE, 0664, 505*8ccd4a63SDavid du Colombier "user", {Quser}, 0, 0666, 506*8ccd4a63SDavid du Colombier "zero", {Qzero}, 0, 0444, 507*8ccd4a63SDavid du Colombier }; 508*8ccd4a63SDavid du Colombier 509*8ccd4a63SDavid du Colombier char secstorebuf[65536]; 510*8ccd4a63SDavid du Colombier Dirtab *secstoretab = &consdir[Qsecstore]; 511*8ccd4a63SDavid du Colombier Dirtab *snarftab = &consdir[Qsnarf]; 512*8ccd4a63SDavid du Colombier 513*8ccd4a63SDavid du Colombier int 514*8ccd4a63SDavid du Colombier readnum(ulong off, char *buf, ulong n, ulong val, int size) 515*8ccd4a63SDavid du Colombier { 516*8ccd4a63SDavid du Colombier char tmp[64]; 517*8ccd4a63SDavid du Colombier 518*8ccd4a63SDavid du Colombier snprint(tmp, sizeof(tmp), "%*.0lud", size-1, val); 519*8ccd4a63SDavid du Colombier tmp[size-1] = ' '; 520*8ccd4a63SDavid du Colombier if(off >= size) 521*8ccd4a63SDavid du Colombier return 0; 522*8ccd4a63SDavid du Colombier if(off+n > size) 523*8ccd4a63SDavid du Colombier n = size-off; 524*8ccd4a63SDavid du Colombier memmove(buf, tmp+off, n); 525*8ccd4a63SDavid du Colombier return n; 526*8ccd4a63SDavid du Colombier } 527*8ccd4a63SDavid du Colombier 528*8ccd4a63SDavid du Colombier int 529*8ccd4a63SDavid du Colombier readstr(ulong off, char *buf, ulong n, char *str) 530*8ccd4a63SDavid du Colombier { 531*8ccd4a63SDavid du Colombier int size; 532*8ccd4a63SDavid du Colombier 533*8ccd4a63SDavid du Colombier size = strlen(str); 534*8ccd4a63SDavid du Colombier if(off >= size) 535*8ccd4a63SDavid du Colombier return 0; 536*8ccd4a63SDavid du Colombier if(off+n > size) 537*8ccd4a63SDavid du Colombier n = size-off; 538*8ccd4a63SDavid du Colombier memmove(buf, str+off, n); 539*8ccd4a63SDavid du Colombier return n; 540*8ccd4a63SDavid du Colombier } 541*8ccd4a63SDavid du Colombier 542*8ccd4a63SDavid du Colombier static void 543*8ccd4a63SDavid du Colombier consinit(void) 544*8ccd4a63SDavid du Colombier { 545*8ccd4a63SDavid du Colombier todinit(); 546*8ccd4a63SDavid du Colombier randominit(); 547*8ccd4a63SDavid du Colombier /* 548*8ccd4a63SDavid du Colombier * at 115200 baud, the 1024 char buffer takes 56 ms to process, 549*8ccd4a63SDavid du Colombier * processing it every 22 ms should be fine 550*8ccd4a63SDavid du Colombier */ 551*8ccd4a63SDavid du Colombier /* addclock0link(kbdputcclock, 22); */ 552*8ccd4a63SDavid du Colombier } 553*8ccd4a63SDavid du Colombier 554*8ccd4a63SDavid du Colombier static Chan* 555*8ccd4a63SDavid du Colombier consattach(char *spec) 556*8ccd4a63SDavid du Colombier { 557*8ccd4a63SDavid du Colombier return devattach('c', spec); 558*8ccd4a63SDavid du Colombier } 559*8ccd4a63SDavid du Colombier 560*8ccd4a63SDavid du Colombier static Walkqid* 561*8ccd4a63SDavid du Colombier conswalk(Chan *c, Chan *nc, char **name, int nname) 562*8ccd4a63SDavid du Colombier { 563*8ccd4a63SDavid du Colombier return devwalk(c, nc, name,nname, consdir, nelem(consdir), devgen); 564*8ccd4a63SDavid du Colombier } 565*8ccd4a63SDavid du Colombier 566*8ccd4a63SDavid du Colombier static int 567*8ccd4a63SDavid du Colombier consstat(Chan *c, uchar *dp, int n) 568*8ccd4a63SDavid du Colombier { 569*8ccd4a63SDavid du Colombier return devstat(c, dp, n, consdir, nelem(consdir), devgen); 570*8ccd4a63SDavid du Colombier } 571*8ccd4a63SDavid du Colombier 572*8ccd4a63SDavid du Colombier static Chan* 573*8ccd4a63SDavid du Colombier consopen(Chan *c, int omode) 574*8ccd4a63SDavid du Colombier { 575*8ccd4a63SDavid du Colombier c->aux = nil; 576*8ccd4a63SDavid du Colombier c = devopen(c, omode, consdir, nelem(consdir), devgen); 577*8ccd4a63SDavid du Colombier switch((ulong)c->qid.path){ 578*8ccd4a63SDavid du Colombier case Qconsctl: 579*8ccd4a63SDavid du Colombier qlock(&kbd.lk); 580*8ccd4a63SDavid du Colombier kbd.ctl++; 581*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 582*8ccd4a63SDavid du Colombier break; 583*8ccd4a63SDavid du Colombier 584*8ccd4a63SDavid du Colombier case Qkprint: 585*8ccd4a63SDavid du Colombier if(tas(&kprintinuse) != 0){ 586*8ccd4a63SDavid du Colombier c->flag &= ~COPEN; 587*8ccd4a63SDavid du Colombier error(Einuse); 588*8ccd4a63SDavid du Colombier } 589*8ccd4a63SDavid du Colombier if(kprintoq == nil){ 590*8ccd4a63SDavid du Colombier kprintoq = qopen(8*1024, Qcoalesce, 0, 0); 591*8ccd4a63SDavid du Colombier if(kprintoq == nil){ 592*8ccd4a63SDavid du Colombier c->flag &= ~COPEN; 593*8ccd4a63SDavid du Colombier error(Enomem); 594*8ccd4a63SDavid du Colombier } 595*8ccd4a63SDavid du Colombier qnoblock(kprintoq, 1); 596*8ccd4a63SDavid du Colombier }else 597*8ccd4a63SDavid du Colombier qreopen(kprintoq); 598*8ccd4a63SDavid du Colombier c->iounit = qiomaxatomic; 599*8ccd4a63SDavid du Colombier break; 600*8ccd4a63SDavid du Colombier 601*8ccd4a63SDavid du Colombier case Qsecstore: 602*8ccd4a63SDavid du Colombier if(omode == ORDWR) 603*8ccd4a63SDavid du Colombier error(Eperm); 604*8ccd4a63SDavid du Colombier if(omode != OREAD) 605*8ccd4a63SDavid du Colombier memset(secstorebuf, 0, sizeof secstorebuf); 606*8ccd4a63SDavid du Colombier break; 607*8ccd4a63SDavid du Colombier 608*8ccd4a63SDavid du Colombier case Qsnarf: 609*8ccd4a63SDavid du Colombier if(omode == ORDWR) 610*8ccd4a63SDavid du Colombier error(Eperm); 611*8ccd4a63SDavid du Colombier if(omode == OREAD) 612*8ccd4a63SDavid du Colombier c->aux = strdup(""); 613*8ccd4a63SDavid du Colombier else 614*8ccd4a63SDavid du Colombier c->aux = mallocz(SnarfSize, 1); 615*8ccd4a63SDavid du Colombier break; 616*8ccd4a63SDavid du Colombier } 617*8ccd4a63SDavid du Colombier return c; 618*8ccd4a63SDavid du Colombier } 619*8ccd4a63SDavid du Colombier 620*8ccd4a63SDavid du Colombier static void 621*8ccd4a63SDavid du Colombier consclose(Chan *c) 622*8ccd4a63SDavid du Colombier { 623*8ccd4a63SDavid du Colombier switch((ulong)c->qid.path){ 624*8ccd4a63SDavid du Colombier /* last close of control file turns off raw */ 625*8ccd4a63SDavid du Colombier case Qconsctl: 626*8ccd4a63SDavid du Colombier if(c->flag&COPEN){ 627*8ccd4a63SDavid du Colombier qlock(&kbd.lk); 628*8ccd4a63SDavid du Colombier if(--kbd.ctl == 0) 629*8ccd4a63SDavid du Colombier kbd.raw = 0; 630*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 631*8ccd4a63SDavid du Colombier } 632*8ccd4a63SDavid du Colombier break; 633*8ccd4a63SDavid du Colombier 634*8ccd4a63SDavid du Colombier /* close of kprint allows other opens */ 635*8ccd4a63SDavid du Colombier case Qkprint: 636*8ccd4a63SDavid du Colombier if(c->flag & COPEN){ 637*8ccd4a63SDavid du Colombier kprintinuse = 0; 638*8ccd4a63SDavid du Colombier qhangup(kprintoq, nil); 639*8ccd4a63SDavid du Colombier } 640*8ccd4a63SDavid du Colombier break; 641*8ccd4a63SDavid du Colombier 642*8ccd4a63SDavid du Colombier case Qsnarf: 643*8ccd4a63SDavid du Colombier if(c->mode == OWRITE) 644*8ccd4a63SDavid du Colombier clipwrite(c->aux); 645*8ccd4a63SDavid du Colombier free(c->aux); 646*8ccd4a63SDavid du Colombier break; 647*8ccd4a63SDavid du Colombier } 648*8ccd4a63SDavid du Colombier } 649*8ccd4a63SDavid du Colombier 650*8ccd4a63SDavid du Colombier static long 651*8ccd4a63SDavid du Colombier consread(Chan *c, void *buf, long n, vlong off) 652*8ccd4a63SDavid du Colombier { 653*8ccd4a63SDavid du Colombier char *b; 654*8ccd4a63SDavid du Colombier char tmp[128]; /* must be >= 6*NUMSIZE */ 655*8ccd4a63SDavid du Colombier char *cbuf = buf; 656*8ccd4a63SDavid du Colombier int ch, i, eol; 657*8ccd4a63SDavid du Colombier vlong offset = off; 658*8ccd4a63SDavid du Colombier 659*8ccd4a63SDavid du Colombier if(n <= 0) 660*8ccd4a63SDavid du Colombier return n; 661*8ccd4a63SDavid du Colombier switch((ulong)c->qid.path){ 662*8ccd4a63SDavid du Colombier case Qdir: 663*8ccd4a63SDavid du Colombier return devdirread(c, buf, n, consdir, nelem(consdir), devgen); 664*8ccd4a63SDavid du Colombier 665*8ccd4a63SDavid du Colombier case Qcons: 666*8ccd4a63SDavid du Colombier qlock(&kbd.lk); 667*8ccd4a63SDavid du Colombier if(waserror()) { 668*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 669*8ccd4a63SDavid du Colombier nexterror(); 670*8ccd4a63SDavid du Colombier } 671*8ccd4a63SDavid du Colombier if(kbd.raw) { 672*8ccd4a63SDavid du Colombier if(qcanread(lineq)) 673*8ccd4a63SDavid du Colombier n = qread(lineq, buf, n); 674*8ccd4a63SDavid du Colombier else { 675*8ccd4a63SDavid du Colombier /* read as much as possible */ 676*8ccd4a63SDavid du Colombier do { 677*8ccd4a63SDavid du Colombier i = qread(kbdq, cbuf, n); 678*8ccd4a63SDavid du Colombier cbuf += i; 679*8ccd4a63SDavid du Colombier n -= i; 680*8ccd4a63SDavid du Colombier } while (n>0 && qcanread(kbdq)); 681*8ccd4a63SDavid du Colombier n = cbuf - (char*)buf; 682*8ccd4a63SDavid du Colombier } 683*8ccd4a63SDavid du Colombier } else { 684*8ccd4a63SDavid du Colombier while(!qcanread(lineq)) { 685*8ccd4a63SDavid du Colombier qread(kbdq, &kbd.line[kbd.x], 1); 686*8ccd4a63SDavid du Colombier ch = kbd.line[kbd.x]; 687*8ccd4a63SDavid du Colombier eol = 0; 688*8ccd4a63SDavid du Colombier switch(ch){ 689*8ccd4a63SDavid du Colombier case '\b': 690*8ccd4a63SDavid du Colombier if(kbd.x) 691*8ccd4a63SDavid du Colombier kbd.x--; 692*8ccd4a63SDavid du Colombier break; 693*8ccd4a63SDavid du Colombier case 0x15: 694*8ccd4a63SDavid du Colombier kbd.x = 0; 695*8ccd4a63SDavid du Colombier break; 696*8ccd4a63SDavid du Colombier case '\n': 697*8ccd4a63SDavid du Colombier case 0x04: 698*8ccd4a63SDavid du Colombier eol = 1; 699*8ccd4a63SDavid du Colombier default: 700*8ccd4a63SDavid du Colombier kbd.line[kbd.x++] = ch; 701*8ccd4a63SDavid du Colombier break; 702*8ccd4a63SDavid du Colombier } 703*8ccd4a63SDavid du Colombier if(kbd.x == sizeof(kbd.line) || eol){ 704*8ccd4a63SDavid du Colombier if(ch == 0x04) 705*8ccd4a63SDavid du Colombier kbd.x--; 706*8ccd4a63SDavid du Colombier qwrite(lineq, kbd.line, kbd.x); 707*8ccd4a63SDavid du Colombier kbd.x = 0; 708*8ccd4a63SDavid du Colombier } 709*8ccd4a63SDavid du Colombier } 710*8ccd4a63SDavid du Colombier n = qread(lineq, buf, n); 711*8ccd4a63SDavid du Colombier } 712*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 713*8ccd4a63SDavid du Colombier poperror(); 714*8ccd4a63SDavid du Colombier return n; 715*8ccd4a63SDavid du Colombier 716*8ccd4a63SDavid du Colombier case Qcpunote: 717*8ccd4a63SDavid du Colombier sleep(&up->sleep, return0, nil); 718*8ccd4a63SDavid du Colombier 719*8ccd4a63SDavid du Colombier case Qcputime: 720*8ccd4a63SDavid du Colombier return 0; 721*8ccd4a63SDavid du Colombier 722*8ccd4a63SDavid du Colombier case Qkprint: 723*8ccd4a63SDavid du Colombier return qread(kprintoq, buf, n); 724*8ccd4a63SDavid du Colombier 725*8ccd4a63SDavid du Colombier case Qpgrpid: 726*8ccd4a63SDavid du Colombier return readnum((ulong)offset, buf, n, up->pgrp->pgrpid, NUMSIZE); 727*8ccd4a63SDavid du Colombier 728*8ccd4a63SDavid du Colombier case Qpid: 729*8ccd4a63SDavid du Colombier return readnum((ulong)offset, buf, n, up->pid, NUMSIZE); 730*8ccd4a63SDavid du Colombier 731*8ccd4a63SDavid du Colombier case Qppid: 732*8ccd4a63SDavid du Colombier return readnum((ulong)offset, buf, n, up->parentpid, NUMSIZE); 733*8ccd4a63SDavid du Colombier 734*8ccd4a63SDavid du Colombier case Qtime: 735*8ccd4a63SDavid du Colombier return readtime((ulong)offset, buf, n); 736*8ccd4a63SDavid du Colombier 737*8ccd4a63SDavid du Colombier case Qbintime: 738*8ccd4a63SDavid du Colombier return readbintime(buf, n); 739*8ccd4a63SDavid du Colombier 740*8ccd4a63SDavid du Colombier case Qhostowner: 741*8ccd4a63SDavid du Colombier return readstr((ulong)offset, buf, n, eve); 742*8ccd4a63SDavid du Colombier 743*8ccd4a63SDavid du Colombier case Qhostdomain: 744*8ccd4a63SDavid du Colombier return readstr((ulong)offset, buf, n, hostdomain); 745*8ccd4a63SDavid du Colombier 746*8ccd4a63SDavid du Colombier case Quser: 747*8ccd4a63SDavid du Colombier return readstr((ulong)offset, buf, n, up->user); 748*8ccd4a63SDavid du Colombier 749*8ccd4a63SDavid du Colombier case Qnull: 750*8ccd4a63SDavid du Colombier return 0; 751*8ccd4a63SDavid du Colombier 752*8ccd4a63SDavid du Colombier case Qsnarf: 753*8ccd4a63SDavid du Colombier if(offset == 0){ 754*8ccd4a63SDavid du Colombier free(c->aux); 755*8ccd4a63SDavid du Colombier c->aux = clipread(); 756*8ccd4a63SDavid du Colombier } 757*8ccd4a63SDavid du Colombier if(c->aux == nil) 758*8ccd4a63SDavid du Colombier return 0; 759*8ccd4a63SDavid du Colombier return readstr(offset, buf, n, c->aux); 760*8ccd4a63SDavid du Colombier 761*8ccd4a63SDavid du Colombier case Qsecstore: 762*8ccd4a63SDavid du Colombier return readstr(offset, buf, n, secstorebuf); 763*8ccd4a63SDavid du Colombier 764*8ccd4a63SDavid du Colombier case Qsysstat: 765*8ccd4a63SDavid du Colombier return 0; 766*8ccd4a63SDavid du Colombier 767*8ccd4a63SDavid du Colombier case Qswap: 768*8ccd4a63SDavid du Colombier return 0; 769*8ccd4a63SDavid du Colombier 770*8ccd4a63SDavid du Colombier case Qsysname: 771*8ccd4a63SDavid du Colombier if(sysname == nil) 772*8ccd4a63SDavid du Colombier return 0; 773*8ccd4a63SDavid du Colombier return readstr((ulong)offset, buf, n, sysname); 774*8ccd4a63SDavid du Colombier 775*8ccd4a63SDavid du Colombier case Qrandom: 776*8ccd4a63SDavid du Colombier return randomread(buf, n); 777*8ccd4a63SDavid du Colombier 778*8ccd4a63SDavid du Colombier case Qdrivers: 779*8ccd4a63SDavid du Colombier b = malloc(READSTR); 780*8ccd4a63SDavid du Colombier if(b == nil) 781*8ccd4a63SDavid du Colombier error(Enomem); 782*8ccd4a63SDavid du Colombier n = 0; 783*8ccd4a63SDavid du Colombier for(i = 0; devtab[i] != nil; i++) 784*8ccd4a63SDavid du Colombier n += snprint(b+n, READSTR-n, "#%C %s\n", devtab[i]->dc, devtab[i]->name); 785*8ccd4a63SDavid du Colombier if(waserror()){ 786*8ccd4a63SDavid du Colombier free(b); 787*8ccd4a63SDavid du Colombier nexterror(); 788*8ccd4a63SDavid du Colombier } 789*8ccd4a63SDavid du Colombier n = readstr((ulong)offset, buf, n, b); 790*8ccd4a63SDavid du Colombier free(b); 791*8ccd4a63SDavid du Colombier poperror(); 792*8ccd4a63SDavid du Colombier return n; 793*8ccd4a63SDavid du Colombier 794*8ccd4a63SDavid du Colombier case Qzero: 795*8ccd4a63SDavid du Colombier memset(buf, 0, n); 796*8ccd4a63SDavid du Colombier return n; 797*8ccd4a63SDavid du Colombier 798*8ccd4a63SDavid du Colombier case Qosversion: 799*8ccd4a63SDavid du Colombier snprint(tmp, sizeof tmp, "2000"); 800*8ccd4a63SDavid du Colombier n = readstr((ulong)offset, buf, n, tmp); 801*8ccd4a63SDavid du Colombier return n; 802*8ccd4a63SDavid du Colombier 803*8ccd4a63SDavid du Colombier default: 804*8ccd4a63SDavid du Colombier print("consread 0x%llux\n", c->qid.path); 805*8ccd4a63SDavid du Colombier error(Egreg); 806*8ccd4a63SDavid du Colombier } 807*8ccd4a63SDavid du Colombier return -1; /* never reached */ 808*8ccd4a63SDavid du Colombier } 809*8ccd4a63SDavid du Colombier 810*8ccd4a63SDavid du Colombier static long 811*8ccd4a63SDavid du Colombier conswrite(Chan *c, void *va, long n, vlong off) 812*8ccd4a63SDavid du Colombier { 813*8ccd4a63SDavid du Colombier char buf[256]; 814*8ccd4a63SDavid du Colombier long l, bp; 815*8ccd4a63SDavid du Colombier char *a = va; 816*8ccd4a63SDavid du Colombier int fd; 817*8ccd4a63SDavid du Colombier Chan *swc; 818*8ccd4a63SDavid du Colombier ulong offset = off; 819*8ccd4a63SDavid du Colombier Cmdbuf *cb; 820*8ccd4a63SDavid du Colombier Cmdtab *ct; 821*8ccd4a63SDavid du Colombier 822*8ccd4a63SDavid du Colombier switch((ulong)c->qid.path){ 823*8ccd4a63SDavid du Colombier case Qcons: 824*8ccd4a63SDavid du Colombier /* 825*8ccd4a63SDavid du Colombier * Can't page fault in putstrn, so copy the data locally. 826*8ccd4a63SDavid du Colombier */ 827*8ccd4a63SDavid du Colombier l = n; 828*8ccd4a63SDavid du Colombier while(l > 0){ 829*8ccd4a63SDavid du Colombier bp = l; 830*8ccd4a63SDavid du Colombier if(bp > sizeof buf) 831*8ccd4a63SDavid du Colombier bp = sizeof buf; 832*8ccd4a63SDavid du Colombier memmove(buf, a, bp); 833*8ccd4a63SDavid du Colombier putstrn0(buf, bp, 1); 834*8ccd4a63SDavid du Colombier a += bp; 835*8ccd4a63SDavid du Colombier l -= bp; 836*8ccd4a63SDavid du Colombier } 837*8ccd4a63SDavid du Colombier break; 838*8ccd4a63SDavid du Colombier 839*8ccd4a63SDavid du Colombier case Qconsctl: 840*8ccd4a63SDavid du Colombier if(n >= sizeof(buf)) 841*8ccd4a63SDavid du Colombier n = sizeof(buf)-1; 842*8ccd4a63SDavid du Colombier strncpy(buf, a, n); 843*8ccd4a63SDavid du Colombier buf[n] = 0; 844*8ccd4a63SDavid du Colombier for(a = buf; a;){ 845*8ccd4a63SDavid du Colombier if(strncmp(a, "rawon", 5) == 0){ 846*8ccd4a63SDavid du Colombier qlock(&kbd.lk); 847*8ccd4a63SDavid du Colombier if(kbd.x){ 848*8ccd4a63SDavid du Colombier qwrite(kbdq, kbd.line, kbd.x); 849*8ccd4a63SDavid du Colombier kbd.x = 0; 850*8ccd4a63SDavid du Colombier } 851*8ccd4a63SDavid du Colombier kbd.raw = 1; 852*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 853*8ccd4a63SDavid du Colombier } else if(strncmp(a, "rawoff", 6) == 0){ 854*8ccd4a63SDavid du Colombier qlock(&kbd.lk); 855*8ccd4a63SDavid du Colombier kbd.raw = 0; 856*8ccd4a63SDavid du Colombier kbd.x = 0; 857*8ccd4a63SDavid du Colombier qunlock(&kbd.lk); 858*8ccd4a63SDavid du Colombier } else if(strncmp(a, "ctlpon", 6) == 0){ 859*8ccd4a63SDavid du Colombier kbd.ctlpoff = 0; 860*8ccd4a63SDavid du Colombier } else if(strncmp(a, "ctlpoff", 7) == 0){ 861*8ccd4a63SDavid du Colombier kbd.ctlpoff = 1; 862*8ccd4a63SDavid du Colombier } 863*8ccd4a63SDavid du Colombier if((a = strchr(a, ' '))) 864*8ccd4a63SDavid du Colombier a++; 865*8ccd4a63SDavid du Colombier } 866*8ccd4a63SDavid du Colombier break; 867*8ccd4a63SDavid du Colombier 868*8ccd4a63SDavid du Colombier case Qtime: 869*8ccd4a63SDavid du Colombier if(!iseve()) 870*8ccd4a63SDavid du Colombier error(Eperm); 871*8ccd4a63SDavid du Colombier return writetime(a, n); 872*8ccd4a63SDavid du Colombier 873*8ccd4a63SDavid du Colombier case Qbintime: 874*8ccd4a63SDavid du Colombier if(!iseve()) 875*8ccd4a63SDavid du Colombier error(Eperm); 876*8ccd4a63SDavid du Colombier return writebintime(a, n); 877*8ccd4a63SDavid du Colombier 878*8ccd4a63SDavid du Colombier case Qhostowner: 879*8ccd4a63SDavid du Colombier return hostownerwrite(a, n); 880*8ccd4a63SDavid du Colombier 881*8ccd4a63SDavid du Colombier case Qhostdomain: 882*8ccd4a63SDavid du Colombier return hostdomainwrite(a, n); 883*8ccd4a63SDavid du Colombier 884*8ccd4a63SDavid du Colombier case Quser: 885*8ccd4a63SDavid du Colombier return userwrite(a, n); 886*8ccd4a63SDavid du Colombier 887*8ccd4a63SDavid du Colombier case Qnull: 888*8ccd4a63SDavid du Colombier break; 889*8ccd4a63SDavid du Colombier 890*8ccd4a63SDavid du Colombier case Qreboot: 891*8ccd4a63SDavid du Colombier if(!iseve()) 892*8ccd4a63SDavid du Colombier error(Eperm); 893*8ccd4a63SDavid du Colombier cb = parsecmd(a, n); 894*8ccd4a63SDavid du Colombier 895*8ccd4a63SDavid du Colombier if(waserror()) { 896*8ccd4a63SDavid du Colombier free(cb); 897*8ccd4a63SDavid du Colombier nexterror(); 898*8ccd4a63SDavid du Colombier } 899*8ccd4a63SDavid du Colombier ct = lookupcmd(cb, rebootmsg, nelem(rebootmsg)); 900*8ccd4a63SDavid du Colombier switch(ct->index) { 901*8ccd4a63SDavid du Colombier case CMreboot: 902*8ccd4a63SDavid du Colombier rebootcmd(cb->nf-1, cb->f+1); 903*8ccd4a63SDavid du Colombier break; 904*8ccd4a63SDavid du Colombier case CMpanic: 905*8ccd4a63SDavid du Colombier panic("/dev/reboot"); 906*8ccd4a63SDavid du Colombier } 907*8ccd4a63SDavid du Colombier poperror(); 908*8ccd4a63SDavid du Colombier free(cb); 909*8ccd4a63SDavid du Colombier break; 910*8ccd4a63SDavid du Colombier 911*8ccd4a63SDavid du Colombier case Qsecstore: 912*8ccd4a63SDavid du Colombier if(offset >= sizeof secstorebuf || offset+n+1 >= sizeof secstorebuf) 913*8ccd4a63SDavid du Colombier error(Etoobig); 914*8ccd4a63SDavid du Colombier secstoretab->qid.vers++; 915*8ccd4a63SDavid du Colombier memmove(secstorebuf+offset, va, n); 916*8ccd4a63SDavid du Colombier return n; 917*8ccd4a63SDavid du Colombier 918*8ccd4a63SDavid du Colombier case Qsnarf: 919*8ccd4a63SDavid du Colombier if(offset >= SnarfSize || offset+n >= SnarfSize) 920*8ccd4a63SDavid du Colombier error(Etoobig); 921*8ccd4a63SDavid du Colombier snarftab->qid.vers++; 922*8ccd4a63SDavid du Colombier memmove((uchar*)c->aux+offset, va, n); 923*8ccd4a63SDavid du Colombier return n; 924*8ccd4a63SDavid du Colombier 925*8ccd4a63SDavid du Colombier case Qsysstat: 926*8ccd4a63SDavid du Colombier n = 0; 927*8ccd4a63SDavid du Colombier break; 928*8ccd4a63SDavid du Colombier 929*8ccd4a63SDavid du Colombier case Qswap: 930*8ccd4a63SDavid du Colombier if(n >= sizeof buf) 931*8ccd4a63SDavid du Colombier error(Egreg); 932*8ccd4a63SDavid du Colombier memmove(buf, va, n); /* so we can NUL-terminate */ 933*8ccd4a63SDavid du Colombier buf[n] = 0; 934*8ccd4a63SDavid du Colombier /* start a pager if not already started */ 935*8ccd4a63SDavid du Colombier if(strncmp(buf, "start", 5) == 0){ 936*8ccd4a63SDavid du Colombier kickpager(); 937*8ccd4a63SDavid du Colombier break; 938*8ccd4a63SDavid du Colombier } 939*8ccd4a63SDavid du Colombier if(cpuserver && !iseve()) 940*8ccd4a63SDavid du Colombier error(Eperm); 941*8ccd4a63SDavid du Colombier if(buf[0]<'0' || '9'<buf[0]) 942*8ccd4a63SDavid du Colombier error(Ebadarg); 943*8ccd4a63SDavid du Colombier fd = strtoul(buf, 0, 0); 944*8ccd4a63SDavid du Colombier swc = fdtochan(fd, -1, 1, 1); 945*8ccd4a63SDavid du Colombier setswapchan(swc); 946*8ccd4a63SDavid du Colombier break; 947*8ccd4a63SDavid du Colombier 948*8ccd4a63SDavid du Colombier case Qsysname: 949*8ccd4a63SDavid du Colombier if(offset != 0) 950*8ccd4a63SDavid du Colombier error(Ebadarg); 951*8ccd4a63SDavid du Colombier if(n <= 0 || n >= sizeof buf) 952*8ccd4a63SDavid du Colombier error(Ebadarg); 953*8ccd4a63SDavid du Colombier strncpy(buf, a, n); 954*8ccd4a63SDavid du Colombier buf[n] = 0; 955*8ccd4a63SDavid du Colombier if(buf[n-1] == '\n') 956*8ccd4a63SDavid du Colombier buf[n-1] = 0; 957*8ccd4a63SDavid du Colombier kstrdup(&sysname, buf); 958*8ccd4a63SDavid du Colombier break; 959*8ccd4a63SDavid du Colombier 960*8ccd4a63SDavid du Colombier default: 961*8ccd4a63SDavid du Colombier print("conswrite: 0x%llux\n", c->qid.path); 962*8ccd4a63SDavid du Colombier error(Egreg); 963*8ccd4a63SDavid du Colombier } 964*8ccd4a63SDavid du Colombier return n; 965*8ccd4a63SDavid du Colombier } 966*8ccd4a63SDavid du Colombier 967*8ccd4a63SDavid du Colombier Dev consdevtab = { 968*8ccd4a63SDavid du Colombier 'c', 969*8ccd4a63SDavid du Colombier "cons", 970*8ccd4a63SDavid du Colombier 971*8ccd4a63SDavid du Colombier devreset, 972*8ccd4a63SDavid du Colombier consinit, 973*8ccd4a63SDavid du Colombier devshutdown, 974*8ccd4a63SDavid du Colombier consattach, 975*8ccd4a63SDavid du Colombier conswalk, 976*8ccd4a63SDavid du Colombier consstat, 977*8ccd4a63SDavid du Colombier consopen, 978*8ccd4a63SDavid du Colombier devcreate, 979*8ccd4a63SDavid du Colombier consclose, 980*8ccd4a63SDavid du Colombier consread, 981*8ccd4a63SDavid du Colombier devbread, 982*8ccd4a63SDavid du Colombier conswrite, 983*8ccd4a63SDavid du Colombier devbwrite, 984*8ccd4a63SDavid du Colombier devremove, 985*8ccd4a63SDavid du Colombier devwstat, 986*8ccd4a63SDavid du Colombier }; 987*8ccd4a63SDavid du Colombier 988*8ccd4a63SDavid du Colombier static uvlong uvorder = (uvlong) 0x0001020304050607ULL; 989*8ccd4a63SDavid du Colombier 990*8ccd4a63SDavid du Colombier static uchar* 991*8ccd4a63SDavid du Colombier le2vlong(vlong *to, uchar *f) 992*8ccd4a63SDavid du Colombier { 993*8ccd4a63SDavid du Colombier uchar *t, *o; 994*8ccd4a63SDavid du Colombier int i; 995*8ccd4a63SDavid du Colombier 996*8ccd4a63SDavid du Colombier t = (uchar*)to; 997*8ccd4a63SDavid du Colombier o = (uchar*)&uvorder; 998*8ccd4a63SDavid du Colombier for(i = 0; i < sizeof(vlong); i++) 999*8ccd4a63SDavid du Colombier t[o[i]] = f[i]; 1000*8ccd4a63SDavid du Colombier return f+sizeof(vlong); 1001*8ccd4a63SDavid du Colombier } 1002*8ccd4a63SDavid du Colombier 1003*8ccd4a63SDavid du Colombier static uchar* 1004*8ccd4a63SDavid du Colombier vlong2le(uchar *t, vlong from) 1005*8ccd4a63SDavid du Colombier { 1006*8ccd4a63SDavid du Colombier uchar *f, *o; 1007*8ccd4a63SDavid du Colombier int i; 1008*8ccd4a63SDavid du Colombier 1009*8ccd4a63SDavid du Colombier f = (uchar*)&from; 1010*8ccd4a63SDavid du Colombier o = (uchar*)&uvorder; 1011*8ccd4a63SDavid du Colombier for(i = 0; i < sizeof(vlong); i++) 1012*8ccd4a63SDavid du Colombier t[i] = f[o[i]]; 1013*8ccd4a63SDavid du Colombier return t+sizeof(vlong); 1014*8ccd4a63SDavid du Colombier } 1015*8ccd4a63SDavid du Colombier 1016*8ccd4a63SDavid du Colombier static long order = 0x00010203; 1017*8ccd4a63SDavid du Colombier 1018*8ccd4a63SDavid du Colombier static uchar* 1019*8ccd4a63SDavid du Colombier le2long(long *to, uchar *f) 1020*8ccd4a63SDavid du Colombier { 1021*8ccd4a63SDavid du Colombier uchar *t, *o; 1022*8ccd4a63SDavid du Colombier int i; 1023*8ccd4a63SDavid du Colombier 1024*8ccd4a63SDavid du Colombier t = (uchar*)to; 1025*8ccd4a63SDavid du Colombier o = (uchar*)ℴ 1026*8ccd4a63SDavid du Colombier for(i = 0; i < sizeof(long); i++) 1027*8ccd4a63SDavid du Colombier t[o[i]] = f[i]; 1028*8ccd4a63SDavid du Colombier return f+sizeof(long); 1029*8ccd4a63SDavid du Colombier } 1030*8ccd4a63SDavid du Colombier 1031*8ccd4a63SDavid du Colombier /* 1032*8ccd4a63SDavid du Colombier static uchar* 1033*8ccd4a63SDavid du Colombier long2le(uchar *t, long from) 1034*8ccd4a63SDavid du Colombier { 1035*8ccd4a63SDavid du Colombier uchar *f, *o; 1036*8ccd4a63SDavid du Colombier int i; 1037*8ccd4a63SDavid du Colombier 1038*8ccd4a63SDavid du Colombier f = (uchar*)&from; 1039*8ccd4a63SDavid du Colombier o = (uchar*)ℴ 1040*8ccd4a63SDavid du Colombier for(i = 0; i < sizeof(long); i++) 1041*8ccd4a63SDavid du Colombier t[i] = f[o[i]]; 1042*8ccd4a63SDavid du Colombier return t+sizeof(long); 1043*8ccd4a63SDavid du Colombier } 1044*8ccd4a63SDavid du Colombier */ 1045*8ccd4a63SDavid du Colombier 1046*8ccd4a63SDavid du Colombier char *Ebadtimectl = "bad time control"; 1047*8ccd4a63SDavid du Colombier 1048*8ccd4a63SDavid du Colombier /* 1049*8ccd4a63SDavid du Colombier * like the old #c/time but with added info. Return 1050*8ccd4a63SDavid du Colombier * 1051*8ccd4a63SDavid du Colombier * secs nanosecs fastticks fasthz 1052*8ccd4a63SDavid du Colombier */ 1053*8ccd4a63SDavid du Colombier static int 1054*8ccd4a63SDavid du Colombier readtime(ulong off, char *buf, int n) 1055*8ccd4a63SDavid du Colombier { 1056*8ccd4a63SDavid du Colombier vlong nsec, ticks; 1057*8ccd4a63SDavid du Colombier long sec; 1058*8ccd4a63SDavid du Colombier char str[7*NUMSIZE]; 1059*8ccd4a63SDavid du Colombier 1060*8ccd4a63SDavid du Colombier nsec = todget(&ticks); 1061*8ccd4a63SDavid du Colombier if(fasthz == (vlong)0) 1062*8ccd4a63SDavid du Colombier fastticks((uvlong*)&fasthz); 1063*8ccd4a63SDavid du Colombier sec = nsec/((uvlong) 1000000000); 1064*8ccd4a63SDavid du Colombier snprint(str, sizeof(str), "%*.0lud %*.0llud %*.0llud %*.0llud ", 1065*8ccd4a63SDavid du Colombier NUMSIZE-1, sec, 1066*8ccd4a63SDavid du Colombier VLNUMSIZE-1, nsec, 1067*8ccd4a63SDavid du Colombier VLNUMSIZE-1, ticks, 1068*8ccd4a63SDavid du Colombier VLNUMSIZE-1, fasthz); 1069*8ccd4a63SDavid du Colombier return readstr(off, buf, n, str); 1070*8ccd4a63SDavid du Colombier } 1071*8ccd4a63SDavid du Colombier 1072*8ccd4a63SDavid du Colombier /* 1073*8ccd4a63SDavid du Colombier * set the time in seconds 1074*8ccd4a63SDavid du Colombier */ 1075*8ccd4a63SDavid du Colombier static int 1076*8ccd4a63SDavid du Colombier writetime(char *buf, int n) 1077*8ccd4a63SDavid du Colombier { 1078*8ccd4a63SDavid du Colombier char b[13]; 1079*8ccd4a63SDavid du Colombier long i; 1080*8ccd4a63SDavid du Colombier vlong now; 1081*8ccd4a63SDavid du Colombier 1082*8ccd4a63SDavid du Colombier if(n >= sizeof(b)) 1083*8ccd4a63SDavid du Colombier error(Ebadtimectl); 1084*8ccd4a63SDavid du Colombier strncpy(b, buf, n); 1085*8ccd4a63SDavid du Colombier b[n] = 0; 1086*8ccd4a63SDavid du Colombier i = strtol(b, 0, 0); 1087*8ccd4a63SDavid du Colombier if(i <= 0) 1088*8ccd4a63SDavid du Colombier error(Ebadtimectl); 1089*8ccd4a63SDavid du Colombier now = i*((vlong) 1000000000); 1090*8ccd4a63SDavid du Colombier todset(now, 0, 0); 1091*8ccd4a63SDavid du Colombier return n; 1092*8ccd4a63SDavid du Colombier } 1093*8ccd4a63SDavid du Colombier 1094*8ccd4a63SDavid du Colombier /* 1095*8ccd4a63SDavid du Colombier * read binary time info. all numbers are little endian. 1096*8ccd4a63SDavid du Colombier * ticks and nsec are syncronized. 1097*8ccd4a63SDavid du Colombier */ 1098*8ccd4a63SDavid du Colombier static int 1099*8ccd4a63SDavid du Colombier readbintime(char *buf, int n) 1100*8ccd4a63SDavid du Colombier { 1101*8ccd4a63SDavid du Colombier int i; 1102*8ccd4a63SDavid du Colombier vlong nsec, ticks; 1103*8ccd4a63SDavid du Colombier uchar *b = (uchar*)buf; 1104*8ccd4a63SDavid du Colombier 1105*8ccd4a63SDavid du Colombier i = 0; 1106*8ccd4a63SDavid du Colombier if(fasthz == (vlong)0) 1107*8ccd4a63SDavid du Colombier fastticks((uvlong*)&fasthz); 1108*8ccd4a63SDavid du Colombier nsec = todget(&ticks); 1109*8ccd4a63SDavid du Colombier if(n >= 3*sizeof(uvlong)){ 1110*8ccd4a63SDavid du Colombier vlong2le(b+2*sizeof(uvlong), fasthz); 1111*8ccd4a63SDavid du Colombier i += sizeof(uvlong); 1112*8ccd4a63SDavid du Colombier } 1113*8ccd4a63SDavid du Colombier if(n >= 2*sizeof(uvlong)){ 1114*8ccd4a63SDavid du Colombier vlong2le(b+sizeof(uvlong), ticks); 1115*8ccd4a63SDavid du Colombier i += sizeof(uvlong); 1116*8ccd4a63SDavid du Colombier } 1117*8ccd4a63SDavid du Colombier if(n >= 8){ 1118*8ccd4a63SDavid du Colombier vlong2le(b, nsec); 1119*8ccd4a63SDavid du Colombier i += sizeof(vlong); 1120*8ccd4a63SDavid du Colombier } 1121*8ccd4a63SDavid du Colombier return i; 1122*8ccd4a63SDavid du Colombier } 1123*8ccd4a63SDavid du Colombier 1124*8ccd4a63SDavid du Colombier /* 1125*8ccd4a63SDavid du Colombier * set any of the following 1126*8ccd4a63SDavid du Colombier * - time in nsec 1127*8ccd4a63SDavid du Colombier * - nsec trim applied over some seconds 1128*8ccd4a63SDavid du Colombier * - clock frequency 1129*8ccd4a63SDavid du Colombier */ 1130*8ccd4a63SDavid du Colombier static int 1131*8ccd4a63SDavid du Colombier writebintime(char *buf, int n) 1132*8ccd4a63SDavid du Colombier { 1133*8ccd4a63SDavid du Colombier uchar *p; 1134*8ccd4a63SDavid du Colombier vlong delta; 1135*8ccd4a63SDavid du Colombier long period; 1136*8ccd4a63SDavid du Colombier 1137*8ccd4a63SDavid du Colombier n--; 1138*8ccd4a63SDavid du Colombier p = (uchar*)buf + 1; 1139*8ccd4a63SDavid du Colombier switch(*buf){ 1140*8ccd4a63SDavid du Colombier case 'n': 1141*8ccd4a63SDavid du Colombier if(n < sizeof(vlong)) 1142*8ccd4a63SDavid du Colombier error(Ebadtimectl); 1143*8ccd4a63SDavid du Colombier le2vlong(&delta, p); 1144*8ccd4a63SDavid du Colombier todset(delta, 0, 0); 1145*8ccd4a63SDavid du Colombier break; 1146*8ccd4a63SDavid du Colombier case 'd': 1147*8ccd4a63SDavid du Colombier if(n < sizeof(vlong)+sizeof(long)) 1148*8ccd4a63SDavid du Colombier error(Ebadtimectl); 1149*8ccd4a63SDavid du Colombier p = le2vlong(&delta, p); 1150*8ccd4a63SDavid du Colombier le2long(&period, p); 1151*8ccd4a63SDavid du Colombier todset(-1, delta, period); 1152*8ccd4a63SDavid du Colombier break; 1153*8ccd4a63SDavid du Colombier case 'f': 1154*8ccd4a63SDavid du Colombier if(n < sizeof(uvlong)) 1155*8ccd4a63SDavid du Colombier error(Ebadtimectl); 1156*8ccd4a63SDavid du Colombier le2vlong(&fasthz, p); 1157*8ccd4a63SDavid du Colombier todsetfreq(fasthz); 1158*8ccd4a63SDavid du Colombier break; 1159*8ccd4a63SDavid du Colombier } 1160*8ccd4a63SDavid du Colombier return n; 1161*8ccd4a63SDavid du Colombier } 1162*8ccd4a63SDavid du Colombier 1163*8ccd4a63SDavid du Colombier 1164*8ccd4a63SDavid du Colombier int 1165*8ccd4a63SDavid du Colombier iprint(char *fmt, ...) 1166*8ccd4a63SDavid du Colombier { 1167*8ccd4a63SDavid du Colombier int n, s; 1168*8ccd4a63SDavid du Colombier va_list arg; 1169*8ccd4a63SDavid du Colombier char buf[PRINTSIZE]; 1170*8ccd4a63SDavid du Colombier 1171*8ccd4a63SDavid du Colombier s = splhi(); 1172*8ccd4a63SDavid du Colombier va_start(arg, fmt); 1173*8ccd4a63SDavid du Colombier n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 1174*8ccd4a63SDavid du Colombier va_end(arg); 1175*8ccd4a63SDavid du Colombier if(screenputs != nil && iprintscreenputs) 1176*8ccd4a63SDavid du Colombier screenputs(buf, n); 1177*8ccd4a63SDavid du Colombier #undef write 1178*8ccd4a63SDavid du Colombier write(2, buf, n); 1179*8ccd4a63SDavid du Colombier splx(s); 1180*8ccd4a63SDavid du Colombier 1181*8ccd4a63SDavid du Colombier return n; 1182*8ccd4a63SDavid du Colombier } 1183*8ccd4a63SDavid du Colombier 1184