/* * pgrpcpy MUST preserve the mountid allocation order of the parent group */ void pgrpcpy(Pgrp *to, Pgrp *from) { int i; Mount *n, *m, **link, *order; Mhead *f, **tom, **l, *mh; wlock(&from->ns); order = 0; tom = to->mnthash; for(i = 0; i < MNTHASH; i++) { l = tom++; for(f = from->mnthash[i]; f; f = f->hash) { rlock(&f->lock); mh = newmhead(f->from); *l = mh; l = &mh->hash; link = &mh->mount; for(m = f->mount; m; m = m->next) { n = newmount(mh, m->to, m->mflag, m->spec); m->copy = n; pgrpinsert(&order, m); *link = n; link = &n->next; } runlock(&f->lock); } } /* * Allocate mount ids in the same sequence as the parent group */ lock(&mountid); for(m = order; m; m = m->order) m->copy->mountid = mountid.ref++; unlock(&mountid); wunlock(&from->ns); }
static int ipifcstate(Conv *c, char *state, int n) { Ipifc *ifc; Iplifc *lifc; int m; ifc = (Ipifc*)c->ptcl; m = snprint(state, n, sfixedformat, ifc->dev, ifc->maxtu, ifc->sendra6, ifc->recvra6, ifc->rp.mflag, ifc->rp.oflag, ifc->rp.maxraint, ifc->rp.minraint, ifc->rp.linkmtu, ifc->rp.reachtime, ifc->rp.rxmitra, ifc->rp.ttl, ifc->rp.routerlt, ifc->in, ifc->out, ifc->inerr, ifc->outerr); rlock(ifc); for(lifc = ifc->lifc; lifc && n > m; lifc = lifc->next) m += snprint(state+m, n - m, slineformat, lifc->local, lifc->mask, lifc->remote, lifc->validlt, lifc->preflt); if(ifc->lifc == nil) m += snprint(state+m, n - m, "\n"); runlock(ifc); return m; }
// --- tERROR pr_call _PropertySetStr( tPO* po, tHANDLE* handle, tDATA* result, tPROPID propid, tSTRING buffer, tDWORD size, tCODEPAGE src_cp ) { tERROR error = errOK; tDATA len = 0; const tDATA* table; tINTERFACE* iface; tDWORD init_prop_pos = 0xffffffff; PR_TRACE_A0( MakeObject(handle), "Enter _PropertySetStr method" ); /* if ( !KNOWN_CP(receive_cp) ) error = errCODEPAGE_NOT_SUPPORTED; */ if ( 0 == (iface=handle->iface) ) error = errINTERFACE_NOT_ASSIGNED_YET; else if ( (0 == (table = _PropTableSearch(iface,propid,&init_prop_pos))) && (0==(table=_PropTableSearch(iface,pgPROP_LAST_CALL,&init_prop_pos))) ) error = errPROPERTY_NOT_FOUND; /* else if ( !KNOWN_CP(src_cp) ) error = errCODEPAGE_NOT_SUPPORTED; */ else if ( PROP_MODE(table) & cPROP_BUFFER_SHARED ) // shared buffer is RO !!! error = errPROPERTY_NOT_WRITABLE; else if ( ((PROP_MODE(table) & cPROP_WRITABLE_ON_INIT) != 0) && ((handle->flags & hf_OPERATIONAL_MODE) != 0) ) // property cannot be set in this operational mode error = errPROPERTY_NOT_WRITABLE; else if ( (cPROP_BUFFER_WRITE|cPROP_BUFFER_HSTRING) == (PROP_MODE(table) & (cPROP_BUFFER_WRITE|cPROP_BUFFER_HSTRING)) ) { hSTRING* pstr = (hSTRING*)(((tBYTE*)*hdata(handle))+PROP_OFFSET(table)); if ( !*pstr ) { tHANDLE* hstr; rlock(po); if ( PR_SUCC(error=_ObjectIIDCreate(po,g_hRoot,&hstr,IID_STRING,PID_ANY,SUBTYPE_ANY)) ) { if ( PR_SUCC(error=_ObjectCreateDone(po,hstr)) ) *pstr = (hSTRING)MakeObject( hstr ); else _ObjectClose( po, hstr, 0 ); } runlock(po); } if ( PR_SUCC(error) ) { tDWORD dwLen = 0; error = CALL_String_ImportFromBuff( *pstr, &dwLen, buffer, size, src_cp, cSTRING_Z ); len = dwLen; } if ( PR_SUCC(error) && buffer && (init_prop_pos < 32) ) handle->init_props &= ~( 1 << init_prop_pos ); } else { tIntFnPropIO func; tPTR dst; tDATA dst_len = 0; tCODEPAGE dst_cp; if ( PR_FAIL(error=_PropertyGetStrCP(po,handle,&dst_cp,propid)) ) dst_cp = src_cp; // cannot get destination CP, just put string witout conversion !!! if ( 0 != (func=PROP_SETFN(table)) ) dst = 0; else if ( PROP_MODE(table) & cPROP_BUFFER_WRITE ) { dst = ((tBYTE*)*hdata(handle))+PROP_OFFSET(table); dst_len = PROP_SIZE(table); } else dst = 0; if ( !func && !dst ) error = errPROPERTY_NOT_WRITABLE; else if ( buffer ) { if ( src_cp != dst_cp ) { if ( func ) { if ( !CalcExportLen || !CopyTo ) error = errCODEPAGE_CONVERSION_UNAVAILABLE; else { tPTR tmp = 0; tDWORD tmp_len = size; call_func6( error, 0/*DPO*/, CalcExportLen, buffer, size, src_cp, dst_cp, cSTRING_Z, &tmp_len ); if ( PR_FAIL(error) ) ; else if ( PR_FAIL(error=PrAlloc(&tmp,tmp_len)) ) ; else { call_func8( error, 0/*DPO*/, CopyTo, tmp, tmp_len, dst_cp, buffer, size, src_cp, cSTRING_Z, &tmp_len ); if ( PR_SUCC(error) ) { tDWORD dwLen = 0; call_func5( error, DPO, func, MakeObject(handle), &dwLen, propid, tmp, tmp_len ); len = dwLen; } } if ( tmp ) PrFree( tmp ); } } else if ( CopyTo ) { tDWORD dwLen = 0; call_func8( error, 0/*DPO*/, CopyTo, dst, (tDWORD)dst_len, dst_cp, buffer, size, src_cp, cSTRING_Z, &dwLen ); len = dwLen; } else error = errCODEPAGE_CONVERSION_UNAVAILABLE; } else if ( !size && ((error=errSTRING_LEN_NOT_SPECIFIED,!CalcExportLen) || PR_FAIL(error=CalcExportLen(buffer,0,src_cp,src_cp,cSTRING_Z,&size))) ) ; else if ( func ) { tDWORD dwLen = 0; call_func5( error, DPO, func, MakeObject(handle), &dwLen, propid, buffer, size ); len = dwLen; } else if ( dst_len < size ) { len = 0; error = errBUFFER_TOO_SMALL; } else { memcpy( dst, buffer, (tDWORD)(len=size) ); error = errOK; } if ( PR_SUCC(error) && (init_prop_pos < 32) ) handle->init_props &= ~( 1 << init_prop_pos ); } else if ( func ) { tDWORD dwLen = (tDWORD)len; call_func5( error, DPO, func, MakeObject(handle), &dwLen, propid, 0, 0 ); if ( PR_SUCC(error) && (src_cp != dst_cp) && dwLen ) { if ( ConvertLen ) { call_func4( error, 0/*DPO*/, ConvertLen, dwLen, &dwLen, dst_cp, src_cp ); } else error = errCODEPAGE_CONVERSION_UNAVAILABLE; } len = dwLen; } else if ( src_cp == dst_cp ) len = dst_len; else if ( ConvertLen ) { tDWORD dwLen = 0; call_func4( error, 0/*DPO*/, ConvertLen, (tDWORD)dst_len, &dwLen, dst_cp, src_cp ); len = dwLen; } else error = errCODEPAGE_CONVERSION_UNAVAILABLE; } if ( result ) *result = len; PR_TRACE_A2( MakeObject(handle), "Leave _PropertySetStr method, ret tDWORD = %u, error = %terr", (tDWORD)len, error ); return error; }
static uint64_t rxmitsols(struct arp *arp) { unsigned int sflag; struct block *next, *xp; struct arpent *a, *b, **l; struct Fs *f; uint8_t ipsrc[IPaddrlen]; struct Ipifc *ifc = NULL; uint64_t nrxt; qlock(&arp->qlock); f = arp->f; a = arp->rxmt; if (a == NULL) { nrxt = 0; goto dodrops; /* return nrxt; */ } nrxt = a->rtime - NOW; if (nrxt > 3 * ReTransTimer / 4) goto dodrops; /* return nrxt; */ for (; a; a = a->nextrxt) { ifc = a->ifc; assert(ifc != NULL); if ((a->rxtsrem <= 0) || !(canrlock(&ifc->rwlock)) || (a->ifcid != ifc->ifcid)) { xp = a->hold; a->hold = NULL; if (xp) { if (arp->dropl == NULL) arp->dropf = xp; else arp->dropl->list = xp; } cleanarpent(arp, a); } else break; } if (a == NULL) goto dodrops; qunlock(&arp->qlock); /* for icmpns */ if ((sflag = ipv6anylocal(ifc, ipsrc)) != SRC_UNSPEC) icmpns(f, ipsrc, sflag, a->ip, TARG_MULTI, ifc->mac); runlock(&ifc->rwlock); qlock(&arp->qlock); /* put to the end of re-transmit chain */ l = &arp->rxmt; for (b = *l; b; b = b->nextrxt) { if (b == a) { *l = a->nextrxt; break; } l = &b->nextrxt; } for (b = *l; b; b = b->nextrxt) { l = &b->nextrxt; } *l = a; a->rxtsrem--; a->nextrxt = NULL; a->rtime = NOW + ReTransTimer; a = arp->rxmt; if (a == NULL) nrxt = 0; else nrxt = a->rtime - NOW; dodrops: xp = arp->dropf; arp->dropf = NULL; arp->dropl = NULL; qunlock(&arp->qlock); for (; xp; xp = next) { next = xp->list; icmphostunr(f, ifc, xp, icmp6_adr_unreach, 1); } return nrxt; }
static void fsopen(Req *r) { int t; uvlong path; Aux *a; Fid *fid; Whist *wh; fid = r->fid; path = fid->qid.path; t = qidtype(fid->qid.path); if((r->ifcall.mode != OREAD && t != Fnew && t != Fmap) || (r->ifcall.mode&ORCLOSE)){ respond(r, "permission denied"); return; } a = fid->aux; switch(t){ case Droot: currentmap(0); rlock(&maplock); a->map = map; incref(map); runlock(&maplock); respond(r, nil); break; case D1st: if((wh = gethistory(qidnum(path))) == nil){ respond(r, "file does not exist"); return; } closewhist(a->w); a->w = wh; a->n = a->w->ndoc-1; r->ofcall.qid.vers = wh->doc[a->n].time; r->fid->qid = r->ofcall.qid; respond(r, nil); break; case D2nd: respond(r, nil); break; case Fnew: a->s = s_copy(""); respond(r, nil); break; case Fmap: case F1st: case F2nd: respond(r, nil); break; default: respond(r, "programmer error"); break; } }
static long consread(Chan *c, void *va, long n, vlong offset) { int send; char buf[64], ch; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: return devtabread(c, va, n, offset); case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); while(!qcanread(lineq)) { if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: send = 1; break; case '\n': send = 1; default: kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, n); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } }
/* * Check all frames on device and resend any frames that have been * outstanding for 200% of the device round trip time average. */ static void aoesweepproc(void*) { ulong i, tx, timeout, nbc; vlong starttick; enum { Nms = 100, Nbcms = 30*1000, }; /* magic */ uchar *ea; Aoeata *a; Aoedev *d; Devlink *l; Frame *f, *e; nbc = Nbcms/Nms; loop: if(nbc-- == 0){ if(rediscover && !waserror()){ discover(0xffff, 0xff); poperror(); } nbc = Nbcms/Nms; } starttick = MACHP(0)->ticks; rlock(&devs); for(d = devs.d; d; d = d->next){ if(!canqlock(d)) continue; if(!UP(d)){ qunlock(d); continue; } tx = 0; f = d->frames; e = f + d->nframes; for (; f < e; f++){ if(f->tag == Tfree) continue; l = f->dl; timeout = l->rttavg << 1; i = tsince(f->tag); if(i < timeout) continue; if(d->nout == d->maxout){ if(d->maxout > 1) d->maxout--; d->lastwadj = MACHP(0)->ticks; } a = (Aoeata*)f->hdr; if(a->scnt > Dbcnt / Aoesectsz && ++f->nl->lostjumbo > (d->nframes << 1)){ ea = f->dl->eatab[f->eaidx]; eventlog("%æ: jumbo failure on %s:%E; lba%lld\n", d, f->nl->path, ea, f->lba); d->maxbcnt = Dbcnt; d->flag &= ~Djumbo; } resend(d, f); if(tx++ == 0){ if((l->rttavg <<= 1) > Rtmax) l->rttavg = Rtmax; eventlog("%æ: rtt %ldms\n", d, TK2MS(l->rttavg)); } } if(d->nout == d->maxout && d->maxout < d->nframes && TK2MS(MACHP(0)->ticks - d->lastwadj) > 10*1000){ /* more magic */ d->maxout++; d->lastwadj = MACHP(0)->ticks; } qunlock(d); } runlock(&devs); i = Nms - TK2MS(MACHP(0)->ticks - starttick); if(i > 0) tsleep(&up->sleep, return0, 0, i); goto loop; }
void CodeGen::gen_a(JavaByteCodes op, jtype jt) { if (gen_a_platf(op, jt)) { return; } if (gen_a_generic(op, jt)) { return; } if (is_f(jt) && gen_a_f(op, jt)) { return; } if (jt == i32 && gen_a_i32(op)) { return; } unsigned stackFix = 0; bool shft = op == OPCODE_ISHL || op == OPCODE_ISHR || op == OPCODE_IUSHR; const CallSig* rcs = NULL; if (is_f(jt)) { assert(jt == dbl64 || jt == flt32); char * helper = NULL; bool is_dbl = jt == dbl64; if (op == OPCODE_INEG) { SYNC_FIRST(static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64)); SYNC_FIRST(static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32)); rcs = is_dbl? &cs_dbl : &cs_flt; stackFix = gen_stack_to_args(true, *rcs, 0, 1); helper = is_dbl ? (char*)&rt_h_neg_dbl64 : (char*)&rt_h_neg_flt32; gen_call_novm(*rcs, helper, 1); runlock(*rcs); } else { //if (m_jframe->dip(1).stype == st_imm && ) SYNC_FIRST(static const CallSig cs_dbl(CCONV_STDCALL, dbl64, dbl64, dbl64, i32)); SYNC_FIRST(static const CallSig cs_flt(CCONV_STDCALL, flt32, flt32, flt32, i32)); rcs = is_dbl? &cs_dbl : &cs_flt; stackFix = gen_stack_to_args(true, *rcs, 0, 2); helper = is_dbl ? (char*)&rt_h_dbl_a : (char*)&rt_h_flt_a; gen_call_novm(*rcs, helper, 2, op); runlock(*rcs); } } else if (jt==i64) { if (op == OPCODE_INEG) { SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64)); rcs = &cs; stackFix = gen_stack_to_args(true, *rcs, 0, 1); gen_call_novm(*rcs, (void*)&rt_h_neg_i64, 1); runlock(*rcs); } else if (shft) { SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64, i32, i32)); rcs = &cs; stackFix = gen_stack_to_args(true, *rcs, 0, 2); gen_call_novm(*rcs, (void*)&rt_h_i64_shift, 2, op); runlock(*rcs); } else { SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i64, i64, i64, i32)); rcs = &cs; stackFix = gen_stack_to_args(true, *rcs, 0, 2); gen_call_novm(*rcs, (void*)&rt_h_i64_a, 2, op); runlock(*rcs); } } else { assert(jt==i32); if (op == OPCODE_INEG) { SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i32, i32)); rcs = &cs; stackFix = gen_stack_to_args(true, *rcs, 0, 1); gen_call_novm(*rcs, (void*)&rt_h_neg_i32, 1); runlock(*rcs); } else if (op == OPCODE_IADD || op == OPCODE_ISUB) { const Val& op2 = vstack(0); vpop(); rlock(op2); const Val& op1 = vstack(0); vpop(); rlock(op1); AR ar = valloc(i32); Opnd reg(i32, ar); //TODO: may eliminate additional register allocation mov(reg, op1.as_opnd()); alu(op == OPCODE_IADD ? alu_add : alu_sub, reg, op2.as_opnd()); runlock(op1); runlock(op2); vpush(Val(i32, ar)); return; } else { SYNC_FIRST(static const CallSig cs(CCONV_STDCALL, i32, i32, i32, i32)); rcs = &cs; stackFix = gen_stack_to_args(true, *rcs, 0, 2); gen_call_novm(*rcs, (void*)&rt_h_i32_a, 2, op); runlock(*rcs); } } assert(rcs != NULL); gen_save_ret(*rcs); if (stackFix != 0) { alu(alu_sub, sp, stackFix); } }
long conswrite(Chan *c, void *va, long count, vlong offset) { char buf[128], *p; int x, y; USED(offset); if(c->qid.type & QTDIR) error(Eperm); switch((ulong)c->qid.path) { default: error(Egreg); case Qcons: if(canrlock(&kprintq.l)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq.l); nexterror(); } qwrite(kprintq.q, va, count); poperror(); runlock(&kprintq.l); return count; } runlock(&kprintq.l); } return write(1, va, count); case Qsysctl: return sysconwrite(va, count); case Qconsctl: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = 0; if(strncmp(buf, "rawon", 5) == 0) { kbd.raw = 1; return count; } else if(strncmp(buf, "rawoff", 6) == 0) { kbd.raw = 0; return count; } error(Ebadctl); case Qkeyboard: for(x=0; x<count; ) { Rune r; x += chartorune(&r, &((char*)va)[x]); gkbdputc(gkbdq, r); } return count; case Qpointer: if(count > sizeof buf-1) count = sizeof buf -1; memmove(buf, va, count); buf[count] = 0; p = nil; x = strtoul(buf+1, &p, 0); if(p == nil || p == buf+1) error(Eshort); y = strtoul(p, 0, 0); setpointer(x, y); return count; case Qnull: return count; case Qpin: if(up->env->pgrp->pin != Nopin) error("pin already set"); if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; up->env->pgrp->pin = atoi(buf); return count; case Qtime: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; timeoffset = strtoll(buf, 0, 0)-osusectime(); return count; case Quser: if(count >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, count); buf[count] = '\0'; if(count > 0 && buf[count-1] == '\n') buf[--count] = '\0'; if(count == 0) error(Ebadarg); if(strcmp(up->env->user, eve) != 0) error(Eperm); setid(buf, 0); return count; case Qhostowner: if(count >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, count); buf[count] = '\0'; if(count > 0 && buf[count-1] == '\n') buf[--count] = '\0'; if(count == 0) error(Ebadarg); if(strcmp(up->env->user, eve) != 0) error(Eperm); kstrdup(&eve, buf); return count; case Qhoststdout: return write(1, va, count); case Qhoststderr: return write(2, va, count); case Qjit: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; x = atoi(buf); if (x < 0 || x > 9) error(Ebadarg); cflag = x; return count; case Qsysname: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; kstrdup(&ossysname, buf); return count; case Qsnarf: if(offset+count >= SnarfSize) error(Etoobig); snarftab->qid.vers++; memmove((uchar*)(c->aux)+offset, va, count); return count; } return 0; }
long consread(Chan *c, void *va, long count, vlong offset) { int i, n, ch, eol; Pointer m; char *p, buf[64]; if(c->qid.type & QTDIR) return devdirread(c, va, count, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, count, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, count, ossysname); case Qrandom: return randomread(va, count); case Qnotquiterandom: pseudoRandomBytes(va, count); return count; case Qpin: p = "pin set"; if(up->env->pgrp->pin == Nopin) p = "no pin"; return readstr(offset, va, count, p); case Qhostowner: return readstr(offset, va, count, eve); case Qhoststdin: return read(0, va, count); /* should be pread */ case Quser: return readstr(offset, va, count, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, count, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, count, buf); case Qdrivers: p = malloc(READSTR); if(p == nil) error(Enomem); n = 0; for(i = 0; devtab[i] != nil; i++) n += snprint(p+n, READSTR-n, "#%C %s\n", devtab[i]->dc, devtab[i]->name); n = readstr(offset, va, count, p); free(p); return n; case Qmemory: return poolread(va, count, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, count, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); 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); continue; } eol = 0; switch(ch) { case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case '\n': case 0x04: eol = 1; default: kbd.line[kbd.x++] = ch; break; } if(kbd.x == sizeof(kbd.line) || eol){ if(ch == 0x04) kbd.x--; qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, count); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, count, gkscanid); else return qread(gkscanq, va, count); case Qkeyboard: return qread(gkbdq, va, count); case Qpointer: m = mouseconsume(); n = sprint(buf, "m%11d %11d %11d %11lud ", m.x, m.y, m.b, m.msec); if (count < n) n = count; memmove(va, buf, n); return n; case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, count); poperror(); runlock(&kprintq.l); return n; case Qsnarf: if(offset == 0) { free(c->aux); c->aux = clipread(); } if(c->aux == nil) return 0; return readstr(offset, va, count, c->aux); } }
static void fileRUnlock(File *f) { runlock(&f->lk); }
static long consread(Chan *c, void *va, long n, vlong offset) { int send; char *p, buf[64], ch; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: return devtabread(c, va, n, offset); case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); /* register this proc's read interest in the channel */ /* this probably won't be done here. the read/readn requests * are going to be different watcher callbacks */ /* the following waits for a signal from the keyboard handler */ uv_mutex_lock(&line_lock); uv_cond_wait(&line_ready, &line_lock); n = qread(lineq, va, n); uv_mutex_unlock(&line_lock); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } }
Packet* ManagedObjectAdapter::invokeMethod(uint32 methid, DistributedMethod* inv) { Packet* resp = new MethodReturnMessage(0); switch (methid) { case 6: lock(inv->getBooleanParameter()); break; case 7: lock((ManagedObject*) inv->getObjectParameter()); break; case 8: rlock(inv->getBooleanParameter()); break; case 9: wlock(inv->getBooleanParameter()); break; case 10: wlock((ManagedObject*) inv->getObjectParameter()); break; case 11: unlock(inv->getBooleanParameter()); break; case 12: runlock(inv->getBooleanParameter()); break; case 13: setLockName(inv->getAsciiParameter(_param0_setLockName__String_)); break; case 14: resp->insertBoolean(notifyDestroy()); break; case 15: writeObject(inv->getAsciiParameter(_param0_writeObject__String_)); break; case 16: readObject(inv->getAsciiParameter(_param0_readObject__String_)); break; case 17: initializeTransientMembers(); break; case 18: updateToDatabase(); break; case 19: queueUpdateToDatabaseTask(); break; case 20: clearUpdateToDatabaseTask(); break; case 21: resp->insertInt(getLastCRCSave()); break; case 22: setLastCRCSave(inv->getUnsignedIntParameter()); break; case 23: resp->insertBoolean(isPersistent()); break; case 24: resp->insertSignedInt(getPersistenceLevel()); break; case 25: setPersistent(inv->getSignedIntParameter()); break; default: return NULL; } return resp; }
void Compiler::gen_switch(const JInst & jinst) { assert(jinst.opcode == OPCODE_LOOKUPSWITCH || jinst.opcode == OPCODE_TABLESWITCH); Opnd val = vstack(0, true).as_opnd(); vpop(); rlock(val); gen_bb_leave(NOTHING); if (jinst.opcode == OPCODE_LOOKUPSWITCH) { unsigned n = jinst.get_num_targets(); for (unsigned i = 0; i < n; i++) { Opnd key(jinst.key(i)); unsigned pc = jinst.get_target(i); alu(alu_cmp, val, key); br(eq, pc, m_bbinfo->start); } runlock(val); br(cond_none, jinst.get_def_target(), m_bbinfo->start); return; } // // TABLESWITCH // alu(alu_cmp, val, jinst.high()); br(gt, jinst.get_def_target(), m_bbinfo->start); alu(alu_cmp, val, jinst.low()); br(lt, jinst.get_def_target(), m_bbinfo->start); AR gr_tabl = valloc(jobj); movp(gr_tabl, DATA_SWITCH_TABLE | m_curr_inst->pc, m_bbinfo->start); #ifdef _EM64T_ // On EM64T, we operate with I_32 value in a register, but the // register will be used as 64 bit in address form - have to extend sx(Opnd(i64, val.reg()), Opnd(i32, val.reg())); #endif // Here, we need to extract 'index-=low()' - can pack this into // complex address form: // [table + index*sizeof(void*) - low()*sizeof(void*)], // but only if low()*sizeof(void*) does fit into displacement ... int tmp = -jinst.low(); const int LO_BOUND = INT_MIN/(int)sizeof(void*); const int UP_BOUND = INT_MAX/(int)sizeof(void*); if (LO_BOUND<=tmp && tmp<=UP_BOUND) { ld(jobj, gr_tabl, gr_tabl, -jinst.low()*sizeof(void*), val.reg(), sizeof(void*)); } else { // ... otherwise subtract explicitly, but only if the register // is not used anywhere else if (rrefs(val.reg()) !=0) { Opnd vtmp(i32, valloc(i32)); mov(vtmp, val); // make a copy of val runlock(val); val = vtmp; rlock(val); } alu(alu_sub, val, jinst.low()); ld(jobj, gr_tabl, gr_tabl, 0, val.reg(), sizeof(void*)); } runlock(val); br(gr_tabl); }
static int gen(Chan *c, int i, Dir *dp, int lockit) { Devlogfs *l; long size; Qid qid; qid.vers = 0; qid.type = 0; if (i + Qctl < Qfs) { switch (i + Qctl) { case Qctl: qid.path = Qctl; devdir(c, qid, devlogfsctlname, 0, eve, 0666, dp); return 1; case Qusers: qid.path = Qusers; devdir(c, qid, devlogfsusersname, 0, eve, 0444, dp); return 1; case Qdump: qid.path = Qdump; devdir(c, qid, devlogfsdumpname, 0, eve, 0444, dp); return 1; } } i -= Qfs - Qctl; if (lockit) rlock(&devlogfslist.rwlock); if (waserror()) { if (lockit) runlock(&devlogfslist.rwlock); nexterror(); } for (l = devlogfslist.head; l; l = l->next) { if (i < Qend - Qfs) break; i -= Qend - Qfs; } if (l == nil) { poperror(); if (lockit) runlock(&devlogfslist.rwlock); return -1; } switch (Qfs + i) { case Qfsboot: size = l->lb ? logfsbootgetsize(l->lb) : 0; break; default: size = 0; break; } /* perhaps the user id should come from the underlying file */ qid.path = MKPATH(l->instance, Qfs + i); devdir(c, qid, l->filename[i], size, eve, 0666, dp); poperror(); if (lockit) runlock(&devlogfslist.rwlock); return 1; }
bool CodeGen::gen_a_generic(JavaByteCodes op, jtype jt) { if (op == OPCODE_INEG) { return false; // later } if (jt == i32) { bool v2_imm = vis_imm(0); if (v2_imm && (op == OPCODE_ISHL || op == OPCODE_ISHL || op == OPCODE_IUSHR)) { // accept it } /*else if (v2_imm && (op == OPCODE_IMUL || op == OPCODE_IDIV)) { // accept it } else if (op == OPCODE_IMUL) { // accept it }*/ else if (op == OPCODE_IADD || op == OPCODE_ISUB) { // accept it } else if (op == OPCODE_IOR || op == OPCODE_IAND || op == OPCODE_IXOR) { // accept it } else if (vis_imm(0) && m_jframe->size()>1 && vis_imm(1)) { // accept it } else { return false; } } else if (is_f(jt)) { if (op != OPCODE_IADD && op != OPCODE_ISUB && op != OPCODE_IMUL && op != OPCODE_IDIV) { return false; } } else { return false; } bool is_dbl = jt == dbl64; unsigned v1_depth = is_dbl?2:1; if (vis_imm(v1_depth) && vis_imm(0)) { const Val& v1 = m_jframe->dip(v1_depth); const Val& v2 = m_jframe->dip(0); Val res; if (jt==dbl64) { double d = rt_h_dbl_a(v1.dval(), v2.dval(), op); res = Val(d); } else if (jt==flt32) { float f = rt_h_flt_a(v1.fval(), v2.fval(), op); res = Val(f); } else { assert(jt==i32); int i = rt_h_i32_a(v1.ival(), v2.ival(), op); res = Val(i); } vpop(); vpop(); vpush(res); return true; } // if v1.is_imm() && v2.is_imm() const Val& v1 = vstack(v1_depth, true); Opnd res = v1.as_opnd(); if (rrefs(v1.reg()) > 1) { rlock(v1); AR ar = valloc(jt); runlock(v1); Opnd reg(jt, ar); mov(reg, v1.as_opnd()); res = reg; } rlock(res); rlock(v1); const Val& v2 = m_jframe->dip(0); /* if (false )v2. #ifdef _IA32_ // on IA32 can use address in a displacement alu(to_alu(op), v1, ar_x, (int)v2.addr()); #else AR addr = valloc(jobj); rlock(addr); movp(addr, v2.addr()); alu_mem(jt, to_alu(op), r1, addr); runlock(addr); #endif } else */ if(v2.is_mem()) { // Everyone can do 'reg, mem' operation alu(to_alu(op), res, v2.as_opnd()); } else if(v2.is_imm() && jt==i32) { // 'reg, imm' is only for i32 operations alu(to_alu(op), res, v2.ival()); } else { Opnd v2 = vstack(0, true).as_opnd(); alu(to_alu(op), res, v2); } vpop(); vpop(); runlock(v1); runlock(res); vpush(res); return true; }
static Devlogfs * devlogfsconfig(char *name, char *device) { Devlogfs *newl, *l; int i; int n; char buf[100], *fields[12]; long rawblocksize, rawsize; newl = nil; qlock(&devlogfslist.configqlock); if (waserror()) { qunlock(&devlogfslist.configqlock); devlogfsfree(newl); nexterror(); } rlock(&devlogfslist.rwlock); for (l = devlogfslist.head; l; l = l->next) if (strcmp(l->name, name) == 0) { runlock(&devlogfslist.rwlock); error(Einuse); } /* horrid n^2 solution to finding a unique instance number */ for (i = 0;; i++) { for (l = devlogfslist.head; l; l = l->next) if (l->instance == i) break; if (l == nil) break; } runlock(&devlogfslist.rwlock); newl = emalloc(sizeof(Devlogfs)); newl->instance = i; newl->name = estrdup(name); newl->device = estrdup(device); newl->filename[Qfs - Qfs] = estrconcat(devlogfsprefix, name, nil); newl->filename[Qfsboot - Qfs] = estrconcat(devlogfsprefix, name, devlogfsbootsuffix, nil); newl->flash = devlogfskopen(device, nil, ORDWR); newl->flashctl = devlogfskopen(device, "ctl", ORDWR); newl->flashctl->offset = 0; if ((n = kchanio(newl->flashctl, buf, sizeof(buf), OREAD)) <= 0) { print("devlogfsconfig: read ctl failed: %s\n", up->env->errstr); error(up->env->errstr); } if (n >= sizeof(buf)) n = sizeof(buf) - 1; buf[n] = 0; n = tokenize(buf, fields, nelem(fields)); if(n < 7) error("unexpected flashctl format"); newl->nand = strcmp(fields[3], "nand") == 0; rawblocksize = strtol(fields[6], nil, 0); rawsize = strtol(fields[5], nil, 0)-strtol(fields[4], nil, 0); if(newl->nand == 0) error("only NAND supported at the moment"); errorany(nandfsinit(newl, rawsize, rawblocksize, xread, xwrite, xerase, xsync, &newl->ll)); wlock(&devlogfslist.rwlock); newl->next = devlogfslist.head; devlogfslist.head = newl; logfsfreemem(devlogfslist.defname); devlogfslist.defname = nil; if (!waserror()){ devlogfslist.defname = estrdup(name); poperror(); } wunlock(&devlogfslist.rwlock); poperror(); qunlock(&devlogfslist.configqlock); return newl; }
ThreadRunner::~ThreadRunner() { pleaseTerminate(); boost::mutex::scoped_lock runlock(m_runmutex); boost::mutex::scoped_lock calllock(m_callmutex); }
void serve9p1(Chan *chan, uint8_t *ib, int nib) { int n, t; uint8_t inbuf[MAXMSG+MAXDAT], outbuf[MAXMSG+MAXDAT]; Oldfcall fi, fo; for(;;){ if(nib){ memmove(inbuf, ib, nib); n = nib; nib = 0; }else n = read(chan->chan, inbuf, sizeof inbuf); if(chat) print("read msg %d\n", n); if(n == 0 && (chan == cons.srvchan || chan == cons.chan)) continue; if(n <= 0) return; if(convM2S9p1(inbuf, &fi, n) != n){ error9p1(chan, outbuf); continue; } t = fi.type; if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) { print("9p1: bad message type\n"); error9p1(chan, outbuf); continue; } if(CHAT(chan)) print("9p1: fi %O\n", &fi); /* * set up reply message */ fo.err = 0; if(t == Tread9p1) fo.data = (char*)outbuf + 8; /* * call the file system */ cons.work.count++; cons.rate.count += n; /* * call the file system */ rlock(&mainlock); rlock(&chan->reflock); (*call9p1[t])(chan, &fi, &fo); runlock(&chan->reflock); runlock(&mainlock); fo.type = t+1; fo.tag = fi.tag; if(chat) print("9p1: fo %O\n", &fo); if(fo.err) { strcpy(fo.ename, errstring[fo.err]); if(CHAT(cp)) print(" error: %s\n", fo.ename); fo.type = Terror9p1+1; } n = convS2M9p1(&fo, outbuf); if(n == 0) { print("9p1: bad S2M conversion\n"); error9p1(chan, outbuf); continue; } cons.rate.count += n; send(chan, outbuf, n); } }
static long consread(Chan *c, void *buf, long n, vlong offset) { int l; Osenv *o; int ch, eol, i; char *p, tmp[128]; char *cbuf = buf; if(n <= 0) return n; o = up->env; switch((ulong)c->qid.path){ case Qdir: return devdirread(c, buf, n, consdir, nelem(consdir), devgen); case Qsysctl: return readstr(offset, buf, n, VERSION); case Qcons: case Qkeyboard: qlock(&kbd); if(waserror()) { qunlock(&kbd); nexterror(); } if(kbd.raw || kbd.kbdr) { if(qcanread(lineq)) n = qread(lineq, buf, n); else { /* read as much as possible */ do { i = qread(kbdq, cbuf, n); cbuf += i; n -= i; } while(n>0 && qcanread(kbdq)); n = cbuf - (char*)buf; } } else { while(!qcanread(lineq)) { qread(kbdq, &kbd.line[kbd.x], 1); ch = kbd.line[kbd.x]; eol = 0; switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case '\n': case 0x04: eol = 1; default: kbd.line[kbd.x++] = ch; break; } if(kbd.x == sizeof(kbd.line) || eol) { if(ch == 0x04) kbd.x--; qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, buf, n); } qunlock(&kbd); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, buf, n, kscanid); else return qread(kscanq, buf, n); case Qtime: snprint(tmp, sizeof(tmp), "%.lld", (vlong)mseconds()*1000); return readstr(offset, buf, n, tmp); case Qhostowner: return readstr(offset, buf, n, eve); case Quser: return readstr(offset, buf, n, o->user); case Qjit: snprint(tmp, sizeof(tmp), "%d", cflag); return readstr(offset, buf, n, tmp); case Qnull: return 0; case Qmsec: return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); case Qsysname: if(sysname == nil) return 0; return readstr(offset, buf, n, sysname); case Qnotquiterandom: genrandom(buf, n); return n; case Qrandom: return randomread(buf, n); case Qmemory: return poolread(buf, n, offset); case Qdrivers: p = malloc(READSTR); if(p == nil) error(Enomem); l = 0; for(i = 0; devtab[i] != nil; i++) l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc, devtab[i]->name); if(waserror()){ free(p); nexterror(); } n = readstr(offset, buf, n, p); free(p); poperror(); return n; case Qklog: return qread(klogq, buf, n); case Qkprint: rlock(&kprintq); if(waserror()){ runlock(&kprintq); nexterror(); } n = qread(kprintq.q, buf, n); poperror(); runlock(&kprintq); return n; default: print("consread %llud\n", c->qid.path); error(Egreg); } return -1; /* never reached */ }
int authCheck(Fcall* t, Fid* fid, Fsys* fsys) { Con *con; Fid *afid; uchar buf[1]; /* * Can't lookup with FidWlock here as there may be * protocol to do. Use a separate lock to protect altering * the auth information inside afid. */ con = fid->con; if(t->afid == NOFID){ /* * If no authentication is asked for, allow * "none" provided the connection has already * been authenticatated. * * The console is allowed to attach without * authentication. */ rlock(&con->alock); if(con->isconsole){ /* anything goes */ }else if((con->flags&ConNoneAllow) || con->aok){ static int noneprint; if(noneprint++ < 10) consPrint("attach %s as %s: allowing as none\n", fsysGetName(fsys), fid->uname); vtfree(fid->uname); fid->uname = vtstrdup(unamenone); }else{ runlock(&con->alock); consPrint("attach %s as %s: connection not authenticated, not console\n", fsysGetName(fsys), fid->uname); werrstr("cannot attach as none before authentication"); return 0; } runlock(&con->alock); if((fid->uid = uidByUname(fid->uname)) == nil){ consPrint("attach %s as %s: unknown uname\n", fsysGetName(fsys), fid->uname); werrstr("unknown user"); return 0; } return 1; } if((afid = fidGet(con, t->afid, 0)) == nil){ consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname); werrstr("bad authentication fid"); return 0; } /* * Check valid afid; * check uname and aname match. */ if(!(afid->qid.type & QTAUTH)){ consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys), fid->uname); fidPut(afid); werrstr("bad authentication fid"); return 0; } if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){ consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys), fid->uname, fsysGetName(afid->fsys), afid->uname); fidPut(afid); werrstr("attach/auth mismatch"); return 0; } qlock(&afid->alock); if(afid->cuname == nil){ if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){ qunlock(&afid->alock); consPrint("attach %s as %s: %r\n", fsysGetName(fsys), fid->uname); fidPut(afid); werrstr("fossil authCheck: auth protocol not finished"); return 0; } } qunlock(&afid->alock); assert(fid->uid == nil); if((fid->uid = uidByUname(afid->cuname)) == nil){ consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys), fid->uname, afid->cuname); fidPut(afid); werrstr("unknown user"); return 0; } vtfree(fid->uname); fid->uname = vtstrdup(afid->cuname); fidPut(afid); /* * Allow "none" once the connection has been authenticated. */ wlock(&con->alock); con->aok = 1; wunlock(&con->alock); return 1; }
static long conswrite(Chan *c, void *va, long n, vlong offset) { char buf[128], *a, ch; int x; if(c->qid.type & QTDIR) error(Eperm); switch((ulong)c->qid.path) { default: error(Egreg); case Qcons: if(canrlock(&kprintq.l)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq.l); nexterror(); } qwrite(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } runlock(&kprintq.l); } return write(1, va, n); case Qsysctl: return sysconwrite(va, n); case Qconsctl: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ kbd.raw = 1; /* clumsy hack - wake up reader */ ch = 0; qwrite(kbdq, &ch, 1); } else if(strncmp(buf, "rawoff", 6) == 0){ kbd.raw = 0; } if((a = strchr(a, ' ')) != nil) a++; } break; case Qkeyboard: for(x=0; x<n; ) { Rune r; x += chartorune(&r, &((char*)va)[x]); gkbdputc(gkbdq, r); } break; case Qnull: break; case Qtime: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; timeoffset = strtoll(buf, 0, 0)-osusectime(); break; case Qhostowner: if(!iseve()) error(Eperm); if(offset != 0 || n >= sizeof(buf)) error(Ebadarg); memmove(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); /* renameuser(eve, buf); */ /* renameproguser(eve, buf); */ kstrdup(&eve, buf); kstrdup(&up->env->user, buf); break; case Quser: if(!iseve()) error(Eperm); if(offset != 0) error(Ebadarg); if(n <= 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); setid(buf, 0); break; case Qhoststdout: return write(1, va, n); case Qhoststderr: return write(2, va, n); case Qjit: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; x = atoi(buf); if(x < 0 || x > 9) error(Ebadarg); cflag = x; break; case Qsysname: if(offset != 0) error(Ebadarg); if(n < 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(buf[n-1] == '\n') buf[n-1] = 0; kstrdup(&ossysname, buf); break; } return n; }
static Whist* getcache(int n, int hist) { int i, isw; uint32_t t; Wcache *c, **cp, **evict; Whist *wh; isw = 0; rlock(&cachelock); if(c = findcache(n)){ Found: current(c); if(hist) currenthist(c); rlock(c); if(hist) wh = c->hist; else wh = c->current; if(wh) incref(wh); runlock(c); if(isw) wunlock(&cachelock); else runlock(&cachelock); return wh; } runlock(&cachelock); wlock(&cachelock); if(c = findcache(n)){ isw = 1; /* better to downgrade lock but can't */ goto Found; } if(ncache < Mcache){ Alloc: c = emalloc(sizeof *c); ncache++; }else{ /* find something to evict. */ t = ~0; evict = nil; for(i=0; i<Nhash; i++){ for(cp=&tab[i], c=*cp; c; cp=&c->hash, c=*cp){ if(c->use < t && (!c->hist || c->hist->ref==1) && (!c->current || c->current->ref==1)){ evict = cp; t = c->use; } } } if(evict == nil){ fprint(2, "wikifs: nothing to evict\n"); goto Alloc; } c = *evict; *evict = c->hash; closewhist(c->current); closewhist(c->hist); memset(c, 0, sizeof *c); } c->n = n; c->hash = tab[n%Nhash]; tab[n%Nhash] = c; isw = 1; goto Found; }
void arpenter(struct Fs *fs, int version, uint8_t *ip, uint8_t *mac, int n, int refresh) { ERRSTACK(1); struct arp *arp; struct route *r; struct arpent *a, *f, **l; struct Ipifc *ifc; struct medium *type; struct block *bp, *next; uint8_t v6ip[IPaddrlen]; arp = fs->arp; if (n != 6) { return; } switch (version) { case V4: r = v4lookup(fs, ip, NULL); v4tov6(v6ip, ip); ip = v6ip; break; case V6: r = v6lookup(fs, ip, NULL); break; default: panic("arpenter: version %d", version); return; /* to supress warnings */ } if (r == NULL) { return; } ifc = r->rt.ifc; type = ifc->m; qlock(&arp->qlock); for (a = arp->hash[haship(ip)]; a; a = a->hash) { if (a->type != type || (a->state != AWAIT && a->state != AOK)) continue; if (ipcmp(a->ip, ip) == 0) { a->state = AOK; memmove(a->mac, mac, type->maclen); if (version == V6) { /* take out of re-transmit chain */ l = &arp->rxmt; for (f = *l; f; f = f->nextrxt) { if (f == a) { *l = a->nextrxt; break; } l = &f->nextrxt; } } a->ifc = ifc; a->ifcid = ifc->ifcid; bp = a->hold; a->hold = NULL; if (version == V4) ip += IPv4off; a->utime = NOW; a->ctime = a->utime; qunlock(&arp->qlock); while (bp) { next = bp->list; if (ifc != NULL) { rlock(&ifc->rwlock); if (waserror()) { runlock(&ifc->rwlock); nexterror(); } if (ifc->m != NULL) ifc->m->bwrite(ifc, bp, version, ip); else freeb(bp); runlock(&ifc->rwlock); poperror(); } else freeb(bp); bp = next; } return; } } if (refresh == 0) { a = newarp6(arp, ip, ifc, 0); a->state = AOK; a->type = type; a->ctime = NOW; memmove(a->mac, mac, type->maclen); } qunlock(&arp->qlock); }
static void ipifcregisterproxy(struct Fs *f, struct Ipifc *ifc, uint8_t * ip) { struct conv **cp, **e; struct Ipifc *nifc; struct Iplifc *lifc; struct medium *m; uint8_t net[IPaddrlen]; /* register the address on any network that will proxy for us */ e = &f->ipifc->conv[f->ipifc->nc]; if (!isv4(ip)) { // V6 for (cp = f->ipifc->conv; cp < e; cp++) { if (*cp == NULL) continue; nifc = (struct Ipifc *)(*cp)->ptcl; if (nifc == ifc) continue; rlock(&nifc->rwlock); m = nifc->m; if (m == NULL || m->addmulti == NULL) { runlock(&nifc->rwlock); continue; } for (lifc = nifc->lifc; lifc; lifc = lifc->next) { maskip(ip, lifc->mask, net); if (ipcmp(net, lifc->remote) == 0) { /* add solicited-node multicast address */ ipv62smcast(net, ip); addselfcache(f, nifc, lifc, net, Rmulti); arpenter(f, V6, ip, nifc->mac, 6, 0); //(*m->addmulti)(nifc, net, ip); break; } } runlock(&nifc->rwlock); } return; } else { // V4 for (cp = f->ipifc->conv; cp < e; cp++) { if (*cp == NULL) continue; nifc = (struct Ipifc *)(*cp)->ptcl; if (nifc == ifc) continue; rlock(&nifc->rwlock); m = nifc->m; if (m == NULL || m->areg == NULL) { runlock(&nifc->rwlock); continue; } for (lifc = nifc->lifc; lifc; lifc = lifc->next) { maskip(ip, lifc->mask, net); if (ipcmp(net, lifc->remote) == 0) { (*m->areg) (nifc, ip); break; } } runlock(&nifc->rwlock); } } }
/* * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. */ static void putstrn0(char *str, int n, int usewrite) { int m; char *t; char buf[PRINTSIZE + 2]; ERRSTACK(1); /* * if kprint is open, put the message there, otherwise * if there's an attached bit mapped display, * put the message there. */ m = consoleprint; if (canrlock(&(&kprintq)->rwlock)) { if (kprintq.q != NULL) { if (waserror()) { runlock(&(&kprintq)->rwlock); nexterror(); } if (usewrite) qwrite(kprintq.q, str, n); else qiwrite(kprintq.q, str, n); poperror(); m = 0; } runlock(&(&kprintq)->rwlock); } if (m && screenputs != NULL) screenputs(str, n); /* * if there's a serial line being used as a console, * put the message there. */ if (serwrite != NULL) { serwrite(str, n); return; } if (printq == 0) return; while (n > 0) { t = memchr(str, '\n', n); if (t && !kbd.raw) { m = t - str; if (m > sizeof(buf) - 2) m = sizeof(buf) - 2; memmove(buf, str, m); buf[m] = '\r'; buf[m + 1] = '\n'; if (usewrite) qwrite(printq, buf, m + 2); else qiwrite(printq, buf, m + 2); str = t + 1; n -= m + 1; } else { if (usewrite) qwrite(printq, str, n); else qiwrite(printq, str, n); break; } } }
static long consread(Chan *c, void *va, long n, vlong offset) { int send; char *p, buf[64], ch; FILE * battery; FILE * brightness; int size; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: return devtabread(c, va, n, offset); case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); while(!qcanread(lineq)) { if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: send = 1; break; case '\n': send = 1; default: kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, n); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qevents: return qread(c->aux, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; case Qbattery: if(type == 's') battery = fopen("/sys/class/power_supply/battery/capacity", "r"); else if(type == 'c') battery = fopen("/sys/class/power_supply/max17042-0/capacity", "r"); else battery = fopen("/sys/class/power_supply/battery/capacity", "r"); size = fread(buf, 1, sizeof(buf), battery); fclose(battery); buf[size - 1] = '\0'; return readstr(offset, va, n, buf); case Qtype: if(type == 's') strncpy(buf, "nexus s", sizeof(buf)); else if(type == 'c') strncpy(buf, "nook color", sizeof(buf)); else if(type == 'e') strncpy(buf, "emulator", sizeof(buf)); else strncpy(buf, "nexus s", sizeof(buf)); return readstr(offset, va, n, buf); case Qbrightness: if(type == 'c') brightness = fopen("/sys/devices/platform/omap_pwm_led/leds/lcd-backlight/brightness", "r"); else if(type == 'e') return; else brightness = fopen("/sys/class/backlight/s5p_bl/brightness", "r"); size = fread(buf, 1, sizeof(buf), brightness); fclose(brightness); buf[size - 1] = '\0'; return readstr(offset, va, n, buf); } }