Ejemplo n.º 1
0
static Walkqid*
devlogfswalk(Chan *c, Chan *nc, char **name, int nname)
{
	int instance, qid, qt, clone;
	Walkqid *wq;

#ifdef CALLTRACE
	print("devlogfswalk(c = 0x%.8lux, nc = 0x%.8lux, name = 0x%.8lux, nname = %d) - start\n",
		(ulong)c, (ulong)nc, (ulong)name, nname);
#endif
	clone = 0;
	if(nc == nil){
		nc = devclone(c);
		nc->type = 0;
		SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt);
		if(DATAQID(qid, qt))
			nc->aux = devlogfsget(instance);
		clone = 1;
	}
	wq = devwalk(c, nc, name, nname, 0, 0, devlogfsgen);
	if (wq == nil || wq->nqid < nname) {
		if(clone)
			cclose(nc);
	}
	else if (clone) {
		wq->clone = nc;
		nc->type = c->type;
	}
#ifdef CALLTRACE
	print("devlogfswalk(c = 0x%.8lux, nc = 0x%.8lux, name = 0x%.8lux, nname = %d) - return\n",
		(ulong)c, (ulong)nc, (ulong)name, nname);
#endif
	return wq;
}
Ejemplo n.º 2
0
static Chan *
powerclone(Chan *c, Chan *nc)
{
	Puser *p;

	nc = devclone(c, nc);
	if((p = nc->aux) != nil)
		incref(p);
	return nc;
}
Ejemplo n.º 3
0
static Walkqid*
fswalk(Chan *c, Chan *nc, char **name, int nname)
{
	int i;
	Path *path;
	Walkqid *wq;
	UnixFd *ufd;

	if(nc != nil)
		panic("fswalk: nc != nil");
	wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
	nc = devclone(c);
	fsclone(c, nc);
	ufd = c->aux;
	path = ufd->path;
	incref(&path->ref);

	wq->clone = nc;
	for(i=0; i<nname; i++){
		ufd = nc->aux;
		replacepath(nc, path);
		if(fswalk1(nc, name[i]) < 0){
			if(i == 0){
				pathclose(path);
				cclose(nc);
				free(wq);
				error(Enonexist);
			}
			break;
		}
		path = addelem(path, name[i], nil);
		wq->qid[i] = nc->qid;
	}
	replacepath(nc, path);
	pathclose(path);
	if(i != nname){
		cclose(nc);
		wq->clone = nil;
	}
	wq->nqid = i;
	return wq;
}
Ejemplo n.º 4
0
static Walkqid*
fswalk(Chan *c, Chan *nc, char **name, int nname)
{
	int i;
	Walkqid *wq;

	if(nc != nil)
		panic("fswalk: nc != nil");
	wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
	nc = devclone(c);
	fsclone(c, nc);
	wq->clone = nc;
	for(i=0; i<nname; i++){
		if(fswalk1(nc, name[i]) == 0)
			break;
		wq->qid[i] = nc->qid;
	}
	if(i != nname){
		cclose(nc);
		wq->clone = nil;
	}
	wq->nqid = i;
	return wq;
}
Ejemplo n.º 5
0
Walkqid*
devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen *gen)
{
	int i, j, alloc;
	Walkqid *wq;
	char *n;
	Dir dir;

	if(nname > 0)
		isdir(c);

	alloc = 0;
	wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
	if(waserror()){
		if(alloc && wq->clone!=nil)
			cclose(wq->clone);
		free(wq);
		return nil;
	}
	if(nc == nil){
		nc = devclone(c);
		nc->type = 0;	/* device doesn't know about this channel yet */
		alloc = 1;
	}
	wq->clone = nc;

	for(j=0; j<nname; j++){
		if(!(nc->qid.type&QTDIR)){
			if(j==0)
				error(Enotdir);
			goto Done;
		}
		n = name[j];
		if(strcmp(n, ".") == 0){
    Accept:
			wq->qid[wq->nqid++] = nc->qid;
			continue;
		}
		if(strcmp(n, "..") == 0){
			if((*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir) != 1){
				print("devgen walk .. in dev%s %llux broken\n",
					devtab[nc->type]->name, nc->qid.path);
				error("broken devgen");
			}
			nc->qid = dir.qid;
			goto Accept;
		}
		/*
		 * Ugly problem: If we're using devgen, make sure we're
		 * walking the directory itself, represented by the first
		 * entry in the table, and not trying to step into a sub-
		 * directory of the table, e.g. /net/net. Devgen itself
		 * should take care of the problem, but it doesn't have
		 * the necessary information (that we're doing a walk).
		 */
		if(gen==devgen && nc->qid.path!=tab[0].qid.path)
			goto Notfound;
		for(i=0;; i++) {
			switch((*gen)(nc, n, tab, ntab, i, &dir)){
			case -1:
			Notfound:
				if(j == 0)
					error(Enonexist);
				kstrcpy(up->errstr, Enonexist, ERRMAX);
				goto Done;
			case 0:
				continue;
			case 1:
				if(strcmp(n, dir.name) == 0){
					nc->qid = dir.qid;
					goto Accept;
				}
				continue;
			}
		}
	}
	/*
	 * We processed at least one name, so will return some data.
	 * If we didn't process all nname entries succesfully, we drop
	 * the cloned channel and return just the Qids of the walks.
	 */
Done:
	poperror();
	if(wq->nqid < nname){
		if(alloc)
			cclose(wq->clone);
		wq->clone = nil;
	}else if(wq->clone){
		/* attach cloned channel to same device */
		wq->clone->type = c->type;
	}
	return wq;
}
Ejemplo n.º 6
0
struct walkqid *devwalk(struct chan *c,
                        struct chan *nc, char **name, int nname,
                        struct dirtab *tab, int ntab, Devgen * gen)
{
    ERRSTACK(1);
    int i, j;
    volatile int alloc;			/* to keep waserror from optimizing this out */
    struct walkqid *wq;
    char *n;
    struct dir dir;

    if (nname > 0)
        isdir(c);

    alloc = 0;
    wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
                  KMALLOC_WAIT);
    if (waserror()) {
        if (alloc && wq->clone != NULL)
            cclose(wq->clone);
        kfree(wq);
        poperror();
        return NULL;
    }
    if (nc == NULL) {
        nc = devclone(c);
        /* inferno was setting this to 0, assuming it was devroot.  lining up
         * with chanrelease and newchan */
        nc->type = -1;	/* device doesn't know about this channel yet */
        alloc = 1;
    }
    wq->clone = nc;

    dir.qid.path = 0;
    for (j = 0; j < nname; j++) {
        if (!(nc->qid.type & QTDIR)) {
            if (j == 0)
                error(Enotdir);
            goto Done;
        }
        n = name[j];
        if (strcmp(n, ".") == 0) {
Accept:
            wq->qid[wq->nqid++] = nc->qid;
            continue;
        }
        if (strcmp(n, "..") == 0) {
            (*gen) (nc, NULL, tab, ntab, DEVDOTDOT, &dir);
            nc->qid = dir.qid;
            goto Accept;
        }
        /*
         * Ugly problem: If we're using devgen, make sure we're
         * walking the directory itself, represented by the first
         * entry in the table, and not trying to step into a sub-
         * directory of the table, e.g. /net/net. Devgen itself
         * should take care of the problem, but it doesn't have
         * the necessary information (that we're doing a walk).
         */
        if (gen == devgen && nc->qid.path != tab[0].qid.path)
            goto Notfound;
        dir.qid.path = 0;
        for (i = 0;; i++) {
            switch ((*gen) (nc, n, tab, ntab, i, &dir)) {
            case -1:
                printd("DEVWALK -1, i was %d, want path %p\n", i,
                       c->qid.path);
Notfound:
                set_errno(ENOENT);
                if (j == 0)
                    error(Enonexist);
                set_errstr(Enonexist);
                goto Done;
            case 0:
                printd("DEVWALK continue, i was %d\n", i);
                continue;
            case 1:
                printd
                ("DEVWALK gen returns path %p name %s, want path %p\n",
                 dir.qid.path, dir.name, c->qid.path);
                if (strcmp(n, dir.name) == 0) {
                    nc->qid = dir.qid;
                    goto Accept;
                }
                continue;
            }
        }
    }
    /*
     * We processed at least one name, so will return some data.
     * If we didn't process all nname entries succesfully, we drop
     * the cloned channel and return just the Qids of the walks.
     */
Done:
    poperror();
    if (wq->nqid < nname) {
        if (alloc)
            cclose(wq->clone);
        wq->clone = NULL;
    } else if (wq->clone) {
        /* attach cloned channel to same device */
        wq->clone->type = c->type;
    }
    return wq;
}
Ejemplo n.º 7
0
Archivo: dev.c Proyecto: Requaos/harvey
Walkqid*
devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab,
	Devgen *gen)
{
	Proc *up = externup();
	if (0) print_func_entry();
	int i, j, alloc;
	Walkqid *wq;
	char *n;
	Dir dir;

	if(nname > 0)
		isdir(c);

	if (0)
	{ int i; iprint("%d names:", nname); for(i = 0; i < nname; i++) iprint("%s ", name[i]); iprint("\n");}
	alloc = 0;
	wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
	if(waserror()){
		if(alloc && wq->clone!=nil)
			cclose(wq->clone);
		free(wq);
		if (0) print_func_exit();
		return nil;
	}
	if(nc == nil){
		nc = devclone(c);
		/*
		 * nc->dev remains nil for now.		//XDYNX
		 */
		alloc = 1;
	}
	wq->clone = nc;

	for(j=0; j<nname; j++){
		if(!(nc->qid.type & QTDIR)){
			if(j==0)
				error(Enotdir);
			goto Done;
		}
		n = name[j];
		if(strcmp(n, ".") == 0){
    Accept:
			wq->qid[wq->nqid++] = nc->qid;
			continue;
		}
		if(strcmp(n, "..") == 0){
			/*
			 * Use c->dev->name in the error because
			 * nc->dev should be nil here.
			 */
			if((*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir) != 1){
				print("devgen walk .. in dev%s %#llx broken\n",
					c->dev->name, nc->qid.path);
				error("broken devgen");
			}
			nc->qid = dir.qid;
			goto Accept;
		}
		/*
		 * Ugly problem: If we're using devgen, make sure we're
		 * walking the directory itself, represented by the first
		 * entry in the table, and not trying to step into a sub-
		 * directory of the table, e.g. /net/net. Devgen itself
		 * should take care of the problem, but it doesn't have
		 * the necessary information (that we're doing a walk).
		 */
		if(gen==devgen && nc->qid.path!=tab[0].qid.path)
			goto Notfound;
		for(i=0;; i++) {
			switch((*gen)(nc, n, tab, ntab, i, &dir)){
			case -1:
			Notfound:
				if(j == 0)
					error(Enonexist);
				kstrcpy(up->errstr, Enonexist, ERRMAX);
				goto Done;
			case 0:
				continue;
			case 1:
				if(strcmp(n, dir.name) == 0){
					nc->qid = dir.qid;
					goto Accept;
				}
				continue;
			}
		}
	}
	/*
	 * We processed at least one name, so will return some data.
	 * If we didn't process all nname entries succesfully, we drop
	 * the cloned channel and return just the Qids of the walks.
	 */
Done:
	poperror();
	if(wq->nqid < nname){
		if(alloc)
			cclose(wq->clone);
		wq->clone = nil;
	}else if(wq->clone){
		/* attach cloned channel to same device */
//what goes here:					//XDYNX
// ->dev must be nil because can't walk an open chan, right?
// what about ref count on dev?
		wq->clone->dev = c->dev;
		//if(wq->clone->dev)			//XDYNX
		//	devtabincr(wq->clone->dev);
	}
	if (0) print_func_exit();
	return wq;
}
Ejemplo n.º 8
0
Archivo: devfs.c Proyecto: 8l/inferno
Walkqid*
fswalk(Chan *c, Chan *nc, char **name, int nname)
{
	int j, alloc;
	Walkqid *wq;
	Dir *dir;
	char *n;
	Cname *current, *next;
	Qid rootqid;

	if(nname > 0)
		isdir(c);	/* do we need this? */

	alloc = 0;
	current = nil;
	wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid));
	if(waserror()){
		if(alloc && wq->clone!=nil)
			cclose(wq->clone);
		cnameclose(current);
		free(wq);
		return nil;
	}
	if(nc == nil){
		nc = devclone(c);
		nc->type = 0;
		alloc = 1;
	}
	wq->clone = nc;

	rootqid = FS(c)->rootqid;
	current = FS(c)->name;
	if(current != nil)
		incref(&current->r);
	for(j=0; j<nname; j++){
		if(!(nc->qid.type&QTDIR)){
			if(j==0)
				error(Enotdir);
			break;
		}
		n = name[j];
		if(strcmp(n, ".") != 0 && !(isdotdot(n) && nc->qid.path == rootqid.path)){	/* TO DO: underlying qids aliased */
			//print("** ufs walk '%s' -> %s\n", current->s, n);
			next = current;
			incref(&next->r);
			next = addelem(current, n);
			dir = dirstat(next->s);
			if(dir == nil){
				cnameclose(next);
				if(j == 0)
					error(Enonexist);
				strcpy(up->env->errstr, Enonexist);
				break;
			}
			nc->qid = dir->qid;
			free(dir);
			cnameclose(current);
			current = next;
		}
		wq->qid[wq->nqid++] = nc->qid;
	}
//	print("** ufs walk '%s'\n", current->s);

	poperror();
	if(wq->nqid < nname){
		cnameclose(current);
		if(alloc)
			cclose(wq->clone);
		wq->clone = nil;
	}else if(wq->clone){
		/* now attach to our device */
		nc->aux = smalloc(sizeof(Fsinfo));
		nc->type = c->type;
		FS(nc)->rootqid = FS(c)->rootqid;
		FS(nc)->name = current;
		FS(nc)->fd = -1;
		FS(nc)->root = FS(c)->root;
	}else
		panic("fswalk: can't happen");
	return wq;
}