Пример #1
0
Файл: fsys.c Проект: npe9/harvey
static
Xfid*
fsysclunk(Xfid *x, Fid *f)
{
    fsysdelid(f->mntdir);
    sendp(x->c, xfidclose);
    return nil;
}
Пример #2
0
Файл: fsys.c Проект: npe9/harvey
/*
 * Called only in exec.c:/^run(), from a different FD group
 */
Mntdir*
fsysmount(Rune *dir, int ndir, Rune **incl, int nincl)
{
    char buf[256];
    Mntdir *m;

    /* close server side so don't hang if acme is half-exited */
    close(sfd);
    m = fsysaddid(dir, ndir, incl, nincl);
    sprint(buf, "%d", m->id);
    if(mount(cfd, -1, "/mnt/acme", MREPL, buf) < 0) {
        fsysdelid(m);
        return nil;
    }
    close(cfd);
    bind("/mnt/acme", "/mnt/wsys", MREPL);
    if(bind("/mnt/acme", "/dev", MBEFORE) < 0) {
        fsysdelid(m);
        return nil;
    }
    return m;
}
Пример #3
0
/* called while row is locked */
void
flushwarnings(void)
{
	Warning *warn, *next;
	Window *w;
	Text *t;
	int owner, nr, q0, n;
	Rune *r;

	for(warn=warnings; warn; warn=next) {
		w = errorwin(warn->md, 'E');
		t = &w->body;
		owner = w->owner;
		if(owner == 0)
			w->owner = 'E';
		wincommit(w, t);
		/*
		 * Most commands don't generate much output. For instance,
		 * Edit ,>cat goes through /dev/cons and is already in blocks
		 * because of the i/o system, but a few can.  Edit ,p will
		 * put the entire result into a single hunk.  So it's worth doing
		 * this in blocks (and putting the text in a buffer in the first
		 * place), to avoid a big memory footprint.
		 */
		r = fbufalloc();
		q0 = t->file->nc;
		for(n = 0; n < warn->buf.nc; n += nr){
			nr = warn->buf.nc - n;
			if(nr > RBUFSIZE)
				nr = RBUFSIZE;
			bufread(&warn->buf, n, r, nr);
			textbsinsert(t, t->file->nc, r, nr, TRUE, &nr);
		}
		textshow(t, q0, t->file->nc, 1);
		free(r);
		winsettag(t->w);
		textscrdraw(t);
		w->owner = owner;
		w->dirty = FALSE;
		winunlock(w);
		bufclose(&warn->buf);
		next = warn->next;
		if(warn->md)
			fsysdelid(warn->md);
		free(warn);
	}
	warnings = nil;
}
Пример #4
0
Файл: fsys.c Проект: npe9/harvey
static
Xfid*
fsyswalk(Xfid *x, Fid *f)
{
    Fcall t;
    int c, i, j, id;
    Qid q;
    uint8_t type;
    uint32_t path;
    Fid *nf;
    Dirtab *d, *dir;
    Window *w;
    char *err;

    nf = nil;
    w = nil;
    if(f->open)
        return respond(x, &t, "walk of open file");
    if(x->fid != x->newfid) {
        nf = newfid(x->newfid);
        if(nf->busy)
            return respond(x, &t, "newfid already in use");
        nf->busy = TRUE;
        nf->open = FALSE;
        nf->mntdir = f->mntdir;
        if(f->mntdir)
            f->mntdir->ref++;
        nf->dir = f->dir;
        nf->qid = f->qid;
        nf->w = f->w;
        nf->nrpart = 0;	/* not open, so must be zero */
        if(nf->w)
            incref(nf->w);
        f = nf;	/* walk f */
    }

    t.nwqid = 0;
    err = nil;
    dir = nil;
    id = WIN(f->qid);
    q = f->qid;

    if(x->nwname > 0) {
        for(i=0; i<x->nwname; i++) {
            if((q.type & QTDIR) == 0) {
                err = Enotdir;
                break;
            }

            if(strcmp(x->wname[i], "..") == 0) {
                type = QTDIR;
                path = Qdir;
                id = 0;
                if(w) {
                    winclose(w);
                    w = nil;
                }
Accept:
                if(i == MAXWELEM) {
                    err = "name too long";
                    break;
                }
                q.type = type;
                q.vers = 0;
                q.path = QID(id, path);
                t.wqid[t.nwqid++] = q;
                continue;
            }

            /* is it a numeric name? */
            for(j=0; (c=x->wname[i][j]); j++)
                if(c<'0' || '9'<c)
                    goto Regular;
            /* yes: it's a directory */
            if(w)	/* name has form 27/23; get out before losing w */
                break;
            id = atoi(x->wname[i]);
            qlock(&row);
            w = lookid(id, FALSE);
            if(w == nil) {
                qunlock(&row);
                break;
            }
            incref(w);	/* we'll drop reference at end if there's an error */
            path = Qdir;
            type = QTDIR;
            qunlock(&row);
            dir = dirtabw;
            goto Accept;

Regular:
//			if(FILE(f->qid) == Qacme)	/* empty directory */
//				break;
            if(strcmp(x->wname[i], "new") == 0) {
                if(w)
                    error("w set in walk to new");
                sendp(cnewwindow, nil);	/* signal newwindowthread */
                w = recvp(cnewwindow);	/* receive new window */
                incref(w);
                type = QTDIR;
                path = QID(w->id, Qdir);
                id = w->id;
                dir = dirtabw;
                goto Accept;
            }

            if(id == 0)
                d = dirtab;
            else
                d = dirtabw;
            d++;	/* skip '.' */
            for(; d->name; d++)
                if(strcmp(x->wname[i], d->name) == 0) {
                    path = d->qid;
                    type = d->type;
                    dir = d;
                    goto Accept;
                }

            break;	/* file not found */
        }

        if(i==0 && err == nil)
            err = Eexist;
    }

    if(err!=nil || t.nwqid<x->nwname) {
        if(nf) {
            nf->busy = FALSE;
            fsysdelid(nf->mntdir);
        }
    } else if(t.nwqid  == x->nwname) {
        if(w) {
            f->w = w;
            w = nil;	/* don't drop the reference */
        }
        if(dir)
            f->dir = dir;
        f->qid = q;
    }

    if(w != nil)
        winclose(w);

    return respond(x, &t, err);
}
Пример #5
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;
		}
	}
}