struct chan *devclone(struct chan *c) { struct chan *nc; /* In plan 9, you couldn't clone an open chan. We're allowing it, possibly * foolishly. The new chan is a non-open, "kernel internal" chan. Note * that c->flag isn't set, for instance. c->mode is, which might be a * problem. The newchan should eventually have a device's open called on * it, at which point it upgrades from a kernel internal chan to one that * can refer to an object in the device (e.g. grab a refcnt on a * conversation in #ip). * * Either we allow devclones of open chans, or O_PATH walks do not open a * file. It's nice to allow the device to do something for O_PATH, but * perhaps that is not critical. However, if we can't clone an opened chan, * then we can *only* openat from an FD that is O_PATH, which is not the * spec (and not as useful). */ if ((c->flag & COPEN) && !(c->flag & O_PATH)) panic("clone of non-O_PATH open file type %s\n", devtab[c->type].name); nc = newchan(); nc->type = c->type; nc->dev = c->dev; nc->mode = c->mode; nc->qid = c->qid; nc->offset = c->offset; nc->umh = NULL; nc->mountid = c->mountid; nc->aux = c->aux; nc->mqid = c->mqid; nc->mcp = c->mcp; return nc; }
Chan* devclone(Chan *c) { if (0) print_func_entry(); Chan *nc; if(c->flag & COPEN){ panic("devclone: file of type %C already open\n", c->dev != nil? c->dev->dc: -1); } nc = newchan(); /* * The caller fills dev in if and when necessary. nc->dev = nil; //XDYNXX */ nc->devno = c->devno; nc->mode = c->mode; nc->qid = c->qid; nc->offset = c->offset; nc->umh = nil; nc->aux = c->aux; nc->mqid = c->mqid; nc->mc = c->mc; if (0) print_func_exit(); return nc; }
Chan* devattach(int dc, char *spec) { if (0) print_func_entry(); Chan *c; char *buf; /* * There are no error checks here because * this can only be called from the driver of dc * which pretty much guarantees devtabget will * succeed. */ c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); c->dev = devtabget(dc, 0); if(spec == nil) spec = ""; buf = smalloc(1+UTFmax+strlen(spec)+1); sprint(buf, "#%C%s", dc, spec); c->path = newpath(buf); free(buf); if (0) print_func_exit(); return c; }
Chan* lfdchan(int fd) { Chan *c; c = newchan(); c->type = devno('L', 0); c->aux = (void*)(uintptr)fd; c->name = newcname("fd"); c->mode = ORDWR; c->qid.type = 0; c->qid.path = 0; c->qid.vers = 0; c->dev = 0; c->offset = 0; return c; }
Chan* devattach(int tc, char *spec) { Chan *c; char *buf; c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); c->type = devno(tc, 0); if(spec == nil) spec = ""; buf = smalloc(4+strlen(spec)+1); sprint(buf, "#%C%s", tc, spec); c->name = newcname(buf); free(buf); return c; }
struct chan *devattach(int tc, char *spec) { struct chan *c; char *buf; c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); c->type = devno(tc, 0); if (spec == NULL) spec = ""; /* 2 for #c, 1 for \0 */ buf = kzmalloc(2 + strlen(spec) + 1, KMALLOC_WAIT); snprintf(buf, sizeof(buf), "#%c%s", tc, spec); c->name = newcname(buf); kfree(buf); return c; }
struct chan *devattach(const char *name, char *spec) { struct chan *c; char *buf; size_t buflen; c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); c->type = devno(name, 0); if (spec == NULL) spec = ""; /* 1 for #, 1 for ., 1 for \0 */ buflen = strlen(name) + strlen(spec) + 3; buf = kzmalloc(buflen, KMALLOC_WAIT); snprintf(buf, sizeof(buf), "#%s.%s", name, spec); c->name = newcname(buf); kfree(buf); return c; }
Chan* devclone(Chan *c) { Chan *nc; if(c->flag & COPEN) panic("clone of open file type %C\n", devtab[c->type]->dc); nc = newchan(); nc->type = c->type; nc->dev = c->dev; nc->mode = c->mode; nc->qid = c->qid; nc->offset = c->offset; nc->umh = nil; nc->mountid = c->mountid; nc->aux = c->aux; nc->mqid = c->mqid; nc->mcp = c->mcp; return nc; }