static Session * createsession(int fd) { Session *s; s = smbemalloc(sizeof(Session)); s->fd = fd; s->state = Connected; qlock(&sessions); if (!(*tcp.accept)(s, &s->write)) { qunlock(&sessions); free(s); return nil; } s->thread = procrfork(tcpreader, s, 32768, RFNAMEG); if (s->thread < 0) { qunlock(&sessions); (*s->write)(s, nil, -1); free(s); return nil; } s->next = sessions.head; sessions.head = s; qunlock(&sessions); return s; }
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) { 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 reader(void *v) { int cfd, tfd, forking = 0, pid, newpid; char *ctl, *truss; Msg *s; pid = (int)(uintptr)v; ctl = smprint("/proc/%d/ctl", pid); if ((cfd = open(ctl, OWRITE)) < 0) die(smprint("%s: %r", ctl)); truss = smprint("/proc/%d/syscall", pid); if ((tfd = open(truss, OREAD)) < 0) die(smprint("%s: %r", truss)); cwrite(cfd, ctl, "stop", 4); cwrite(cfd, truss, "startsyscall", 12); s = mallocz(sizeof(Msg) + Bufsize, 1); s->pid = pid; s->buf = (char *)&s[1]; while(pread(tfd, s->buf, Bufsize - 1, 0) > 0){ if (forking && s->buf[1] == '=' && s->buf[3] != '-') { forking = 0; newpid = strtol(&s->buf[3], 0, 0); sendp(forkc, (void*)newpid); procrfork(reader, (void*)newpid, Stacksize, 0); } /* * There are three tests here and they (I hope) guarantee * no false positives. */ if (strstr(s->buf, " Rfork") != nil) { char *a[8]; char *rf; rf = strdup(s->buf); if (tokenize(rf, a, 8) == 5) { ulong flags; flags = strtoul(a[4], 0, 16); if (flags & RFPROC) forking = 1; } free(rf); } sendp(out, s); cwrite(cfd, truss, "startsyscall", 12); s = mallocz(sizeof(Msg) + Bufsize, 1); s->pid = pid; s->buf = (char *)&s[1]; } sendp(quit, nil); threadexitsall(nil); }
void reader(void *v) { char *ctl, *truss; int pid, newpid; int cfd, tfd; Str *s; int forking = 0; pid = (int)v; ctl = smprint("/proc/%d/ctl", pid); if ((cfd = open(ctl, OWRITE)) < 0) die(smprint("%s: %r", ctl)); truss = smprint("/proc/%d/syscall", pid); if ((tfd = open(truss, OREAD)) < 0) die(smprint("%s: %r", truss)); cwrite(cfd, ctl, "stop", 4); cwrite(cfd, truss, "startsyscall", 12); s = mallocz(sizeof(Str) + 8192, 1); s->buf = (char *)&s[1]; /* 8191 is not a typo. It ensures a null-terminated string. The device currently limits to 4096 anyway */ while((s->len = pread(tfd, s->buf, 8191, 0ULL)) > 0){ if (forking && (s->buf[1] == '=') && (s->buf[3] != '-')) { forking = 0; newpid = strtol(&s->buf[3], 0, 0); sendp(forkc, (void*)newpid); procrfork(reader, (void*)newpid, 8192, 0); } /* There are three tests here and they (I hope) guarantee no false positives */ if (strstr(s->buf, " Rfork") != nil) { char *a[8]; char *rf; rf = strdup(s->buf); if (tokenize(rf, a, 8) == 5) { unsigned long flags; flags = strtoul(a[4], 0, 16); if (flags & RFPROC) forking = 1; } free(rf); } sendp(out, s); cwrite(cfd, truss, "startsyscall", 12); s = mallocz(sizeof(Str) + 8192, 1); s->buf = (char *)&s[1]; } sendp(quit, nil); threadexitsall(nil); }
static NbSession * createsession(int fd) { Session *s; s = nbemalloc(sizeof(Session)); s->fd = fd; s->state = NeedSessionRequest; qlock(&sessions); s->thread = procrfork(tcpreader, s, 32768, RFNAMEG); if (s->thread < 0) { qunlock(&sessions); free(s); return nil; } s->next = sessions.head; sessions.head = s; qunlock(&sessions); return s; }
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); }
static int startplay(ushort n) { int fd[2]; Playfd *pfd; char *file; file = getplaylist(n); if(file == nil) return Undef; if (debug & DbgPlayer) fprint(2, "startplay: file is `%s'\n", file); if(pipe(fd) < 0) sysfatal("pipe: %r"); pfd = malloc(sizeof(Playfd)); pfd->filename = file; /* mallocated already */ pfd->fd = fd[1]; pfd->cfd = fd[0]; procrfork(decexec, pfd, 4096, RFFDG|RFENVG); close(fd[1]); /* write fd, for pac4dec */ return fd[0]; /* read fd */ }
int proccreate(void (*f)(void*), void *arg, uint stacksize) { return procrfork(f, arg, stacksize, 0); }
void reader(void *v) { int cfd, tfd, exiting, pid; uintptr_t newpid; char *ctl, *truss; Str *s; static char waitstop[] = "waitstop"; pid = (int)(uintptr)v; if (debug) fprint(outf, "DEBUG: -------------> reader starts with pid %d\n", pid); ctl = smprint("/proc/%d/ctl", pid); if ((cfd = open(ctl, OWRITE)) < 0) die(smprint("%s: %r", ctl)); truss = smprint("/proc/%d/syscall", pid); if ((tfd = open(truss, OREAD)) < 0) die(smprint("%s: %r", truss)); if (debug) fprint(outf, "DEBUG: Send %s to pid %d ...", waitstop, pid); /* child was stopped by hang msg earlier */ cwrite(cfd, ctl, waitstop, sizeof waitstop - 1); if (debug) fprint(outf, "DEBUG: back for %d\n", pid); if (debug) fprint(outf, "DEBUG: Send %s to pid %d\n", "startsyscall", pid); cwrite(cfd, ctl, "startsyscall", 12); if (debug) fprint(outf, "DEBUG: back for %d\n", pid); s = newstr(); exiting = 0; while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) >= 0){ if (s->buf[0] == 'F') { char *val = strstr(s->buf, "= "); if (val) { newpid = strtol(&val[2], 0, 0); sendp(forkc, (void*)newpid); procrfork(reader, (void*)newpid, Stacksize, 0); } } if (strstr(s->buf, " Exits") != nil) exiting = 1; sendp(out, s); /* print line from /proc/$child/syscall */ if (exiting) { s = newstr(); strcpy(s->buf, "\n"); sendp(out, s); break; } /* flush syscall trace buffer */ if (debug) fprint(outf, "DEBUG: Send %s to pid %d\n", "startsyscall", pid); cwrite(cfd, ctl, "startsyscall", 12); if (debug) fprint(outf, "DEBUG: back for %d\n", pid); s = newstr(); } sendp(quit, nil); threadexitsall(nil); }
int startdev(Port *pp) { Dev *d; Usbdev *ud; Devtab *dt; Sarg *sa; Channel *rc; d = pp->dev; assert(d); ud = d->usb; assert(ud != nil); writeinfo(d); if(ud->class == Clhub){ /* * Hubs are handled directly by this process avoiding * concurrent operation so that at most one device * has the config address in use. * We cancel kernel debug for these eps. too chatty. */ pp->hub = newhub(d->dir, d); if(pp->hub == nil) fprint(2, "%s: %s: %r\n", argv0, d->dir); else fprint(2, "usb/hub... "); if(usbdebug > 1) devctl(d, "debug 0"); /* polled hubs are chatty */ return pp->hub == nil ? -1 : 0; } for(dt = devtab; dt->name != nil; dt++) if(devmatch(dt, ud)) break; /* * From here on the device is for the driver. * When we return pp->dev contains a Dev just for us * with only the ctl open. Both devs are released on the last closedev: * driver's upon I/O errors and ours upon port dettach. */ if(dt->name == nil){ dprint(2, "%s: no configured entry for %s (csp %#08lx)\n", argv0, d->dir, ud->csp); close(d->dfd); d->dfd = -1; return 0; } sa = emallocz(sizeof(Sarg), 1); sa->pp = pp; sa->dt = dt; rc = sa->rc = chancreate(sizeof(uint32_t), 1); procrfork(startdevproc, sa, Stack, RFNOTEG); if(recvul(rc) != 0) free(sa); chanfree(rc); fprint(2, "usb/%s... ", dt->name); sleep(Spawndelay); /* in case we re-spawn too fast */ return 0; }
void threadmain(int argc, char *argv[]) { char *srvfile; char *srvpost; char *mntpt; int i; mntpt = "/mnt"; srvpost = nil; rfork(RFNOTEG); ARGBEGIN{ case 'a': aflag = 1; break; case 'm': mntpt = ARGF(); break; case 'd': debug = strtoul(ARGF(), nil, 0); break; case 's': srvpost = ARGF(); break; default: usage(); }ARGEND user = strdup(getuser()); quotefmtinstall(); if(debug) fmtinstall('F', fcallfmt); volumechan = chancreate(sizeof(volume), 1); playchan = chancreate(sizeof(Wmsg), 1); playlistreq = chancreate(sizeof(Wmsg), 0); /* No storage! requires rendez-vous */ workers = chancreate(sizeof(Worker*), 256); for(i = 1; i < Nqid; i++) files[i].workers = chancreate(sizeof(Worker*), 256); if(pipe(srvfd) < 0) sysfatal("pipe failed: %r"); procrfork(srv, nil, STACKSIZE, RFFDG); close(srvfd[0]); /* don't deadlock if child fails */ procrfork(volumeproc, nil, STACKSIZE, RFFDG); playinit(); if(srvpost){ srvfile = smprint("/srv/playlist.%s", srvpost); remove(srvfile); post(srvfile, srvfd[1]); free(srvfile); } if(mount(srvfd[1], -1, mntpt, MBEFORE, "") < 0) sysfatal("mount failed: %r"); threadexits(nil); }
void threadmain(int argc, char *argv[]) { char *defsrv, *srvname; int p[2], fd; int stdio; char *host = nil; long ncache; stdio = 0; ncache = 256; fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); fmtinstall('F', vtfcallfmt); defmnt = nil; defsrv = nil; ARGBEGIN{ case 'd': fmtinstall('F', fcallfmt); dflag = 1; break; case 'c': ncache = atoi(EARGF(usage())); break; case 'i': defmnt = nil; stdio = 1; mfd[0] = 0; mfd[1] = 1; break; case 'h': host = EARGF(usage()); break; case 'S': defsrv = EARGF(usage()); break; case 's': defsrv = "vacfs"; break; case 'm': defmnt = EARGF(usage()); break; case 'p': noperm = 1; break; case 'V': chattyventi = 1; break; default: usage(); }ARGEND if(argc != 1) usage(); if(defsrv == nil && defmnt == nil && !stdio) defmnt = "/n/vac"; if(stdio && defmnt) sysfatal("cannot use -m with -i"); initfcalls(); notify(notifyf); user = getuser(); conn = vtdial(host); if(conn == nil) sysfatal("could not connect to server: %r"); if(vtconnect(conn) < 0) sysfatal("vtconnect: %r"); fs = vacfsopen(conn, argv[0], VtOREAD, ncache); if(fs == nil) sysfatal("vacfsopen: %r"); if(!stdio){ if(pipe(p) < 0) sysfatal("pipe failed: %r"); mfd[0] = p[0]; mfd[1] = p[0]; srvfd = p[1]; if(defsrv){ srvname = smprint("/srv/%s", defsrv); fd = create(srvname, OWRITE|ORCLOSE, 0666); if(fd < 0) sysfatal("create %s: %r", srvname); if(fprint(fd, "%d", srvfd) < 0) sysfatal("write %s: %r", srvname); free(srvname); } } procrfork(srv, 0, Stacksize, RFFDG|RFNAMEG|RFNOTEG); if(!stdio){ close(p[0]); if(defmnt){ if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) sysfatal("mount %s: %r", defmnt); } } threadexits(0); }
void lockscreen(void) { enum { Nfld = 5, Fldlen = 12, Cursorlen = 2*4 + 2*2*16, }; char *s; char buf[Nfld*Fldlen], *flds[Nfld], newcmd[128], cbuf[Cursorlen]; int fd, dx, dy; Image *i; Point p; Rectangle r; Tm *tm; fd = open("/dev/screen", OREAD); if(fd < 0) error("can't open /dev/screen: %r"); if(read(fd, buf, Nfld*Fldlen) != Nfld*Fldlen) error("can't read /dev/screen: %r"); close(fd); buf[sizeof buf-1] = 0; if(tokenize(buf, flds, Nfld) != Nfld) error("can't tokenize /dev/screen header"); snprint(newcmd, sizeof newcmd, "-r %s %s %d %d", flds[1], flds[2], atoi(flds[3]) - 1, atoi(flds[4]) - 1); newwindow(newcmd); if (initdraw(nil, nil, "screenlock") < 0) sysfatal("initdraw failed"); if(display == nil) error("no display"); /* screen is now open and covered. grab mouse and hold on tight */ procrfork(grabmouse, nil, 4096, RFFDG); procrfork(blanker, nil, 4096, RFFDG); fd = open(pic, OREAD); if(fd > 0){ i = readimage(display, fd, 0); if(i){ r = screen->r; p = Pt(r.max.x / 2, r.max.y * 2 / 3); dx = (Dx(screen->r) - Dx(i->r)) / 2; r.min.x += dx; r.max.x -= dx; dy = (Dy(screen->r) - Dy(i->r)) / 2; r.min.y += dy; r.max.y -= dy; draw(screen, screen->r, display->black, nil, ZP); draw(screen, r, i, nil, i->r.min); flushimage(display, 1); } close(fd); /* identify the user on screen, centered */ tm = localtime(time(0)); s = smprint("user %s at %d:%02.2d", getuser(), tm->hour, tm->min); p = subpt(p, Pt(stringwidth(font, "m") * strlen(s) / 2, 0)); screenstring(p, s); } /* clear the cursor */ fd = open("/dev/cursor", OWRITE); if(fd > 0){ memset(cbuf, 0, sizeof cbuf); write(fd, cbuf, sizeof cbuf); /* leave it open */ } }
void threadmain(int argc, char *argv[]) { char *defsrv, *srvname; int p[2], fd; int stdio; char *host = nil; ulong mem; mem = 16<<20; stdio = 0; fmtinstall('H', encodefmt); fmtinstall('V', vtscorefmt); fmtinstall('F', vtfcallfmt); defmnt = nil; defsrv = nil; ARGBEGIN{ case 'd': fmtinstall('F', fcallfmt); dflag = 1; break; case 'i': defmnt = nil; stdio = 1; mfd[0] = 0; mfd[1] = 1; break; case 'h': host = EARGF(usage()); break; case 'S': defsrv = EARGF(usage()); break; case 's': defsrv = "vacfs"; break; case 'M': mem = unittoull(EARGF(usage())); break; case 'm': defmnt = EARGF(usage()); break; case 'p': noperm = 1; break; case 'V': chattyventi = 1; break; default: usage(); }ARGEND if(argc != 1) usage(); #ifdef PLAN9PORT if(defsrv == nil && defmnt == nil && !stdio){ srvname = strchr(argv[0], '/'); if(srvname) srvname++; else srvname = argv[0]; defsrv = vtmalloc(6+strlen(srvname)+1); strcpy(defsrv, "vacfs."); strcat(defsrv, srvname); if(strcmp(defsrv+strlen(defsrv)-4, ".vac") == 0) defsrv[strlen(defsrv)-4] = 0; } #else if(defsrv == nil && defmnt == nil && !stdio) defmnt = "/n/vac"; #endif if(stdio && defmnt) sysfatal("cannot use -m with -i"); initfcalls(); notify(notifyf); user = getuser(); conn = vtdial(host); if(conn == nil) sysfatal("could not connect to server: %r"); if(vtconnect(conn) < 0) sysfatal("vtconnect: %r"); fs = vacfsopen(conn, argv[0], VtOREAD, mem); if(fs == nil) sysfatal("vacfsopen: %r"); if(!stdio){ if(pipe(p) < 0) sysfatal("pipe failed: %r"); mfd[0] = p[0]; mfd[1] = p[0]; srvfd = p[1]; #ifndef PLAN9PORT if(defsrv){ srvname = smprint("/srv/%s", defsrv); fd = create(srvname, OWRITE|ORCLOSE, 0666); if(fd < 0) sysfatal("create %s: %r", srvname); if(fprint(fd, "%d", srvfd) < 0) sysfatal("write %s: %r", srvname); free(srvname); } #endif } #ifdef PLAN9PORT USED(fd); proccreate(srv, 0, 32 * 1024); if(!stdio && post9pservice(p[1], defsrv, defmnt) < 0) sysfatal("post9pservice"); #else procrfork(srv, 0, 32 * 1024, RFFDG|RFNAMEG|RFNOTEG); if(!stdio){ close(p[0]); if(defmnt){ if(mount(srvfd, -1, defmnt, MREPL|MCREATE, "") < 0) sysfatal("mount %s: %r", defmnt); } } #endif threadexits(0); }
void threadmain(int argc, char *argv[]) { char *q; char *srvname; char *mntpt; int list; mntpt = "/mnt"; user = strdup(getuser()); srvname = nil; list = 0; // mainmem->flags |= POOL_NOREUSE; ARGBEGIN{ case 'l': list = 1; break; case 'm': mntpt = ARGF(); break; case 'd': debug = strtoul(ARGF(), nil, 0); break; case 's': srvname = ARGF(); break; case 'f': fflag = 1; break; default: fprint(2, usage, argv0); exits("usage"); }ARGEND switch (argc) { default: fprint(2, usage, argv0); exits("usage"); case 0: mapname = DEFAULTMAP; break; case 1: mapname = argv[0]; break; } quotefmtinstall(); if((f = Bopen(mapname, OREAD)) == nil) sysfatal("%s: %r", mapname); free(file); file = strdup(mapname); free(startdir); startdir = strdup(mapname); if ((q = strrchr(startdir, '/'))) *q = '\0'; else startdir[0] = '\0'; inittokenlist(); getobject(Root, nil); Bterm(f); f = nil; root->parent = root; if(list){ listfiles(root); threadexits(nil); } if(pipe(p) < 0) sysfatal("pipe failed: %r"); mfd[0] = p[0]; mfd[1] = p[0]; threadnotify(robusthandler, 1); user = strdup(getuser()); if(debug) fmtinstall('F', fcallfmt); procrfork(io, nil, STACKSIZE, RFFDG); //RFNOTEG? close(p[0]); /* don't deadlock if child fails */ if(srvname){ srvname = smprint("/srv/jukefs.%s", srvname); remove(srvname); post(srvname, "jukefs", p[1]); } if(mount(p[1], -1, mntpt, MBEFORE, "") < 0) sysfatal("mount failed: %r"); threadexits(nil); }