Ejemplo n.º 1
0
static void
execproc(void *a)
{
	int i, fd;
	Client *c;
	char tmp[32];

	c = a;
	snprint(tmp, sizeof tmp, "execproc%d", c->num);
	threadsetname(tmp);
	if(pipe(c->fd) < 0){
		rerrstr(c->err, sizeof c->err);
		sendul(c->execpid, -1);
		return;
	}
	rfork(RFFDG);
	fd = c->fd[1];
	close(c->fd[0]);
	dup(fd, 0);
	dup(fd, 1);
	for(i=3; i<100; i++)	/* should do better */
		close(i);
	strcpy(c->err, "exec failed");
	procexecl(c->execpid, "/bin/rc", "rc", "-c", c->cmd, nil);
}
Ejemplo n.º 2
0
static int
wait4data(Serialport *p, uchar *data, int count)
{
    int d;
    Serial *ser;

    ser = p->s;

    qunlock(ser);
    d = sendul(p->w4data, 1);
    qlock(ser);
    if(d <= 0)
        return -1;
    if(p->ndata >= count)
        p->ndata -= count;
    else {
        count = p->ndata;
        p->ndata = 0;
    }
    memmove(data, p->data, count);
    if(p->ndata != 0)
        memmove(p->data, p->data+count, p->ndata);
    recvul(p->gotdata);
    return count;
}
Ejemplo n.º 3
0
static void
icachewriteproc(void *v)
{
	int ret;
	uint bsize;
	ISect *is;
	Index *ix;
	u8int *buf;

	ix = mainindex;
	is = v;
	threadsetname("icachewriteproc:%s", is->part->name);

	bsize = 1<<is->blocklog;
	buf = emalloc(Bufsize+bsize);
	buf = (u8int*)(((uintptr)buf+bsize-1)&~(uintptr)(bsize-1));

	for(;;){
		trace(TraceProc, "icachewriteproc recv");
		recv(is->writechan, 0);
		trace(TraceWork, "start");
		ret = icachewritesect(ix, is, buf);
		trace(TraceProc, "icachewriteproc send");
		trace(TraceWork, "finish");
		sendul(is->writedonechan, ret);
	}
}
Ejemplo n.º 4
0
static void
writeproc(void *v)
{
	Channel *sync;
	void **a;
	char *s;
	long np;
	int fd, i, n;

	threadsetname("writeproc");
	a = v;
	sync = a[0];
	fd = (uintptr)a[1];
	s = a[2];
	np =(uintptr)a[3];
	free(a);

	for(i=0; i<np; i+=n){
		n = np-i;
		if(n > BUFSIZE)
			n = BUFSIZE;
		if(write(fd, s+i, n) != n)
			break;
	}
	close(fd);
	sendul(sync, i);
}
Ejemplo n.º 5
0
void
winshell(void *args)
{
	print_func_entry();
	Window *w;
	Channel *pidc;
	void **arg;
	char *cmd, *dir;
	char **argv;

	arg = args;
	w = arg[0];
	pidc = arg[1];
	cmd = arg[2];
	argv = arg[3];
	dir = arg[4];
	rfork(RFNAMEG|RFFDG|RFENVG);
	if(filsysmount(filsys, w->id) < 0){
		fprint(2, "mount failed: %r\n");
		sendul(pidc, 0);
		threadexits("mount failed");
	}
	close(0);
	if(open("/dev/cons", OREAD) < 0){
		fprint(2, "can't open /dev/cons: %r\n");
		sendul(pidc, 0);
		threadexits("/dev/cons");
	}
	close(1);
	if(open("/dev/cons", OWRITE) < 0){
		fprint(2, "can't open /dev/cons: %r\n");
		sendul(pidc, 0);
		threadexits("open");	/* BUG? was terminate() */
	}
	if(wclose(w) == 0){	/* remove extra ref hanging from creation */
		notify(nil);
		dup(1, 2);
		if(dir)
			chdir(dir);
		procexec(pidc, cmd, argv);
		_exits("exec failed");
	}
	print_func_exit();
}
Ejemplo n.º 6
0
void
clockproc(void *arg)
{
	int t;
	Channel *c;

	c = arg;
	for(t=0;; t++){
		sleep(1000);
		sendul(c, t);
	}
}
Ejemplo n.º 7
0
int
sendstr(int sock,char *s)
{
  size_t len = s ? strlen(s) : 0;

  DLOG_MSG(("sendstr() : sendul(%d,%lu)",sock,(unsigned long)len));
  if (!sendul(sock,(unsigned long)len))
    return 0;
  if (len > 0) {
    DLOG_MSG(("sendstr() : x_send(%d,%s)",sock,s));
    if (!x_send(sock,s,len)) {
      DLOG_ERROR(("sendstr()"));
      return 0;
    }
  }
  return 1;
}
Ejemplo n.º 8
0
static void
bloomwriteproc(void *v)
{
	int ret;
	Bloom *b;

	threadsetname("bloomwriteproc");	
	b = v;
	for(;;){
		recv(b->writechan, 0);
		if((ret=writebloom(b)) < 0)
			fprint(2, "oops! writing bloom: %r\n");
		else
			ret = 0;
		sendul(b->writedonechan, ret);
	}
}
Ejemplo n.º 9
0
Archivo: ftdi.c Proyecto: 99years/plan9
static void
statusreader(void *u)
{
	Areader *a;
	Channel *c;
	Packser *pk;
	Serialport *p;
	Serial *ser;
	int cl;

	p = u;
	ser = p->s;
	threadsetname("statusreader thread");
	/* big buffering, fewer bytes lost */
	c = chancreate(sizeof(Packser *), 128);
	a = emallocz(sizeof(Areader), 1);
	a->p = p;
	a->c = c;
	incref(ser->dev);
	proccreate(epreader, a, 16*1024);

	while((pk = recvp(c)) != nil){
		memmove(p->data, pk->b, pk->nb);
		p->ndata = pk->nb;
		free(pk);
		dsprint(2, "serial %p: status reader %d \n", p, p->ndata);
		/* consume it all */
		while(p->ndata != 0){
			dsprint(2, "serial %p: status reader to consume: %d\n",
				p, p->ndata);
			cl = recvul(p->w4data);
			if(cl  < 0)
				break;
			cl = sendul(p->gotdata, 1);
			if(cl  < 0)
				break;
		}
	}

	shutdownchan(c);
	devctl(ser->dev, "detach");
	closedev(ser->dev);
	usbfsdel(&p->fs);
}
Ejemplo n.º 10
0
/* We can't use procexec to execute drivers, because
 * procexec mounts #| at /mnt/temp and we do *not*
 * have /mnt/temp at boot time.
 * Instead, we use access to guess if we can execute the file.
 * and reply as procexec. Be careful that the child inherits
 * all the shared state of the thread library. It should run unnoticed.
 */
static void
xexec(Channel *c, char *nm, char *args[])
{
	int	pid;

	if(access(nm, AEXEC) == 0){
		pid = rfork(RFFDG|RFREND|RFPROC);
		switch(pid){
		case 0:
			exec(nm, args);
			_exits("exec");
		case -1:
			break;
		default:
			sendul(c, pid);
			threadexits(nil);
		}
	}
}
Ejemplo n.º 11
0
void
execproc(void *v)
{
	struct Exec *e;
	int p[2], q[2];
	char *prog;
	char *argv[NARGS+1], args[NARGCHAR];

	e = v;
	p[0] = e->p[0];
	p[1] = e->p[1];
	q[0] = e->q[0];
	q[1] = e->q[1];
	prog = e->prog;	/* known not to be malloc'ed */
	rfork(RFFDG);
	sendul(e->sync, 1);
	buildargv(e->argv, argv, args);
	free(e->argv);
	chanfree(e->sync);
	free(e);
	dup(p[0], 0);
	close(p[0]);
	close(p[1]);
	if(q[0]){
		dup(q[1], 1);
		close(q[0]);
		close(q[1]);
	}
	procexec(nil, prog, argv);
//fprint(2, "exec: %s", e->prog);
//{int i;
//for(i=0; argv[i]; i++) print(" '%s'", argv[i]);
//print("\n");
//}
//argv[0] = "cat";
//argv[1] = nil;
//procexec(nil, "/bin/cat", argv);
	fprint(2, "Mail: can't exec %s: %r\n", prog);
	threadexits("can't exec");
}
Ejemplo n.º 12
0
void
execproc(void *v)
{
	struct Exec *e;
	int p[2], q[2];
	char *prog;
	char *argv[NARGS+1], args[NARGCHAR];
	int fd[3];

	e = v;
	p[0] = e->p[0];
	p[1] = e->p[1];
	q[0] = e->q[0];
	q[1] = e->q[1];
	prog = e->prog;	/* known not to be malloc'ed */
	
	fd[0] = dup(p[0], -1);
	if(q[0])
		fd[1] = dup(q[1], -1);
	else
		fd[1] = dup(1, -1);
	fd[2] = dup(2, -2);
	sendul(e->sync, 1);
	buildargv(e->argv, argv, args);
	free(e->argv);
	chanfree(e->sync);
	free(e);
	
	threadexec(nil, fd, prog, argv);
	close(fd[0]);
	close(fd[1]);
	close(fd[2]);

	fprint(2, "Mail: can't exec %s: %r\n", prog);
	threadexits("can't exec");
}
Ejemplo n.º 13
0
Archivo: exec.c Proyecto: 99years/plan9
void
procexec(Channel *pidc, char *prog, char *args[])
{
	int n;
	Proc *p;
	Thread *t;

	_threaddebug(DBGEXEC, "procexec %s", prog);
	/* must be only thread in proc */
	p = _threadgetproc();
	t = p->thread;
	if(p->threads.head != t || p->threads.head->nextt != nil){
		werrstr("not only thread in proc");
	Bad:
		if(pidc)
			sendul(pidc, ~0);
		return;
	}

	/*
	 * We want procexec to behave like exec; if exec succeeds,
	 * never return, and if it fails, return with errstr set.
	 * Unfortunately, the exec happens in another proc since
	 * we have to wait for the exec'ed process to finish.
	 * To provide the semantics, we open a pipe with the 
	 * write end close-on-exec and hand it to the proc that
	 * is doing the exec.  If the exec succeeds, the pipe will
	 * close so that our read below fails.  If the exec fails,
	 * then the proc doing the exec sends the errstr down the
	 * pipe to us.
	 */
	if(bind("#|", PIPEMNT, MREPL) < 0)
		goto Bad;
	if((p->exec.fd[0] = open(PIPEMNT "/data", OREAD)) < 0){
		unmount(nil, PIPEMNT);
		goto Bad;
	}
	if((p->exec.fd[1] = open(PIPEMNT "/data1", OWRITE|OCEXEC)) < 0){
		close(p->exec.fd[0]);
		unmount(nil, PIPEMNT);
		goto Bad;
	}
	unmount(nil, PIPEMNT);

	/* exec in parallel via the scheduler */
	assert(p->needexec==0);
	p->exec.prog = prog;
	p->exec.args = args;
	p->needexec = 1;
	_sched();

	close(p->exec.fd[1]);
	if((n = read(p->exec.fd[0], p->exitstr, ERRMAX-1)) > 0){	/* exec failed */
		p->exitstr[n] = '\0';
		errstr(p->exitstr, ERRMAX);
		close(p->exec.fd[0]);
		goto Bad;
	}
	close(p->exec.fd[0]);

	if(pidc)
		sendul(pidc, t->ret);

	/* wait for exec'ed program, then exit */
	_schedexecwait();
}
Ejemplo n.º 14
0
static void
startdevproc(void *a)
{
	Sarg	*sa = a;
	Dev	*d;
	Devtab *dt;
	int	argc;
	char *args, *argse, **argv;
	char *fname;

	threadsetgrp(threadid());
	d = sa->pp->dev;
	dt = sa->dt;
	args = sa->args;
	argse = sa->args + sizeof sa->args;
	argv = sa->argv;
	fname = sa->fname;
	sa->pp->devmaskp = &dt->devmask;
	sa->pp->devnb = getdevnb(&dt->devmask);
	if(sa->pp->devnb < 0){
		sa->pp->devmaskp = nil;
		sa->pp->devnb = 0;
	}else
		args = seprint(args, argse, "-N %d", sa->pp->devnb);
	if(dt->args != nil)
		seprint(args, argse, " %s", dt->args);
	args = sa->args;
	dprint(2, "%s: start: %s %s\n", argv0, dt->name, args);
	argv[0] = dt->name;
	argc = 1;
	if(args[0] != 0)
		argc += tokenize(args, argv+1, nelem(sa->argv)-2);
	argv[argc] = nil;
	if(dt->init == nil){
		if(d->dfd > 0 ){
			close(d->dfd);
			d->dfd = -1;
		}
		rfork(RFCFDG);
		open("/dev/null", OREAD);
		open("/dev/cons", OWRITE);
		open("/dev/cons", OWRITE);

		xexec(sa->rc, argv[0], argv);
		snprint(fname, sizeof(sa->fname), "/bin/usb/%s", dt->name);
		xexec(sa->rc, fname, argv);
		snprint(fname, sizeof(sa->fname), "/boot/%s", dt->name);
		xexec(sa->rc, fname, argv);
		if(cputype == nil)
			cputype = getenv("cputype");
		if(cputype != nil){
			snprint(fname, sizeof(sa->fname), "/%s/bin/%s",
				cputype, dt->name);
			argv[0] = fname;
			xexec(sa->rc, fname, argv);
		}
		fprint(2, "%s: %s: not found. can't exec\n", argv0, dt->name);
		sendul(sa->rc, -1);
		threadexits("exec");
	}else{
		sa->pp->dev = opendev(d->dir);
		sendul(sa->rc, 0);
		if(dt->init(d, argc, argv) < 0)
			fprint(2, "%s: %s: %r\n", argv0, dt->name);
		closedev(d);
		free(sa);
	}
	threadexits(nil);
}
Ejemplo n.º 15
0
void
waitthread(void *v)
{
	Waitmsg *w;
	Command *c, *lc;
	uint pid;
	int found, ncmd;
	Rune *cmd;
	char *err;
	Text *t;
	Pid *pids, *p, *lastp;
	enum { WErr, WKill, WWait, WCmd, NWALT };
	Alt alts[NWALT+1];

	USED(v);
	threadsetname("waitthread");
	pids = nil;
	alts[WErr].c = cerr;
	alts[WErr].v = &err;
	alts[WErr].op = CHANRCV;
	alts[WKill].c = ckill;
	alts[WKill].v = &cmd;
	alts[WKill].op = CHANRCV;
	alts[WWait].c = cwait;
	alts[WWait].v = &w;
	alts[WWait].op = CHANRCV;
	alts[WCmd].c = ccommand;
	alts[WCmd].v = &c;
	alts[WCmd].op = CHANRCV;
	alts[NWALT].op = CHANEND;

	command = nil;
	for(;;){
		switch(alt(alts)){
		case WErr:
			qlock(&row.lk);
			warning(nil, "%s", err);
			free(err);
			flushimage(display, 1);
			qunlock(&row.lk);
			break;
		case WKill:
			found = FALSE;
			ncmd = runestrlen(cmd);
			for(c=command; c; c=c->next){
				/* -1 for blank */
				if(runeeq(c->name, c->nname-1, cmd, ncmd) == TRUE){
					if(postnote(PNGROUP, c->pid, "kill") < 0)
						warning(nil, "kill %S: %r\n", cmd);
					found = TRUE;
				}
			}
			if(!found)
				warning(nil, "Kill: no process %S\n", cmd);
			free(cmd);
			break;
		case WWait:
			pid = w->pid;
			lc = nil;
			for(c=command; c; c=c->next){
				if(c->pid == pid){
					if(lc)
						lc->next = c->next;
					else
						command = c->next;
					break;
				}
				lc = c;
			}
			qlock(&row.lk);
			t = &row.tag;
			textcommit(t, TRUE);
			if(c == nil){
				/* helper processes use this exit status */
				if(strncmp(w->msg, "libthread", 9) != 0){
					p = emalloc(sizeof(Pid));
					p->pid = pid;
					strncpy(p->msg, w->msg, sizeof(p->msg));
					p->next = pids;
					pids = p;
				}
			}else{
				if(search(t, c->name, c->nname)){
					textdelete(t, t->q0, t->q1, TRUE);
					textsetselect(t, 0, 0);
				}
				if(w->msg[0])
					warning(c->md, "%.*S: exit %s\n", c->nname-1, c->name, w->msg);
				flushimage(display, 1);
			}
			qunlock(&row.lk);
			free(w);
    Freecmd:
			if(c){
				if(c->iseditcmd)
					sendul(cedit, 0);
				free(c->text);
				free(c->name);
				fsysdelid(c->md);
				free(c);
			}
			break;
		case WCmd:
			/* has this command already exited? */
			lastp = nil;
			for(p=pids; p!=nil; p=p->next){
				if(p->pid == c->pid){
					if(p->msg[0])
						warning(c->md, "%s\n", p->msg);
					if(lastp == nil)
						pids = p->next;
					else
						lastp->next = p->next;
					free(p);
					goto Freecmd;
				}
				lastp = p;
			}
			c->next = command;
			command = c;
			qlock(&row.lk);
			t = &row.tag;
			textcommit(t, TRUE);
			textinsert(t, 0, c->name, c->nname, TRUE);
			textsetselect(t, 0, 0);
			flushimage(display, 1);
			qunlock(&row.lk);
			break;
		}
	}
}