int sunsrvudp(SunSrv *srv, char *address) { int fd; char adir[40]; Arg *arg; fd = announce(address, adir); if(fd < 0) return -1; arg = emalloc(sizeof(Arg)); arg->fd = fd; arg->srv = srv; arg->creply = chancreate(sizeof(SunMsg*), 10); arg->csync = chancreate(sizeof(void*), 10); proccreate(sunudpread, arg, SunStackSize); proccreate(sunudpwrite, arg, SunStackSize); recvp(arg->csync); recvp(arg->csync); chanfree(arg->csync); free(arg); return 0; }
void threadmain(int argc, char *argv[]) { char m[48]; int t; Alt a[] = { /* c v op */ {nil, m, CHANRCV}, {nil, &t, CHANRCV}, {nil, nil, CHANEND}, }; /* create mouse event channel and mouse process */ a[0].c = chancreate(sizeof m, 0); proccreate(mouseproc, a[0].c, STACK); /* create clock event channel and clock process */ a[1].c = chancreate(sizeof(ulong), 0); /* clock event channel */ proccreate(clockproc, a[1].c, STACK); for(;;){ switch(alt(a)){ case 0: /*mouse event */ fprint(2, "click "); break; case 1: /* clock event */ fprint(2, "tic "); break; default: sysfatal("can't happen"); } } }
void listenthread(void *arg) { Conn *c; Ioproc *io; io = ioproc(); USED(arg); threadsetname("listen %s", adir); for(;;){ c = emalloc(sizeof(Conn)); c->fd = iolisten(io, adir, c->dir); if(c->fd < 0){ if(verbose) fprint(2, "%T listen: %r\n"); close(afd); free(c); return; } c->inc = chancreate(sizeof(void*), 0); c->internal = chancreate(sizeof(void*), 0); c->inq = qalloc(); c->outq = qalloc(); c->outqdead = chancreate(sizeof(void*), 0); if(verbose) fprint(2, "%T incoming call on %s\n", c->dir); threadcreate(connthread, c, STACK); } }
void startbloomproc(Bloom *b) { b->writechan = chancreate(sizeof(void*), 0); b->writedonechan = chancreate(sizeof(ulong), 0); vtproc(bloomwriteproc, b); }
int xopenfd(Msg *m) { char errs[ERRMAX]; int n, p[2]; Conn *nc; if(pipe(p) < 0){ rerrstr(errs, sizeof errs); err(m, errs); /* XXX return here? */ } if(verbose) fprint(2, "%T xopen pipe %d %d...", p[0], p[1]); /* now we're committed. */ /* a new connection for this fid */ nc = emalloc(sizeof(Conn)); nc->internal = chancreate(sizeof(void*), 0); /* a ref for us */ nc->fdfid = m->fid; m->fid->ref++; nc->fdfid->openfd++; nc->fdmode = m->tx.mode; nc->fd = p[0]; /* a thread to tend the pipe */ threadcreate(openfdthread, nc, STACK); /* if mode is ORDWR, that openfdthread will write; start a reader */ if((m->tx.mode&3) == ORDWR){ nc = emalloc(sizeof(Conn)); nc->internal = chancreate(sizeof(void*), 0); nc->fdfid = m->fid; m->fid->ref++; nc->fdfid->openfd++; nc->fdmode = OREAD; nc->fd = dup(p[0], -1); threadcreate(openfdthread, nc, STACK); } /* steal fid from other connection */ if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) fidput(m->fid); /* rewrite as Ropenfd */ m->rx.type = Ropenfd; n = GBIT32(m->rpkt); m->rpkt = erealloc(m->rpkt, n+4); PBIT32(m->rpkt+n, p[1]); n += 4; PBIT32(m->rpkt, n); m->rpkt[4] = Ropenfd; m->rx.unixfd = p[1]; return 0; }
void threadmain(int argc, char **argv) { uintptr_t pid; char *cmd = nil; char **args = nil; /* * don't bother with fancy arg processing, because it picks up options * for the command you are starting. Just check for -c as argv[1] * and then take it from there. */ if (argc < 2) usage(); while (argv[1][0] == '-') { switch(argv[1][1]) { case 'c': if (argc < 3) usage(); cmd = strdup(argv[2]); args = &argv[2]; break; case 'd': debug = 1; break; default: usage(); } ++argv; --argc; } /* run a command? */ if(cmd) { pid = fork(); if (pid < 0) sysfatal("fork failed: %r"); if(pid == 0) { hang(); exec(cmd, args); if(cmd[0] != '/') exec(smprint("/bin/%s", cmd), args); sysfatal("exec %s failed: %r", cmd); } } else { if(argc != 2) usage(); pid = atoi(argv[1]); } out = chancreate(sizeof(char*), 0); quit = chancreate(sizeof(char*), 0); forkc = chancreate(sizeof(uint32_t *), 0); nread++; procrfork(writer, nil, Stacksize, 0); reader((void*)pid); }
void mountcons(void) { fschan = chancreate(sizeof(Fsevent), 0); writechan = chancreate(sizeof(void*), 0); fs.tree = alloctree("win", "win", DMDIR|0555, nil); devcons = createfile(fs.tree->root, "cons", "win", 0666, nil); if(devcons == nil) sysfatal("creating /dev/cons: %r"); devnew = createfile(fs.tree->root, "wnew", "win", 0666, nil); if(devnew == nil) sysfatal("creating /dev/wnew: %r"); threadpostmountsrv(&fs, nil, "/dev", MBEFORE); }
SunSrv* sunSrv(void) { SunSrv *srv; srv = emalloc(sizeof(SunSrv)); srv->chatty = 0; srv->crequest = chancreate(sizeof(SunMsg*), 16); srv->creply = chancreate(sizeof(SunMsg*), 16); srv->cthread = chancreate(sizeof(Targ), 4); proccreate(sunRpcProc, srv, SunStackSize); return srv; }
void startplumbing(void) { cplumb = chancreate(sizeof(Plumbmsg*), 0); chansetname(cplumb, "cplumb"); threadcreate(plumbthread, nil, STACK); }
void plumbstart(void) { plumbchan = chancreate(sizeof(Plumbmsg*), 0); proccreate(plumbwebproc, nil, STACK); threadcreate(plumbwebthread, nil, STACK); }
void hoststart(void) { hostc = chancreate(sizeof(int), 0); chansetname(hostc, "hostc"); proccreate(hostproc, hostc, STACK); }
void twaitinit(void) { threadwaitchan(); /* allocate it before returning */ twaitchan = chancreate(sizeof(Waitreq), 10); threadcreate(waitthread, nil, 128*1024); }
void initicachewrite(void) { int i; Index *ix; initround(&iwrite.round, "icache", 120*60*1000); ix = mainindex; for(i=0; i<ix->nsects; i++){ ix->sects[i]->writechan = chancreate(sizeof(ulong), 1); ix->sects[i]->writedonechan = chancreate(sizeof(ulong), 1); vtproc(icachewriteproc, ix->sects[i]); } vtproc(icachewritecoord, nil); vtproc(delaykickroundproc, &iwrite.round); }
static void execthread(void *a) { Client *c; int p; char tmp[32]; c = a; snprint(tmp, sizeof tmp, "exec%d", c->num); threadsetname(tmp); c->execpid = chancreate(sizeof(ulong), 0); proccreate(execproc, c, STACK); p = recvul(c->execpid); chanfree(c->execpid); c->execpid = nil; close(c->fd[1]); c->fd[1] = c->fd[0]; if(p != -1){ c->pid = p; c->activethread = 2; threadcreate(readthread, c, STACK); threadcreate(writethread, c, STACK); if(c->execreq) respond(c->execreq, nil); }else{ if(c->execreq) respond(c->execreq, c->err); } }
void startpipe(void) { newpipechan = chancreate(sizeof(Window*), 0); threadcreate(newpipethread, nil, STACK); snarffd = open("/dev/snarf", OREAD|OCEXEC); }
int pipeline(int fd, char *cmd, ...) { Exec *e; va_list a; e = emalloc(sizeof(Exec)); if(pipe(e->p)<0 || pipe(e->q)<0) error("can't create pipe"); close(e->p[0]); e->p[0] = fd; va_start(a, cmd); e->cmd = vsmprint(cmd, a); va_end(a); e->sync = chancreate(sizeof(ulong), 0); if(e->sync == nil) error("can't create channel"); proccreate(execproc, e, STACK); recvul(e->sync); chanfree(e->sync); free(e->cmd); close(e->p[0]); close(e->p[1]); close(e->q[1]); fd = e->q[0]; free(e); return fd; }
static Conn* newconn(Ether *e) { int i; Conn *c; qlock(e); for(i = 0; i < nelem(e->conns); i++){ c = e->conns[i]; if(c == nil || c->ref == 0){ if(c == nil){ c = emallocz(sizeof(Conn), 1); c->rc = chancreate(sizeof(Buf*), 16); c->nb = i; } c->ref = 1; if(i == e->nconns) e->nconns++; e->conns[i] = c; deprint(2, "%s: newconn %d\n", argv0, i); qunlock(e); return c; } } qunlock(e); return nil; }
Channel* threadwaitchan(void) { if(_threadwaitchan==nil) _threadwaitchan = chancreate(sizeof(Waitmsg*), 16); return _threadwaitchan; }
int main(void) { int i, nprocs, procn[Nproc]; fail = 0; nprocs = 0; ch = chancreate(1000, sizeof(int)); if(ch == nil){ fail = 1; printf("chancreate failed\n"); } for(i = 0; i < Nproc; ++i){ procn[i] = i + 1; if(proccreate(f, &procn[i], 0) == nil){ fail = 1; printf("proccreate failed\n"); }else{ nprocs++; } } for(i = 0; i < nprocs; ++i){ int n; if(chanrecv(ch, &n) != 1){ fail = 1; printf("recv error\n"); } } chanfree(ch); return fail; }
void extstart(void) { char buf[32]; int fd; static int p[2]; static void *arg[2]; if(pipe(p) < 0) return; sprint(exname, "/srv/sam.%s", getuser()); fd = create(exname, 1, 0600); if(fd < 0){ /* assume existing guy is more important */ Err: close(p[0]); close(p[1]); return; } sprint(buf, "%d", p[0]); if(write(fd, buf, strlen(buf)) <= 0) goto Err; close(fd); /* * leave p[0] open so if the file is removed the event * library won't get an error */ plumbc = chancreate(sizeof(int), 0); arg[0] = plumbc; arg[1] = &p[1]; proccreate(extproc, arg, 1024); atexit(removeextern); }
static void xioproc(void *a) { Channel *c; Ioproc *io; Iocall *r; c = a; if(io = mallocz(sizeof(*io), 1)){ char buf[128]; /* * open might fail, ignore it for programs like factotum * that don't use iointerrupt() anyway. */ snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid()); io->ctl = open(buf, OWRITE); if((io->creply = chancreate(sizeof(void*), 0)) == nil){ if(io->ctl >= 0) close(io->ctl); free(io); io = nil; } else io->c = c; } while(send(c, &io) < 0) ; if(io == nil) return; for(;;){ while(recv(io->c, &r) < 0) ; if(r == 0) break; if(io->intr){ r->ret = -1; strcpy(r->err, "interrupted"); } else if((r->ret = r->op(&r->arg)) < 0) rerrstr(r->err, sizeof r->err); qlock(io); if(io->intr){ io->intr = 0; if(io->ctl >= 0) write(io->ctl, "nointerrupt", 11); } while(send(io->creply, &r) < 0) ; qunlock(io); } if(io->ctl >= 0) close(io->ctl); chanfree(io->c); chanfree(io->creply); free(io); }
static Cimage * loadimg(Rune *src, int x , int y) { Channel *sync; Cimage *ci; Runestr rs; Exec *e; char *filter; int fd, p[2], q[2]; ci = emalloc(sizeof(Cimage)); rs. r = src; rs.nr = runestrlen(rs.r); ci->url = urlalloc(&rs, nil, HGet); fd = urlopen(ci->url); if(fd < 0){ Err1: return ci; } filter = getfilter(ci->url->ctype.r, x, y); if(filter == nil){ werrstr("%S unsupported: %S", ci->url->ctype.r, ci->url->act.r); Err2: close(fd); goto Err1; } if(pipe(p)<0 || pipe(q)<0) error("can't create pipe"); close(p[0]); p[0] = fd; sync = chancreate(sizeof(ulong), 0); if(sync == nil) error("can't create channel"); e = emalloc(sizeof(Exec)); e->p[0] = p[0]; e->p[1] = p[1]; e->q[0] = q[0]; e->q[1] = q[1]; e->cmd = filter; e->sync = sync; proccreate(execproc, e, STACK); recvul(sync); chanfree(sync); close(p[0]); close(p[1]); close(q[1]); ci->mi = readmemimage(q[0]); close(q[0]); if(ci->mi == nil){ werrstr("can't read image"); goto Err2; } free(filter); return ci; }
void playinit(void) { int i; full = chancreate(sizeof(Pacbuf*), 1); empty = chancreate(sizeof(Pacbuf*), NPacbuf); spare = chancreate(sizeof(Pacbuf*), NSparebuf); playout = chancreate(sizeof(Pacbuf*), NPacbuf+NSparebuf); for(i = 0; i < NPacbuf; i++) sendp(empty, malloc(sizeof(Pacbuf))); for(i = 0; i < NSparebuf; i++) sendp(spare, malloc(sizeof(Pacbuf))); playc = chancreate(sizeof(Pmsg), 1); procrfork(decproc, nil, 32*1024, RFFDG); procrfork(pcmproc, nil, 32*1024, RFFDG); }
void threadmain(int argc, char **argv) { Scsi *s; Drive *d; char buf[80]; ARGBEGIN{ case 'v': debug++; scsiverbose++; }ARGEND if(argc != 1) usage(); fmtinstall('M', msfconv); if((s = openscsi(argv[0])) == nil) error("opening scsi: %r"); d = malloc(sizeof(*d)); if(d == nil) error("out of memory"); memset(d, 0, sizeof d); d->scsi = s; d->w = newwindow(); d->ctocdisp = chancreate(sizeof(Toc), 0); d->cdbreq = chancreate(sizeof(Toc), 0); d->cdbreply = chancreate(sizeof(Toc), 0); d->cstatus = chancreate(sizeof(Cdstatus), 0); proccreate(wineventproc, d->w, STACK); proccreate(cddbproc, d, STACK); proccreate(cdstatusproc, d, STACK); cleanname(argv[0]); snprint(buf, sizeof(buf), "%s/", argv[0]); winname(d->w, buf); wintagwrite(d->w, "Stop Pause Resume Eject Ingest ", 5+6+7+6+7); eventwatcher(d); }
Filsys* filsysinit(Channel *cxfidalloc) { int n, fd, pid, p0; Filsys *fs; Channel *c; char buf[128]; fs = emalloc(sizeof(Filsys)); if(cexecpipe(&fs->cfd, &fs->sfd) < 0) goto Rescue; fmtinstall('F', fcallfmt); clockfd = open("/dev/time", OREAD|OCEXEC); fd = open("/dev/user", OREAD); strcpy(buf, "Jean-Paul_Belmondo"); if(fd >= 0){ n = read(fd, buf, sizeof buf-1); if(n > 0) buf[n] = 0; close(fd); } fs->user = estrdup(buf); fs->cxfidalloc = cxfidalloc; pid = getpid(); /* * Create and post wctl pipe */ if(cexecpipe(&p0, &wctlfd) < 0) goto Rescue; sprint(srvwctl, "/srv/riowctl.%s.%d", fs->user, pid); post(srvwctl, "wctl", p0); close(p0); /* * Start server processes */ c = chancreate(sizeof(char*), 0); if(c == nil) error("wctl channel"); proccreate(wctlproc, c, 4096); threadcreate(wctlthread, c, 4096); proccreate(filsysproc, fs, 10000); /* * Post srv pipe */ sprint(srvpipe, "/srv/rio.%s.%d", fs->user, pid); post(srvpipe, "wsys", fs->cfd); return fs; Rescue: free(fs); return nil; }
void extstart(void) { char *user, *disp; int fd, flags; static void *arg[2]; user = getenv("USER"); if(user == nil) return; disp = getenv("DISPLAY"); if(disp) exname = smprint("/tmp/.sam.%s.%s", user, disp); else exname = smprint("/tmp/.sam.%s", user); if(exname == nil){ fprint(2, "not posting for B: out of memory\n"); return; } if(mkfifo(exname, 0600) < 0){ struct stat st; if(errno != EEXIST || stat(exname, &st) < 0) return; if(!S_ISFIFO(st.st_mode)){ removeextern(); if(mkfifo(exname, 0600) < 0) return; } } fd = open(exname, OREAD|ONONBLOCK); if(fd == -1){ removeextern(); return; } /* * Turn off no-delay and provide ourselves as a lingering * writer so as not to get end of file on read. */ flags = fcntl(fd, F_GETFL, 0); if(flags<0 || fcntl(fd, F_SETFL, flags&~O_NONBLOCK)<0 ||open(exname, OWRITE) < 0){ close(fd); removeextern(); return; } plumbc = chancreate(sizeof(int), 0); chansetname(plumbc, "plumbc"); arg[0] = plumbc; arg[1] = (void*)(uintptr)fd; proccreate(extproc, arg, STACK); atexit(removeextern); }
void threadmain(int argc, char **argv) { int pid; char *cmd = nil; char **args = nil; ARGBEGIN{ case 'c': cmd = strdup(EARGF(usage())); args = argv; break; default: usage(); }ARGEND; /* run a command? */ if(cmd) { pid = fork(); if (pid < 0) { fprint(2, "No fork: %r\n"); exits("fork failed"); } if(pid == 0) { hang(getpid()); exec(cmd, args); fprint(2, "Bad exec: %s: %r\n", cmd); exits("Bad exec"); } } else { if(argc != 1) sysfatal("usage"); pid = atoi(argv[0]); } out = chancreate(sizeof(char*), 0); quit = chancreate(sizeof(char*), 0); forkc = chancreate(sizeof(ulong *), 0); nread++; procrfork(writer, nil, 8192, 0); reader((void*)pid); }
Conv* convalloc(char *sysuser) { Conv *c; c = mallocz(sizeof(Conv), 1); if(c == nil) return nil; c->ref = 1; c->tag = taggen++; c->next = conv; c->sysuser = estrdup(sysuser); c->state = "nascent"; c->rpcwait = chancreate(sizeof(void*), 0); c->keywait = chancreate(sizeof(void*), 0); strcpy(c->err, "protocol has not started"); conv = c; convreset(c); return c; }
Req* reqalloc(void) { Req *r; if(reqs == nil) reqs = chancreate(sizeof(Req*), 256); if(r = nbrecvp(reqs)) return r; r = malloc(sizeof(Req)); return r; }
Window* wmk(Mousectl *mc, Channel *ck, Channel *cctl) { print_func_entry(); Window *w; w = emalloc(sizeof(Window)); // NO. w->mc = nil; // *mc; w->ck = ck; w->cctl = cctl; w->conswrite = chancreate(sizeof(Conswritemesg), 0); w->consread = chancreate(sizeof(Consreadmesg), 0); w->mouseread = chancreate(sizeof(Mousereadmesg), 0); w->wctlread = chancreate(sizeof(Consreadmesg), 0); w->id = ++id; w->notefd = -1; w->dir = estrdup(startdir); w->label = estrdup("<unnamed>"); incref(w); /* ref will be removed after mounting; avoids delete before ready to be deleted */ print_func_exit(); return w; }