/* * associate an address with the interface. This wipes out any previous * addresses. This is a macro that means, remove all the old interfaces * and add a new one. */ static char* ipifcconnect(Conv* c, char **argv, int argc) { Proc *up = externup(); char *err; Ipifc *ifc; ifc = (Ipifc*)c->ptcl; if(ifc->medium == nil) return "ipifc not yet bound to device"; if(waserror()){ wunlock(ifc); nexterror(); } wlock(ifc); while(ifc->lifc){ err = ipifcremlifc(ifc, ifc->lifc); if(err) error(err); } wunlock(ifc); poperror(); err = ipifcadd(ifc, argv, argc, 0, nil); if(err) return err; Fsconnected(c, nil); return nil; }
void closepgrp(Pgrp *p) { Mhead **h, **e, *f, *next; if(decref(&p->ref) != 0) return; qlock(&p->debug); wlock(&p->ns); p->pgrpid = -1; e = &p->mnthash[MNTHASH]; for(h = p->mnthash; h < e; h++) { for(f = *h; f; f = next) { wlock(&f->lock); cclose(f->from); mountfree(f->mount); f->mount = nil; next = f->hash; wunlock(&f->lock); putmhead(f); } } wunlock(&p->ns); qunlock(&p->debug); free(p); }
/* * associate an address with the interface. This wipes out any previous * addresses. This is a macro that means, remove all the old interfaces * and add a new one. */ static char *ipifcconnect(struct conv *c, char **argv, int argc) { ERRSTACK(1); char *err; struct Ipifc *ifc; ifc = (struct Ipifc *)c->ptcl; if (ifc->m == NULL) return "ipifc not yet bound to device"; if (waserror()) { wunlock(&ifc->rwlock); nexterror(); } wlock(&ifc->rwlock); while (ifc->lifc) { err = ipifcremlifc(ifc, ifc->lifc); if (err) error(err); } wunlock(&ifc->rwlock); poperror(); err = ipifcadd(ifc, argv, argc, 0, NULL); if (err) return err; Fsconnected(c, NULL); return NULL; }
static Devlogfs * devlogfssetdefname(char *name) { Devlogfs *l; char *searchname; wlock(&devlogfslist.rwlock); if (waserror()) { wunlock(&devlogfslist.rwlock); nexterror(); } if (name == nil) searchname = devlogfslist.defname; else searchname = name; for (l = devlogfslist.head; l; l = l->next) if (strcmp(l->name, searchname) == 0) break; if (l == nil) { logfsfreemem(devlogfslist.defname); devlogfslist.defname = nil; } else if (name) { if (devlogfslist.defname) { logfsfreemem(devlogfslist.defname); devlogfslist.defname = nil; } devlogfslist.defname = estrdup(name); } poperror(); wunlock(&devlogfslist.rwlock); return l; }
// --- tERROR pr_call _MemoryRealloc( tPO* po, tHANDLE* handle, tDWORD size ) { tOBJECT* obj; tERROR error; PR_TRACE_A0( MakeObject(handle), "Enter _MemoryRealloc" ); if ( handle->obj == NULL ) { // alloc new memory error = PrAlloc( (tPTR*)&obj, sizeof(tOBJECT) + size ); if ( PR_SUCC(error) ) { wlock(po); handle->obj = obj; _ObjectInit0( handle ); wunlock(po); } } else { wlock(po); if ( PR_SUCC(error=PrRealloc((tPTR*)&handle->obj,handle->obj,sizeof(tOBJECT)+size)) ) { *odata(handle->obj) = handle->obj + 1; } wunlock(po); } PR_TRACE_A1( MakeObject(handle), "Leave _MemoryRealloc ret %terr", error ); return error; }
static void gencurrent(Wcache *w, Qid *q, char *file, char *lock, uint32_t *t, Whist **wp, int n) { Dir *d; Whist *wh; if(*wp && *t+Tcache >= time(0)) return; wlock(w); if(*wp && *t+Tcache >= time(0)){ wunlock(w); return; } if(((d = wdirstat(file)) == nil) || (d->qid.path==q->path && d->qid.vers==q->vers)){ *t = time(0); wunlock(w); free(d); return; } free(d); if(wh = readwhist(file, lock, q)){ wh->n = n; *t = time(0); closewhist(*wp); *wp = wh; } else fprint(2, "error file=%s lock=%s %r\n", file, lock); wunlock(w); }
static Chan* consopen(Chan *c, int omode) { c->aux = 0; switch((ulong)c->qid.path){ case Qconsctl: if(!iseve()) error(Eperm); qlock(&kbd); kbd.ctl++; qunlock(&kbd); break; case Qkeyboard: if((omode & 3) != OWRITE) { qlock(&kbd); kbd.kbdr++; flushkbdline(kbdq); kbd.raw = 1; qunlock(&kbd); } break; case Qscancode: qlock(&kbd); if(kscanq || !kscanid) { qunlock(&kbd); c->flag &= ~COPEN; if(kscanq) error(Einuse); else error(Ebadarg); } kscanq = qopen(256, 0, nil, nil); qunlock(&kbd); break; case Qkprint: if((omode & 3) != OWRITE) { wlock(&kprintq); if(kprintq.q != nil){ wunlock(&kprintq); error(Einuse); } kprintq.q = qopen(32*1024, Qcoalesce, nil, nil); if(kprintq.q == nil){ wunlock(&kprintq); error(Enomem); } qnoblock(kprintq.q, 1); wunlock(&kprintq); c->iounit = qiomaxatomic; } break; } return devopen(c, omode, consdir, nelem(consdir), devgen); }
void devream(Device *d, int top) { Device *l; loop: print("\tdevream: %Z %d\n", d, top); switch(d->type) { default: print("ream: unknown dev type %Z\n", d); return; case Devcw: devream(d->cw.w, 0); devream(d->cw.c, 0); if(top) { wlock(&mainlock); cwream(d); wunlock(&mainlock); } devinit(d); return; case Devfworm: devream(d->fw.fw, 0); fwormream(d); break; case Devpart: devream(d->part.d, 0); break; case Devmlev: case Devmcat: case Devmirr: for(l=d->cat.first; l; l=l->link) devream(l, 0); break; case Devjuke: case Devworm: case Devlworm: case Devwren: break; case Devswab: d = d->swab.d; goto loop; } devinit(d); if(top) { wlock(&mainlock); rootream(d, ROOT_ADDR); superream(d, SUPER_ADDR); wunlock(&mainlock); } }
Chan* consopen(Chan *c, int omode) { c = devopen(c, omode, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { case Qconsctl: incref(&kbd.ctl); break; case Qpointer: if(incref(&kbd.ptr) != 1){ decref(&kbd.ptr); c->flag &= ~COPEN; error(Einuse); } break; case Qscancode: qlock(&kbd.gq); if(gkscanq || !gkscanid) { qunlock(&kbd.q); c->flag &= ~COPEN; if(gkscanq) error(Einuse); else error(Ebadarg); } gkscanq = qopen(256, 0, nil, nil); qunlock(&kbd.gq); break; case Qkprint: wlock(&kprintq.l); if(kprintq.q != nil){ wunlock(&kprintq.l); c->flag &= ~COPEN; error(Einuse); } kprintq.q = qopen(32*1024, 0, 0, 0); if(kprintq.q == nil){ wunlock(&kprintq.l); c->flag &= ~COPEN; error(Enomem); } qnoblock(kprintq.q, 1); wunlock(&kprintq.l); break; case Qsnarf: if(omode == ORDWR) error(Eperm); if(omode == OREAD) c->aux = strdup(""); else c->aux = mallocz(SnarfSize, 1); break; } return c; }
static Chan* envcreate(Chan *c, char *name, int omode, ulong) { Egrp *eg; Evalue *e; Evalue **ent; if(c->qid.type != QTDIR || !envwriteable(c)) error(Eperm); if(strlen(name) >= sizeof(up->genbuf)) error(Etoolong); omode = openmode(omode); eg = envgrp(c); wlock(eg); if(waserror()) { wunlock(eg); nexterror(); } if(envlookup(eg, name, -1) != nil) error(Eexist); e = smalloc(sizeof(Evalue)); e->name = smalloc(strlen(name)+1); strcpy(e->name, name); if(eg->nent == eg->ment){ eg->ment += 32; ent = smalloc(sizeof(eg->ent[0])*eg->ment); if(eg->nent) memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent); free(eg->ent); eg->ent = ent; } e->qid.path = ++eg->path; e->qid.vers = 0; eg->vers++; eg->ent[eg->nent++] = e; c->qid = e->qid; wunlock(eg); poperror(); c->offset = 0; c->mode = omode; c->flag |= COPEN; return c; }
static Chan* envcreate(Chan *c, char *name, int omode, ulong) { Egrp *eg; Evalue *e; if(c->qid.type != QTDIR || !envwriteable(c)) error(Eperm); if(strlen(name) >= sizeof(up->genbuf)) error(Etoolong); omode = openmode(omode); eg = envgrp(c); wlock(eg); if(waserror()) { wunlock(eg); nexterror(); } if(envlookup(eg, name, -1) != nil) error(Eexist); if(eg->nent == eg->ment){ Evalue *tmp; eg->ment += DELTAENV; if((tmp = realloc(eg->ent, sizeof(eg->ent[0])*eg->ment)) == nil){ eg->ment -= DELTAENV; error(Enomem); } eg->ent = tmp; } eg->vers++; e = &eg->ent[eg->nent++]; e->value = nil; e->len = 0; e->name = smalloc(strlen(name)+1); strcpy(e->name, name); mkqid(&e->qid, ++eg->path, 0, QTFILE); c->qid = e->qid; wunlock(eg); poperror(); c->offset = 0; c->mode = omode; c->flag |= COPEN; return c; }
static void envcreate(Chan *c, char *name, int omode, int i) { Proc *up = externup(); Egrp *eg; Evalue *e; Evalue **ent; if(c->qid.type != QTDIR) error(Eperm); omode = openmode(omode); eg = envgrp(c); wlock(&eg->rwl); if(waserror()) { wunlock(&eg->rwl); nexterror(); } if(envlookup(eg, name, -1)) error(Eexist); e = smalloc(sizeof(Evalue)); e->name = smalloc(strlen(name)+1); strcpy(e->name, name); if(eg->nent == eg->ment){ eg->ment += 32; ent = smalloc(sizeof(eg->ent[0])*eg->ment); if(eg->nent) memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent); free(eg->ent); eg->ent = ent; } e->qid.path = ++eg->path; e->qid.vers = 0; eg->vers++; eg->ent[eg->nent++] = e; c->qid = e->qid; wunlock(&eg->rwl); poperror(); c->offset = 0; c->mode = omode; c->flag |= COPEN; }
const char *GetLastErrorMsg(void) { static unsigned int lock = 0; wlock(&lock); static TCHAR szBuf[256]; LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); char *p; while ( (p=strchr((char*)lpMsgBuf,'\n'))!=NULL ) *p=' '; while ( (p=strchr((char*)lpMsgBuf,'\r'))!=NULL ) *p=' '; sprintf(szBuf, "%s (error code %d)", lpMsgBuf, dw); LocalFree(lpMsgBuf); wunlock(&lock); return szBuf; }
/* * allocate 'count' contiguous channels * of type 'type' and return pointer to base */ Chan* fs_chaninit(int type, int count, int data) { uint8_t *p; Chan *cp, *icp; int i; p = malloc(count * (sizeof(Chan)+data)); icp = (Chan*)p; for(i = 0; i < count; i++) { cp = (Chan*)p; cp->next = chans; chans = cp; cp->type = type; cp->chan = cons.chano; cons.chano++; strncpy(cp->whoname, "<none>", sizeof cp->whoname); wlock(&cp->reflock); wunlock(&cp->reflock); rlock(&cp->reflock); runlock(&cp->reflock); p += sizeof(Chan); if(data){ cp->pdata = p; p += data; } } return icp; }
static void envremove(Chan *c) { int i; Egrp *eg; Evalue *e; if(c->qid.type & QTDIR) error(Eperm); eg = envgrp(c); wlock(&eg->rwl); e = 0; for(i=0; i<eg->nent; i++){ if(eg->ent[i]->qid.path == c->qid.path){ e = eg->ent[i]; eg->nent--; eg->ent[i] = eg->ent[eg->nent]; eg->vers++; break; } } wunlock(&eg->rwl); if(e == 0) error(Enonexist); free(e->name); if(e->value) free(e->value); free(e); }
void consclose(Chan *c) { if((c->flag & COPEN) == 0) return; switch((ulong)c->qid.path) { case Qconsctl: if(decref(&kbd.ctl) == 0) kbd.raw = 0; break; case Qpointer: decref(&kbd.ptr); break; case Qscancode: qlock(&kbd.gq); if(gkscanq) { qfree(gkscanq); gkscanq = 0; } qunlock(&kbd.gq); break; case Qkprint: wlock(&kprintq.l); qfree(kprintq.q); kprintq.q = nil; wunlock(&kprintq.l); break; case Qsnarf: if(c->mode == OWRITE) clipwrite(c->aux, strlen(c->aux)); free(c->aux); break; } }
void cmd_start(void) { superok(cur_fs->dev, superaddr(cur_fs->dev), 0); wunlock(&mainlock); print("kfs: file system started\n"); }
static void consclose(Chan *c) { if((c->flag & COPEN) == 0) return; switch((ulong)c->qid.path) { case Qconsctl: /* last close of control file turns off raw */ if(decref(&kbd.ctl) == 0) kbd.raw = 0; break; case Qscancode: qlock(&kbd.gq); if(gkscanq) { qfree(gkscanq); gkscanq = nil; } qunlock(&kbd.gq); break; case Qkprint: wlock(&kprintq.l); qfree(kprintq.q); kprintq.q = nil; wunlock(&kprintq.l); break; } }
static void sysbrk(void) { ulong v; Segment *s; v = arg(0); if(systrace) fprint(2, "brk(%#lux)\n", v); if(v >= P->S[SEGSTACK]->start) sysfatal("bss > stack, wtf?"); if(v < P->S[SEGBSS]->start) sysfatal("bss length < 0, wtf?"); s = P->S[SEGBSS]; wlock(&s->rw); s->dref = realloc(s->dref, v - s->start + sizeof(Ref)); if(s->dref == nil) sysfatal("error reallocating"); s->data = s->dref + 1; if(s->size < v - s->start) memset((char*)s->data + s->size, 0, v - s->start - s->size); s->size = v - s->start; P->R[0] = 0; wunlock(&s->rw); }
static Chan* consopen(Chan *c, int omode) { c = devopen(c, omode, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { case Qconsctl: incref(&kbd.ctl); break; case Qscancode: qlock(&kbd.gq); if(gkscanq != nil || gkscanid == nil) { qunlock(&kbd.q); c->flag &= ~COPEN; if(gkscanq) error(Einuse); else error("not supported"); } gkscanq = qopen(256, 0, nil, nil); qunlock(&kbd.gq); break; case Qkprint: wlock(&kprintq.l); if(waserror()){ wunlock(&kprintq.l); c->flag &= ~COPEN; nexterror(); } if(kprintq.q != nil) error(Einuse); kprintq.q = qopen(32*1024, Qcoalesce, nil, nil); if(kprintq.q == nil) error(Enomem); qnoblock(kprintq.q, 1); poperror(); wunlock(&kprintq.l); c->iounit = qiomaxatomic; break; case Qevents: c->aux = qopen(512, 0, nil, nil); add_listener(&event_listeners, c->aux); break; } return c; }
static int report_close(void) { wlock(&report_lock); if ( report_fp ) fclose(report_fp); report_fp = NULL; wunlock(&report_lock); return report_rows; }
/* * detach a device from an interface, close the interface * called with ifc->conv closed */ static char* ipifcunbind(Ipifc *ifc) { Proc *up = externup(); char *err; if(waserror()){ wunlock(ifc); nexterror(); } wlock(ifc); /* dissociate routes */ if(ifc->medium != nil && ifc->medium->unbindonclose == 0) ifc->conv->inuse--; ifc->ifcid++; /* disassociate logical interfaces (before zeroing ifc->arg) */ while(ifc->lifc){ err = ipifcremlifc(ifc, ifc->lifc); /* * note: err non-zero means lifc not found, * which can't happen in this case. */ if(err) error(err); } /* disassociate device */ if(ifc->medium && ifc->medium->unbind) (*ifc->medium->unbind)(ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = nil; ifc->reassemble = 0; /* close queues to stop queuing of packets */ qclose(ifc->conv->rq); qclose(ifc->conv->wq); qclose(ifc->conv->sq); ifc->medium = nil; wunlock(ifc); poperror(); return nil; }
static Chan* envopen(Chan *c, int omode) { Egrp *eg; Evalue *e; int trunc; eg = envgrp(c); if(c->qid.type & QTDIR) { if(omode != OREAD) error(Eperm); } else { trunc = omode & OTRUNC; if(omode != OREAD && !envwriteable(c)) error(Eperm); if(trunc) wlock(&eg->rwl); else rlock(&eg->rwl); e = envlookup(eg, nil, c->qid.path); if(e == 0) { if(trunc) wunlock(&eg->rwl); else runlock(&eg->rwl); error(Enonexist); } if(trunc && e->value) { e->qid.vers++; free(e->value); e->value = 0; e->len = 0; } if(trunc) wunlock(&eg->rwl); else runlock(&eg->rwl); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; }
void closedirfile(Readdir *r) { if(decref(&r->dir->readers) == 0){ wlock(&r->dir->RWLock); cleanfilelist(r->dir); wunlock(&r->dir->RWLock); } free(r); }
static void dochaninit(Chan *cp, int fd) { cp->chan = fd; fileinit(cp); wlock(&cp->reflock); wunlock(&cp->reflock); lock(&cp->flock); unlock(&cp->flock); }
static long envwrite(Chan *c, void *a, long n, vlong off) { char *s; ulong len; Egrp *eg; Evalue *e; ulong offset = off; if(n <= 0) return 0; if(offset > Maxenvsize || n > (Maxenvsize - offset)) error(Etoobig); eg = envgrp(c); wlock(eg); if(waserror()){ wunlock(eg); nexterror(); } e = envlookup(eg, nil, c->qid.path); if(e == nil) error(Enonexist); len = offset+n; if(len > e->len) { s = realloc(e->value, len); if(s == nil) error(Enomem); memset(s+offset, 0, n); e->value = s; e->len = len; } memmove(e->value+offset, a, n); e->qid.vers++; eg->vers++; wunlock(eg); poperror(); return n; }
/* * remove a multicast address from an interface, called with c locked */ void ipifcremmulti(struct conv *c, uint8_t * ma, uint8_t * ia) { ERRSTACK(1); struct Ipmulti *multi, **l; struct Iplifc *lifc; struct conv **p; struct Ipifc *ifc; struct Fs *f; f = c->p->f; for (l = &c->multi; *l; l = &(*l)->next) if (ipcmp(ma, (*l)->ma) == 0) if (ipcmp(ia, (*l)->ia) == 0) break; multi = *l; if (multi == NULL) return; /* we don't have it open */ *l = multi->next; for (p = f->ipifc->conv; *p; p++) { if ((*p)->inuse == 0) continue; ifc = (struct Ipifc *)(*p)->ptcl; if (waserror()) { wunlock(&ifc->rwlock); nexterror(); } wlock(&ifc->rwlock); for (lifc = ifc->lifc; lifc; lifc = lifc->next) if (ipcmp(ia, lifc->local) == 0) remselfcache(f, ifc, lifc, ma); wunlock(&ifc->rwlock); poperror(); } kfree(multi); }
/* * remove a multicast address from an interface, called with c->car locked */ void ipifcremmulti(Conv *c, uint8_t *ma, uint8_t *ia) { Proc *up = externup(); Ipmulti *multi, **l; Iplifc *lifc; Conv **p; Ipifc *ifc; Fs *f; f = c->p->f; for(l = &c->multi; *l; l = &(*l)->next) if(ipcmp(ma, (*l)->ma) == 0 && ipcmp(ia, (*l)->ia) == 0) break; multi = *l; if(multi == nil) return; /* we don't have it open */ *l = multi->next; for(p = f->ipifc->conv; *p; p++){ if((*p)->inuse == 0) continue; ifc = (Ipifc*)(*p)->ptcl; if(waserror()){ wunlock(ifc); nexterror(); } wlock(ifc); for(lifc = ifc->lifc; lifc; lifc = lifc->next) if(ipcmp(ia, lifc->local) == 0) remselfcache(f, ifc, lifc, ma); wunlock(ifc); poperror(); } free(multi); }
/* * detach a device from an interface, close the interface * called with ifc->conv closed */ static char *ipifcunbind(struct Ipifc *ifc) { ERRSTACK(1); char *err; if (waserror()) { wunlock(&ifc->rwlock); nexterror(); } wlock(&ifc->rwlock); /* dissociate routes */ if (ifc->m != NULL && ifc->m->unbindonclose == 0) ifc->conv->inuse--; ifc->ifcid++; /* disassociate device */ if (ifc->m != NULL && ifc->m->unbind) (*ifc->m->unbind) (ifc); memset(ifc->dev, 0, sizeof(ifc->dev)); ifc->arg = NULL; ifc->reassemble = 0; /* close queues to stop queuing of packets */ qclose(ifc->conv->rq); qclose(ifc->conv->wq); qclose(ifc->conv->sq); /* disassociate logical interfaces */ while (ifc->lifc) { err = ipifcremlifc(ifc, ifc->lifc); if (err) error(err); } ifc->m = NULL; wunlock(&ifc->rwlock); poperror(); return NULL; }
counters operator+(counters a) { wlock(); n_scanned += a.get_scanned(); n_tested += a.get_tested(); n_passed += a.get_passed(); n_files += a.get_nfiles(); n_success += a.get_nsuccess(); n_failed += a.get_nfailed(); n_exceptions += a.get_nexceptions(); wunlock(); return *this; };