Пример #1
0
static void
icachewritecoord(void *v)
{
	int i, err;
	Index *ix;
	AState as;

	USED(v);

	threadsetname("icachewritecoord");

	ix = mainindex;
	iwrite.as = icachestate();

	for(;;){
		trace(TraceProc, "icachewritecoord sleep");
		waitforkick(&iwrite.round);
		trace(TraceWork, "start");
		as = icachestate();
		if(as.arena==iwrite.as.arena && as.aa==iwrite.as.aa){
			/* will not be able to do anything more than last flush - kick disk */
			trace(TraceProc, "icachewritecoord kick dcache");
			kickdcache();
			trace(TraceProc, "icachewritecoord kicked dcache");
			goto SkipWork;	/* won't do anything; don't bother rewriting bloom filter */
		}
		iwrite.as = as;

		trace(TraceProc, "icachewritecoord start flush");
		if(iwrite.as.arena){
			for(i=0; i<ix->nsects; i++)
				send(ix->sects[i]->writechan, 0);
			if(ix->bloom)
				send(ix->bloom->writechan, 0);
		
			err = 0;
			for(i=0; i<ix->nsects; i++)
				err |= recvul(ix->sects[i]->writedonechan);
			if(ix->bloom)
				err |= recvul(ix->bloom->writedonechan);

			trace(TraceProc, "icachewritecoord donewrite err=%d", err);
			if(err == 0){
				setatailstate(&iwrite.as);
			}
		}
	SkipWork:
		icacheclean(nil);	/* wake up anyone waiting */
		trace(TraceWork, "finish");
		addstat(StatIcacheFlush, 1);
	}
}
Пример #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;
}
Пример #3
0
/*
 * Receives message string from the network and
 * returns the appropriate numeric token.  If error
 * occurs -1 is returned.
 */
int
recvmstr(int sock,char **s)
{
  char buf[MAX_MSGSTR + 1];
  unsigned long ultmp;
  int i;
  size_t len;

  DLOG_MSG(("recvmstr() : recvul(%d)",sock));
  if (!recvul(sock,&ultmp))
    return -1;
  len = (size_t)ultmp;
  if (len == 0 || len > MAX_MSGSTR) {
    errlog(LOG_ERR,"recvmstr() : len=%lu",(unsigned long)len);
    return -1;
  }
  DLOG_MSG(("recvmstr() : x_recv(%d)",sock));
  if (!x_recv(sock,buf,len)) {
    DLOG_ERROR(("recvstr()"));
    return -1;
  }
  buf[len] = '\0';
  DLOG_MSG(("recvstr() : buf=%s",buf));
  for (i = 0; s[i]; i++)
    if (streql(s[i],buf)) return i;
  errlog(LOG_ERR,"recvmstr() : unknown message (%s)",buf);
  return -1;
}
Пример #4
0
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);
	}
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
int
confirmkey(Conv *c, Key *k)
{
	int ret;

	if(*confirminuse == 0)
		return -1;

	lbappend(&confbuf, "confirm tag=%lud %A %N", c->tag, k->attr, k->privattr);
	flog("confirm %A %N", k->attr, k->privattr);
	c->state = "keyconfirm";
	ret = recvul(c->keywait);
	flog("confirm=%d %A %N", ret, k->attr, k->privattr);
	return ret;
}
Пример #8
0
int
threadspawn(int fd[3], char *cmd, char *argv[])
{
	int pid;
	Execjob e;

	e.fd = fd;
	e.cmd = cmd;
	e.argv = argv;
	e.c = chancreate(sizeof(void*), 0);
	proccreate(execproc, &e, 65536);
	close(fd[0]);
	close(fd[1]);
	close(fd[2]);
	pid = recvul(e.c);
	chanfree(e.c);
	return pid;
}
Пример #9
0
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);
}
Пример #10
0
Файл: main.c Проект: npe9/harvey
void
startcmd(char *argv[], int *notepg)
{
	struct Exec *e;
	Channel *cpid;
	char buf[64];
	int pid;

	e = emalloc(sizeof(struct Exec));
	e->argv = argv;
	cpid = chancreate(sizeof(uint32_t), 0);
	e->cpid = cpid;
	sprint(buf, "/mnt/wsys/%d", win->id);
	bind(buf, "/dev/acme", MREPL);
	proccreate(execproc, e, EXECSTACK);
	do
		pid = recvul(cpid);
	while(pid == -1);
	sprint(buf, "/proc/%d/notepg", pid);
	*notepg = open(buf, OWRITE);
}
Пример #11
0
/*
 * Receives string from network (length info comes first) and
 * returns an allocated buffer containing the string and its length
 * (len will be in the same form as when returned by strlen(), i.e.,
 * excluding the null terminator).  If len is zero, the string
 * was empty in which case strorage will not be allocated
 * and the actual x_recv() for the string is not performed.
 * If the string buffer passed to recvstr() was not empty (i.e.,
 * the pointer to it was not null) it is freed first.
 */
int
recvstr(int sock,char **s,size_t *len)
{
  unsigned long ultmp;

  DLOG_MSG(("recvstr() : recvul(%d)",sock));
  if (!recvul(sock,&ultmp))
    return 0;
  *len = (size_t)ultmp;
  if (*s) x_free(*s);
  if (*len > 0) {
    DLOG_MSG(("recvstr() : x_recv(%d)",sock));
    *s = (char *)x_malloc(*len + 1);
    if (!x_recv(sock,*s,*len)) {
      DLOG_ERROR(("recvstr()"));
      return 0;
    }
    DLOG_MSG(("recvstr() : *s=%s",*s));
  }
  else
    *s = (char *)0;
  return 1;
}
Пример #12
0
char *
tcs(char *cs, char *s, long *np)
{
	Channel *sync;
	Exec *e;
	Rune r;
	long i, n;
	void **a;
	uchar *us;
	char buf[BUFSIZE], cmd[50];
	char *t, *u;
	int p[2], q[2];


	if(s==nil || *s=='\0' || *np==0){
		werrstr("tcs failed: no data");
		return s;
	}

	if(cs == nil){
		werrstr("tcs failed: no charset");
		return s;
	}

	if(cistrncmp(cs, "utf-8", 5)==0 || cistrncmp(cs, "utf8", 4)==0)
		return s;

	for(i=0; tcstab[i].mime!=nil; i++)
		if(cistrncmp(cs, tcstab[i].mime, strlen(tcstab[i].mime)) == 0)
			break;

	if(tcstab[i].mime == nil){
		fprint(2, "abaco: charset: %s not supported\n", cs);
		goto latin1;
	}
	if(cistrcmp(tcstab[i].tcs, "8859-1")==0 || cistrcmp(tcstab[i].tcs, "ascii")==0){
latin1:
		n = 0;
		for(us=(uchar*)s; *us; us++)
			n += runelen(*us);
		n++;
		t = emalloc(n);
		for(us=(uchar*)s, u=t; *us; us++){
			if(*us>=Winstart && *us<=Winend)
				*u++ = winchars[*us-Winstart];
			else{
				r = *us;
				u += runetochar(u, &r);
			}
		}
		*u = 0;
		free(s);
		return t;
	}

	if(pipe(p)<0 || pipe(q)<0)
		error("can't create pipe");

	sync = chancreate(sizeof(ulong), 0);
	if(sync == nil)
		error("can't create channel");

	snprint(cmd, sizeof cmd, "tcs -f %s", tcstab[i].tcs);
	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 = cmd;
	e->sync = sync;
	proccreate(execproc, e, STACK);
	recvul(sync);
	chanfree(sync);
	close(p[0]);
	close(q[1]);

	/* in case tcs fails */
	t = s;
	sync = chancreate(sizeof(ulong), 0);
	if(sync == nil)
		error("can't create channel");

	a = emalloc(4*sizeof(void *));
	a[0] = sync;
	a[1] = (void *)p[1];
	a[2] = s;
	a[3] = (void *)*np;
	proccreate(writeproc, a, STACK);

	s = nil;
	while((n = read(q[0], buf, sizeof(buf))) > 0){
		s = erealloc(s, i+n+1);
		memmove(s+i, buf, n);
		i += n;
		s[i] = '\0';
	}
	n = recvul(sync);
	if(n != *np)
		fprint(2, "tcs: did not write %ld; wrote %uld\n", *np, n);

	*np = i;
	chanfree(sync);
	close(q[0]);

	if(s == nil){
		fprint(2, "tcs failed: can't convert charset=%s to %s\n", cs, tcstab[i].tcs);
		return t;
	}
	free(t);

	return s;
}
Пример #13
0
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;
}
Пример #14
0
void
mesgsend(Message *m)
{
	char *s, *body, *to;
	int i, j, h, n, natt, p[2];
	struct Exec *e;
	Channel *sync;
	int first, nfld, delit, ofd;
	char *copy, *fld[100], *now;

	body = winreadbody(m->w, &n);
	/* assemble to: list from first line, to: line, and cc: line */
	nto = 0;
	natt = 0;
	ncc = 0;
	nbcc = 0;
	first = 1;
	to = body;
	for(;;){
		for(s=to; *s!='\n'; s++)
			if(*s == '\0'){
				free(body);
				return;
			}
		if(s++ == to)	/* blank line */
			break;
		/* make copy of line to tokenize */
		copy = emalloc(s-to);
		memmove(copy, to, s-to);
		copy[s-to-1] = '\0';
		nfld = tokenizec(copy, fld, nelem(fld), ", \t");
		if(nfld == 0){
			free(copy);
			break;
		}
		n -= s-to;
		switch(h = whichheader(fld[0])){
		case TO:
		case FROM:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && nto<nelem(tolist); i++)
				if(!addressed(fld[i]))
					tolist[nto++] = estrdup(fld[i]);
			break;
		case BCC:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && nbcc<nelem(bcclist); i++)
				if(!addressed(fld[i]))
					bcclist[nbcc++] = estrdup(fld[i]);
			break;
		case CC:
			delit = 1;
			commas(to+strlen(fld[0]), s-1);
			for(i=1; i<nfld && ncc<nelem(cclist); i++)
				if(!addressed(fld[i]))
					cclist[ncc++] = estrdup(fld[i]);
			break;
		case ATTACH:
		case INCLUDE:
			delit = 1;
			for(i=1; i<nfld && natt<nelem(attlist); i++){
				attlist[natt] = estrdup(fld[i]);
				included[natt++] = (h == INCLUDE);
			}
			break;
		default:
			if(first){
				delit = 1;
				for(i=0; i<nfld && nto<nelem(tolist); i++)
					tolist[nto++] = estrdup(fld[i]);
			}else	/* ignore it */
				delit = 0;
			break;
		}
		if(delit){
			/* delete line from body */
			memmove(to, s, n+1);
		}else
			to = s;
		free(copy);
		first = 0;
	}

	ofd = open(outgoing, OWRITE|OCEXEC);	/* no error check necessary */
	if(ofd > 0){
		/* From dhog Fri Aug 24 22:13:00 EDT 2001 */
		now = ctime(time(0));
		seek(ofd, 0, 2);
		fprint(ofd, "From %s %s", user, now);
		fprint(ofd, "From: %s\n", user);
		fprint(ofd, "Date: %s", now);
		for(i=0; i<natt; i++)
			if(included[i])
				fprint(ofd, "Include: %s\n", attlist[i]);
			else
				fprint(ofd, "Attach: %s\n", attlist[i]);
		/* needed because mail is by default Latin-1 */
		fprint(ofd, "Content-Type: text/plain; charset=\"UTF-8\"\n");
		fprint(ofd, "Content-Transfer-Encoding: 8bit\n");
	}

	e = emalloc(sizeof(struct Exec));
	if(pipe(p) < 0)
		error("can't create pipe: %r");
	e->p[0] = p[0];
	e->p[1] = p[1];
	e->prog = unsharp("#9/bin/upas/marshal");
	e->argv = emalloc((1+1+2+4*natt+1)*sizeof(char*));
	e->argv[0] = estrdup("marshal");
	e->argv[1] = estrdup("-8");
	j = 2;
	if(m->replyname){
		e->argv[j++] = estrdup("-R");
		e->argv[j++] = estrstrdup(mbox.name, m->replyname);
	}
	for(i=0; i<natt; i++){
		if(included[i])
			e->argv[j++] = estrdup("-A");
		else
			e->argv[j++] = estrdup("-a");
		e->argv[j++] = estrdup(attlist[i]);
	}
	sync = chancreate(sizeof(int), 0);
	e->sync = sync;
	proccreate(execproc, e, EXECSTACK);
	recvul(sync);
	/* close(p[0]); */

	/* using marshal -8, so generate rfc822 headers */
	if(nto > 0){
		print2(p[1], ofd, "To: ");
		for(i=0; i<nto-1; i++)
			print2(p[1], ofd, "%s, ", tolist[i]);
		print2(p[1], ofd, "%s\n", tolist[i]);
	}
	if(ncc > 0){
		print2(p[1], ofd, "CC: ");
		for(i=0; i<ncc-1; i++)
			print2(p[1], ofd, "%s, ", cclist[i]);
		print2(p[1], ofd, "%s\n", cclist[i]);
	}
	if(nbcc > 0){
		print2(p[1], ofd, "BCC: ");
		for(i=0; i<nbcc-1; i++)
			print2(p[1], ofd, "%s, ", bcclist[i]);
		print2(p[1], ofd, "%s\n", bcclist[i]);
	}

	i = strlen(body);
	if(i > 0)
		write2(p[1], ofd, body, i, 1);

	/* guarantee a blank line, to ensure attachments are separated from body */
	if(i==0 || body[i-1]!='\n')
		write2(p[1], ofd, "\n\n", 2, 0);
	else if(i>1 && body[i-2]!='\n')
		write2(p[1], ofd, "\n", 1, 0);

	/* these look like pseudo-attachments in the "outgoing" box */
	if(ofd>0 && natt>0){
		for(i=0; i<natt; i++)
			if(included[i])
				fprint(ofd, "=====> Include: %s\n", attlist[i]);
			else
				fprint(ofd, "=====> Attach: %s\n", attlist[i]);
	}
	if(ofd > 0)
		write(ofd, "\n", 1);

	for(i=0; i<natt; i++)
		free(attlist[i]);
	close(ofd);
	close(p[1]);
	free(body);

	if(m->replyname != nil)
		mesgmenumark(mbox.w, m->replyname, "\t[replied]");
	if(m->name[0] == '/')
		s = estrdup(m->name);
	else
		s = estrstrdup(mbox.name, m->name);
	s = egrow(s, "-R", nil);
	winname(m->w, s);
	free(s);
	winclean(m->w);
	/* mark message unopened because it's no longer the original message */
	m->opened = 0;
}
Пример #15
0
void
threadmain(int argc, char *argv[])
{
	int i;
	char *p, *loadfile;
	Column *c;
	int ncol;
	Display *d;

	rfork(RFENVG|RFNAMEG);

	ncol = -1;

	loadfile = nil;
	ARGBEGIN{
	case 'D':
		{extern int _threaddebuglevel;
		_threaddebuglevel = ~0;
		}
		break;
	case 'a':
		globalautoindent = TRUE;
		break;
	case 'b':
		bartflag = TRUE;
		break;
	case 'c':
		p = ARGF();
		if(p == nil)
			goto Usage;
		ncol = atoi(p);
		if(ncol <= 0)
			goto Usage;
		break;
	case 'f':
		fontnames[0] = ARGF();
		if(fontnames[0] == nil)
			goto Usage;
		break;
	case 'F':
		fontnames[1] = ARGF();
		if(fontnames[1] == nil)
			goto Usage;
		break;
	case 'l':
		loadfile = ARGF();
		if(loadfile == nil)
			goto Usage;
		break;
	case 'm':
		mtpt = ARGF();
		if(mtpt == nil)
			goto Usage;
		break;
	case 'r':
		swapscrollbuttons = TRUE;
		break;
	case 'W':
		winsize = ARGF();
		if(winsize == nil)
			goto Usage;
		break;
	default:
	Usage:
		fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n");
		threadexitsall("usage");
	}ARGEND

	fontnames[0] = estrdup(fontnames[0]);
	fontnames[1] = estrdup(fontnames[1]);

	quotefmtinstall();
	fmtinstall('t', timefmt);

	cputype = getenv("cputype");
	objtype = getenv("objtype");
	home = getenv("HOME");
	acmeshell = getenv("acmeshell");
	if(acmeshell && *acmeshell == '\0')
		acmeshell = nil;
	p = getenv("tabstop");
	if(p != nil){
		maxtab = strtoul(p, nil, 0);
		free(p);
	}
	if(maxtab == 0)
		maxtab = 4;
	if(loadfile)
		rowloadfonts(loadfile);
	putenv("font", fontnames[0]);
	snarffd = open("/dev/snarf", OREAD|OCEXEC);
/*
	if(cputype){
		sprint(buf, "/acme/bin/%s", cputype);
		bind(buf, "/bin", MBEFORE);
	}
	bind("/acme/bin", "/bin", MBEFORE);
*/
	getwd(wdir, sizeof wdir);

/*
	if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){
		fprint(2, "acme: can't open display: %r\n");
		threadexitsall("geninitdraw");
	}
*/
	if(initdraw(derror, fontnames[0], "acme") < 0){
		fprint(2, "acme: can't open display: %r\n");
		threadexitsall("initdraw");
	}

	d = display;
	font = d->defaultfont;
/*assert(font); */

	reffont.f = font;
	reffonts[0] = &reffont;
	incref(&reffont.ref);	/* one to hold up 'font' variable */
	incref(&reffont.ref);	/* one to hold up reffonts[0] */
	fontcache = emalloc(sizeof(Reffont*));
	nfontcache = 1;
	fontcache[0] = &reffont;

	iconinit();
	timerinit();
	rxinit();

	cwait = threadwaitchan();
	ccommand = chancreate(sizeof(Command**), 0);
	ckill = chancreate(sizeof(Rune*), 0);
	cxfidalloc = chancreate(sizeof(Xfid*), 0);
	cxfidfree = chancreate(sizeof(Xfid*), 0);
	cnewwindow = chancreate(sizeof(Channel*), 0);
	cerr = chancreate(sizeof(char*), 0);
	cedit = chancreate(sizeof(int), 0);
	cexit = chancreate(sizeof(int), 0);
	cwarn = chancreate(sizeof(void*), 1);
	if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){
		fprint(2, "acme: can't create initial channels: %r\n");
		threadexitsall("channels");
	}
	chansetname(ccommand, "ccommand");
	chansetname(ckill, "ckill");
	chansetname(cxfidalloc, "cxfidalloc");
	chansetname(cxfidfree, "cxfidfree");
	chansetname(cnewwindow, "cnewwindow");
	chansetname(cerr, "cerr");
	chansetname(cedit, "cedit");
	chansetname(cexit, "cexit");
	chansetname(cwarn, "cwarn");

	mousectl = initmouse(nil, screen);
	if(mousectl == nil){
		fprint(2, "acme: can't initialize mouse: %r\n");
		threadexitsall("mouse");
	}
	mouse = &mousectl->m;
	keyboardctl = initkeyboard(nil);
	if(keyboardctl == nil){
		fprint(2, "acme: can't initialize keyboard: %r\n");
		threadexitsall("keyboard");
	}
	mainpid = getpid();
	startplumbing();
/*
	plumbeditfd = plumbopen("edit", OREAD|OCEXEC);
	if(plumbeditfd < 0)
		fprint(2, "acme: can't initialize plumber: %r\n");
	else{
		cplumb = chancreate(sizeof(Plumbmsg*), 0);
		threadcreate(plumbproc, nil, STACK);
	}
	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);
*/

	fsysinit();

	#define	WPERCOL	8
	disk = diskinit();
	if(!loadfile || !rowload(&row, loadfile, TRUE)){
		rowinit(&row, screen->clipr);
		if(ncol < 0){
			if(argc == 0)
				ncol = 2;
			else{
				ncol = (argc+(WPERCOL-1))/WPERCOL;
				if(ncol < 2)
					ncol = 2;
			}
		}
		if(ncol == 0)
			ncol = 2;
		for(i=0; i<ncol; i++){
			c = rowadd(&row, nil, -1);
			if(c==nil && i==0)
				error("initializing columns");
		}
		c = row.col[row.ncol-1];
		if(argc == 0)
			readfile(c, wdir);
		else
			for(i=0; i<argc; i++){
				p = utfrrune(argv[i], '/');
				if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol)
					readfile(c, argv[i]);
				else
					readfile(row.col[i/WPERCOL], argv[i]);
			}
	}
	flushimage(display, 1);

	acmeerrorinit();
	threadcreate(keyboardthread, nil, STACK);
	threadcreate(mousethread, nil, STACK);
	threadcreate(waitthread, nil, STACK);
	threadcreate(xfidallocthread, nil, STACK);
	threadcreate(newwindowthread, nil, STACK);
/*	threadcreate(shutdownthread, nil, STACK); */
	threadnotify(shutdown, 1);
	recvul(cexit);
	killprocs();
	threadexitsall(nil);
}
Пример #16
0
void
threadmain(int argc, char *argv[])
{
	int i;
	char *p, *loadfile;
	char buf[256];
	Column *c;
	int ncol;
	Display *d;
	static void *arg[1];

	rfork(RFENVG|RFNAMEG);

	ncol = -1;

	loadfile = nil;
	ARGBEGIN{
	case 'a':
		globalautoindent = TRUE;
		break;
	case 'b':
		bartflag = TRUE;
		break;
	case 'c':
		p = ARGF();
		if(p == nil)
			goto Usage;
		ncol = atoi(p);
		if(ncol <= 0)
			goto Usage;
		break;
	case 'f':
		fontnames[0] = ARGF();
		if(fontnames[0] == nil)
			goto Usage;
		break;
	case 'F':
		fontnames[1] = ARGF();
		if(fontnames[1] == nil)
			goto Usage;
		break;
	case 'l':
		loadfile = ARGF();
		if(loadfile == nil)
			goto Usage;
		break;
	default:
	Usage:
		fprint(2, "usage: acme [-ab] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
		exits("usage");
	}ARGEND

	if(fontnames[0] == nil)
		fontnames[0] = getenv("font");
	if(fontnames[0] == nil)
		fontnames[0] = "/lib/font/bit/vga/unicode.font";
	if(access(fontnames[0], 0) < 0){
		fprint(2, "acme: can't access %s: %r\n", fontnames[0]);
		exits("font open");
	}
	if(fontnames[1] == nil)
		fontnames[1] = fontnames[0];
	fontnames[0] = estrdup(fontnames[0]);
	fontnames[1] = estrdup(fontnames[1]);

	quotefmtinstall();
	cputype = getenv("cputype");
	objtype = getenv("objtype");
	home = getenv("home");
	p = getenv("tabstop");
	if(p != nil){
		maxtab = strtoul(p, nil, 0);
		free(p);
	}
	if(maxtab == 0)
		maxtab = 4; 
	if(loadfile)
		rowloadfonts(loadfile);
	putenv("font", fontnames[0]);
	snarffd = open("/dev/snarf", OREAD|OCEXEC);
	if(cputype){
		sprint(buf, "/acme/bin/%s", cputype);
		bind(buf, "/bin", MBEFORE);
	}
	bind("/acme/bin", "/bin", MBEFORE);
	getwd(wdir, sizeof wdir);

	if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){
		fprint(2, "acme: can't open display: %r\n");
		exits("geninitdraw");
	}
	d = display;
	font = d->defaultfont;

	reffont.f = font;
	reffonts[0] = &reffont;
	incref(&reffont);	/* one to hold up 'font' variable */
	incref(&reffont);	/* one to hold up reffonts[0] */
	fontcache = emalloc(sizeof(Reffont*));
	nfontcache = 1;
	fontcache[0] = &reffont;

	iconinit();
	timerinit();
	rxinit();

	cwait = threadwaitchan();
	ccommand = chancreate(sizeof(Command**), 0);
	ckill = chancreate(sizeof(Rune*), 0);
	cxfidalloc = chancreate(sizeof(Xfid*), 0);
	cxfidfree = chancreate(sizeof(Xfid*), 0);
	cnewwindow = chancreate(sizeof(Channel*), 0);
	cerr = chancreate(sizeof(char*), 0);
	cedit = chancreate(sizeof(int), 0);
	cexit = chancreate(sizeof(int), 0);
	cwarn = chancreate(sizeof(void*), 1);
	if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){
		fprint(2, "acme: can't create initial channels: %r\n");
		threadexitsall("channels");
	}

	mousectl = initmouse(nil, screen);
	if(mousectl == nil){
		fprint(2, "acme: can't initialize mouse: %r\n");
		threadexitsall("mouse");
	}
	mouse = mousectl;
	keyboardctl = initkeyboard(nil);
	if(keyboardctl == nil){
		fprint(2, "acme: can't initialize keyboard: %r\n");
		threadexitsall("keyboard");
	}
	mainpid = getpid();
	plumbeditfd = plumbopen("edit", OREAD|OCEXEC);
	if(plumbeditfd >= 0){
		cplumb = chancreate(sizeof(Plumbmsg*), 0);
		proccreate(plumbproc, nil, STACK);
	}
	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);

	fsysinit();

	#define	WPERCOL	8
	disk = diskinit();
	if(!loadfile || !rowload(&row, loadfile, TRUE)){
		rowinit(&row, screen->clipr);
		if(ncol < 0){
			if(argc == 0)
				ncol = 2;
			else{
				ncol = (argc+(WPERCOL-1))/WPERCOL;
				if(ncol < 2)
					ncol = 2;
			}
		}
		if(ncol == 0)
			ncol = 2;
		for(i=0; i<ncol; i++){
			c = rowadd(&row, nil, -1);
			if(c==nil && i==0)
				error("initializing columns");
		}
		c = row.col[row.ncol-1];
		if(argc == 0)
			readfile(c, wdir);
		else
			for(i=0; i<argc; i++){
				p = utfrrune(argv[i], '/');
				if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol)
					readfile(c, argv[i]);
				else
					readfile(row.col[i/WPERCOL], argv[i]);
			}
	}
	flushimage(display, 1);

	acmeerrorinit();
	threadcreate(keyboardthread, nil, STACK);
	threadcreate(mousethread, nil, STACK);
	threadcreate(waitthread, nil, STACK);
	threadcreate(xfidallocthread, nil, STACK);
	threadcreate(newwindowthread, nil, STACK);

	threadnotify(shutdown, 1);
	recvul(cexit);
	killprocs();
	threadexitsall(nil);
}
Пример #17
0
void
threadmain(int argc, char *argv[])
{
	Column *c;
	char buf[256];
	int i, ncol;

	rfork(RFENVG|RFNAMEG);

	ncol = 1;
	ARGBEGIN{
	case 'c':
		ncol = atoi(EARGF(usage()));
		if(ncol <= 0)
			usage();
		break;
	case 'm':
		webmountpt = EARGF(usage());
		break;
	case 'p':
		procstderr++;
		break;
	case 't':
		charset = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	snprint(buf, sizeof(buf), "%s/ctl", webmountpt);
	webctlfd = open(buf, ORDWR);
	if(webctlfd < 0)
		sysfatal("can't initialize webfs: %r");

	snarffd = open("/dev/snarf", OREAD|OCEXEC);

	if(initdraw(derror, fontnames[0], "abaco") < 0)
		sysfatal("can't open display: %r");
	memimageinit();
	iconinit();
	timerinit();
	initfontpaths();

	cexit = chancreate(sizeof(int), 0);
	crefresh = chancreate(sizeof(Page *), 0);
	if(cexit==nil || crefresh==nil)
		sysfatal("can't create initial channels: %r");

	mousectl = initmouse(nil, screen);
	if(mousectl == nil)
		sysfatal("can't initialize mouse: %r");
	mouse = mousectl;
	keyboardctl = initkeyboard(nil);
	if(keyboardctl == nil)
		sysfatal("can't initialize keyboard: %r");
	mainpid = getpid();
	plumbwebfd = plumbopen("web", OREAD|OCEXEC);
	if(plumbwebfd >= 0){
		cplumb = chancreate(sizeof(Plumbmsg*), 0);
		proccreate(plumbproc, nil, STACK);
	}
	plumbsendfd = plumbopen("send", OWRITE|OCEXEC);

	rowinit(&row, screen->clipr);
	for(i=0; i<ncol; i++){
		c = rowadd(&row, nil, -1);
		if(c==nil && i==0)
			error("initializing columns");
	}
	c = row.col[row.ncol-1];
	for(i=0; i<argc; i++)
		if(i/WPERCOL >= row.ncol)
			readpage(c, argv[i]);
		else
			readpage(row.col[i/WPERCOL], argv[i]);
	flushimage(display, 1);
	threadcreate(keyboardthread, nil, STACK);
	threadcreate(mousethread, nil, STACK);

	threadnotify(shutdown, 1);
	recvul(cexit);
	threadexitsall(nil);
}