Пример #1
0
static Chan*
dupopen(Chan *c, int omode)
{
	Chan *f;
	int fd, twicefd;

	if(c->qid.type & QTDIR){
		if(omode != 0)
			error(Eisdir);
		c->mode = 0;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}
	if(c->qid.type & QTAUTH)
		error(Eperm);
	twicefd = c->qid.path - 1;
	fd = twicefd/2;
	if((twicefd & 1)){
		/* ctl file */
		f = c;
		f->mode = openmode(omode);
		f->flag |= COPEN;
		f->offset = 0;
	}else{
		/* fd file */
		f = fdtochan(up->env->fgrp, fd, openmode(omode), 0, 1);
		cclose(c);
	}
	if(omode & OCEXEC)
		f->flag |= CCEXEC;
	return f;
}
Пример #2
0
static Chan*
signopen(Chan *c, int omode)
{
	if(c->qid.type & QTDIR) {
		if(omode != OREAD)
			error(Eisdir);
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	switch((ulong)c->qid.path){
	case Qctl:
		if(!iseve())
			error(Eperm);
		break;

	case Qkey:
		if(omode != OREAD && !iseve())
			error(Eperm);
		break;
	}

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
Пример #3
0
static struct chan *ver_open(struct chan *c, int omode)
{
	if (c->qid.type & QTDIR) {
		if (openmode(omode) != O_READ)
			error(EPERM, ERROR_FIXME);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
Пример #4
0
static struct chan*
regressopen(struct chan *c, int omode)
{
	if(c->qid.type & QTDIR){
		if(openmode(omode) != O_READ)
			error(EPERM, NULL);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
Пример #5
0
Файл: devfs.c Проект: 8l/inferno
void
fscreate(Chan *c, char *name, int mode, ulong perm)
{
	Dir *d;
	Cname *n;

	if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
		error(Efilename);
	n = addelem(newcname(FS(c)->name->s), name);
	osenter();
	FS(c)->fd = create(n->s, mode, perm);
	osleave();
	if(FS(c)->fd < 0) {
		cnameclose(n);
		fserr(FS(c));
	}
	d = dirfstat(FS(c)->fd);
	if(d == nil) {
		cnameclose(n);
		close(FS(c)->fd);
		FS(c)->fd = -1;
		fserr(FS(c));
	}
	c->qid = d->qid;
	free(d);

	cnameclose(FS(c)->name);
	FS(c)->name = n;

	c->mode = openmode(mode);
	c->offset = 0;
	FS(c)->offset = 0;
	c->flag |= COPEN;
}
Пример #6
0
/*
 *  if the stream doesn't exist, create it
 */
static Chan*
loopbackopen(Chan *c, int omode)
{
	Loop *lb;

	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Ebadarg);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	lb = c->aux;
	qlock(lb);
	if(TYPE(c->qid.path) == Qdata){
		if(lb->link[ID(c->qid.path)].ref){
			qunlock(lb);
			error(Einuse);
		}
		lb->link[ID(c->qid.path)].ref++;
	}
	qunlock(lb);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Пример #7
0
static Chan*
mouseopen(Chan *c, int omode)
{
	switch((ulong)c->qid.path){
	case Qdir:
		if(omode != OREAD)
			error(Eperm);
		break;
	case Qmouse:
		lock(&mouse.ref.lk);
		if(mouse.open){
			unlock(&mouse.ref.lk);
			error(Einuse);
		}
		mouse.open = 1;
		mouse.ref.ref++;
		mouse.lastresize = mouse.resize;
		unlock(&mouse.ref.lk);
		break;
	case Qsnarf:
		if(omode == ORDWR)
			error(Eperm);	/* one at a time please */
		c->aux = nil;
		incref(&mouse.ref);
		break;
	default:
		incref(&mouse.ref);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
Пример #8
0
struct chan *devopen(struct chan *c, int omode, struct dirtab *tab, int ntab,
                     Devgen * gen)
{
    int i;
    struct dir dir;

    dir.qid.path = 0;
    for (i = 0;; i++) {
        switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
        case -1:
            goto Return;
        case 0:
            break;
        case 1:
            if (c->qid.path == dir.qid.path) {
                devpermcheck(dir.uid, dir.mode, omode);
                goto Return;
            }
            break;
        }
    }
Return:
    c->offset = 0;
    if ((c->qid.type & QTDIR) && !IS_RDONLY(omode))
        error("Tried opening dir with non-read-only mode %o", omode);
    c->mode = openmode(omode);
    c->flag |= COPEN;
    return c;
}
Пример #9
0
/*
 *  if the stream doesn't exist, create it
 */
static Chan*
pipeopen(Chan *c, int omode)
{
	Pipe *p;

	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Ebadarg);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	p = c->aux;
	qlock(p);
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		p->qref[0]++;
		break;
	case Qdata1:
		p->qref[1]++;
		break;
	}
	qunlock(p);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Пример #10
0
int syscreate(char *path, int mode, uint32_t perm)
{
	ERRSTACK(2);
	int fd;
	struct chan *c;

	if (waserror()) {
		poperror();
		return -1;
	}

	openmode(mode & ~O_EXCL);	/* error check only; OEXCL okay here */
	c = namec(path, Acreate, mode, perm);
	if (waserror()) {
		cclose(c);
		nexterror();
	}
	fd = newfd(c, mode);	/* 9ns mode is the O_FLAGS and perm is glibc mode */
	if (fd < 0)
		error(-fd, ERROR_FIXME);
	poperror();

	poperror();
	return fd;
}
Пример #11
0
void
syscreate(Ar0* ar0, ...)
{
	Proc *up = externup();
	char *aname;
	int fd, omode, perm;
	Chan *c;
	va_list list;
	va_start(list, ar0);

	/*
	 * int create(char* file, int omode, uint32_t perm);
	 * should be
	 * int create(char* file, int omode, int perm);
	 */
	aname = va_arg(list, char*);
	omode = va_arg(list, int);
	perm = va_arg(list, int);
	va_end(list);

	openmode(omode & ~OEXCL);	/* error check only; OEXCL okay here */
	c = nil;
	if(waserror()) {
		if(c != nil)
			cclose(c);
		nexterror();
	}
	c = namec(validaddr(aname, 1, 0), Acreate, omode, perm);
	fd = newfd(c);
	if(fd < 0)
		error(Enofd);
	poperror();

	ar0->i = fd;
}
Пример #12
0
void
sysopen(Ar0* ar0, ...)
{
	Proc *up = externup();
	va_list list;
	char *aname;
	int fd, omode;
	Chan *c;

	/*
	 * int open(char* file, int omode);
	 */
	va_start(list, ar0);
	aname = va_arg(list, char*);
	omode = va_arg(list, int);
	va_end(list);
	openmode(omode);	/* error check only */

	c = nil;
	if(waserror()){
		if(c != nil)
			cclose(c);
		nexterror();
	}
	aname = validaddr(aname, 1, 0);
	c = namec(aname, Aopen, omode, 0);
	fd = newfd(c);
	if(fd < 0)
		error(Enofd);
	poperror();

	ar0->i = fd;
}
Пример #13
0
int syscreate(char *path, int mode, uint32_t perm)
{
	ERRSTACK(2);
	int fd;
	struct chan *c;

	if (waserror()) {
		poperror();
		return -1;
	}

	openmode(mode & ~OEXCL);	/* error check only; OEXCL okay here */
	c = namec(path, Acreate, mode, perm);
	if (waserror()) {
		cclose(c);
		nexterror();
	}
	fd = newfd(c);
	if (fd < 0)
		error(Enofd);
	poperror();

	poperror();
	return fd;
}
Пример #14
0
Chan*
devopen(Chan *c, int omode, Dirtab *tab, int ntab, Devgen *gen)
{
	int i;
	Dir dir;

	for(i=0;; i++) {
		switch((*gen)(c, nil, tab, ntab, i, &dir)){
		case -1:
			goto Return;
		case 0:
			break;
		case 1:
			if(c->qid.path == dir.qid.path) {
				devpermcheck(dir.uid, dir.mode, omode);
				goto Return;
			}
			break;
		}
	}
Return:
	c->offset = 0;
	if((c->qid.type&QTDIR) && omode!=OREAD)
		error(Eperm);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	return c;
}
Пример #15
0
static Chan*
segmentopen(Chan *c, int omode)
{
	Globalseg *g;

	switch(TYPE(c)){
	case Qtopdir:
	case Qsegdir:
		if(omode != 0)
			error(Eisdir);
		break;
	case Qctl:
	case Qfree:
		g = getgseg(c);
		if(waserror()){
			putgseg(g);
			nexterror();
		}
		devpermcheck(g->uid, g->perm, omode);
		c->aux = g;
		poperror();
		c->flag |= COPEN;
		break;
	case Qdata:
		g = getgseg(c);
		if(waserror()){
			putgseg(g);
			nexterror();
		}
		devpermcheck(g->uid, g->perm, omode);
		if(g->s == nil)
			error("segment not yet allocated");
		if(g->kproc == nil){
			qlock(&g->l);
			if(waserror()){
				qunlock(&g->l);
				nexterror();
			}
			if(g->kproc == nil){
				g->cmd = Cnone;
				kproc(g->name, segmentkproc, g);
				docmd(g, Cstart);
			}
			poperror();
			qunlock(&g->l);
		}
		c->aux = g;
		poperror();
		c->flag |= COPEN;
		break;
	default:
		panic("segmentopen");
	}
	c->mode = openmode(omode);
	c->offset = 0;
	return c;
}
Пример #16
0
/*
 *  if the stream doesn't exist, create it
 */
static struct chan *pipeopen(struct chan *c, int omode)
{
	ERRSTACK(2);
	Pipe *p;

	if (c->qid.type & QTDIR) {
		if (omode & O_WRITE)
			error(EINVAL, "Can only open directories O_READ, mode is %o oct",
				  omode);
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	openmode(omode);	/* check it */

	p = c->aux;
	qlock(&p->qlock);
	if (waserror()) {
		qunlock(&p->qlock);
		nexterror();
	}
	switch (NETTYPE(c->qid.path)) {
		case Qdata0:
			devpermcheck(p->user, p->pipedir[1].perm, omode);
			p->qref[0]++;
			break;
		case Qdata1:
			devpermcheck(p->user, p->pipedir[2].perm, omode);
			p->qref[1]++;
			break;
	}
	poperror();
	qunlock(&p->qlock);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Пример #17
0
static void rootcreate(struct chan *c, char *name, int omode, uint32_t perm)
{
	struct dirtab *r = &roottab[c->qid.path], *newr;
	struct rootdata *rd = &rootdata[c->qid.path];
	/* need to filter openmode so that it gets only the access-type bits */
	omode = openmode(omode);
	c->mode = openmode(omode);
	printd("rootcreate: c %p, name %s, omode %o, perm %x\n", 
	       c, name, omode, perm);
	/* find an empty slot */
	int path = c->qid.path;
	int newfile;
	newfile = createentry(path, name, omode, perm);
	c->qid = roottab[newfile].qid;	/* need to update c */
	rd->size++;
	if (newfile > rootmaxq)
		rootmaxq = newfile;
	printd("create: %s, newfile %d, dotdot %d, rootmaxq %d\n", name, newfile,
	       rootdata[newfile].dotdot, rootmaxq);
}
Пример #18
0
/*
 *  if the stream doesn't exist, create it
 */
static Chan*
pipeopen(Chan *c, int omode)
{
	Pipe *p;

	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Ebadarg);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	openmode(omode);	/* check it */

	p = c->aux;
	qlock(&p->l);
	if(waserror()){
		qunlock(&p->l);
		nexterror();
	}
	switch(NETTYPE(c->qid.path)){
	case Qdata0:
		devpermcheck(p->user, p->pipedir[1].perm, omode);
		p->qref[0]++;
		break;
	case Qdata1:
		devpermcheck(p->user, p->pipedir[2].perm, omode);
		p->qref[1]++;
		break;
	}
	poperror();
	qunlock(&p->l);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Пример #19
0
static void
fscreate(Chan *c, char *name, int mode, ulong perm)
{
	int m;
	ulong t;
	wchar_t *newpath;
	Ufsinfo *uif;

	m = fsomode(mode&3);
	uif = c->aux;
	t = pathtype(uif->path);
	newpath = catpath(uif->path, name, nil);
	if(waserror()){
		free(newpath);
		nexterror();
	}
	if(perm & DMDIR) {
		wchar_t *p;
		DIR *d;
		if(m || t!=TPATH_FILE)
			error(Eperm);
		if(!CreateDirectory(newpath, NULL))
			oserror();
		d = malloc(sizeof(*d));
		p = catpath(newpath, "*.*", nil);
		d->handle = FindFirstFile(p, &d->wfd);
		free(p);
		if(d->handle == INVALID_HANDLE_VALUE){
			free(d);
			oserror();
		}
		d->keep = 1;
		uif->dir = d;
	} else {
		uif->dir = nil;
		if((uif->fh = CreateFile(
			newpath,
			fsaccess(mode),
			FILE_SHARE_READ | FILE_SHARE_WRITE,
			NULL,
			CREATE_NEW,
			FILE_ATTRIBUTE_NORMAL,
			0)) == INVALID_HANDLE_VALUE)
			oserror();
	}
	free(uif->path);
	uif->path = newpath;
	poperror();
	c->qid = wfdtoqid(newpath, nil);
	c->offset = 0;
	c->flag |= COPEN;
	c->mode = openmode(mode);
}
Пример #20
0
static Chan*
screenopen(Chan *c, int omode)
{
	if ((ulong)c->qid.path == Qdss) {
		qlock(&dsslck);
		oscreen.open = 1;
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
	}
	return c;
}
Пример #21
0
static Chan*
devlogfsopen(Chan *c, int omode)
{
	int instance, qid, qt;

	omode = openmode(omode);
	SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt);
#ifdef CALLTRACE
	print("devlogfsopen(c = 0x%.8lux, omode = %o, instance = %d, qid = %d, qt = %d)\n",
		(ulong)c, omode, instance, qid, qt);
#endif


	rlock(&devlogfslist.rwlock);
	if (waserror()) {
		runlock(&devlogfslist.rwlock);
#ifdef CALLTRACE
		print("devlogfsopen(c = 0x%.8lux, omode = %o) - error %s\n", (ulong)c, omode, up->env->errstr);
#endif
		nexterror();
	}

	if (DATAQID(qid, qt)) {
		Devlogfs *d;
		d = devlogfsfind(instance);
		if (d == nil)
			error(Enodev);
		if (strcmp(up->env->user, eve) != 0)
			error(Eperm);
		if (qid == Qfs && d->state != BootOpen)
			error(Eperm);
		if (d->server == nil) {
			errorany(logfsservernew(d->lb, d->ll, is, d->openflags, d->logfstrace, &d->server));
			d->state = NeedVersion;
		}
		c = devopen(c, omode, 0, 0, devlogfsgennolock);
		incref(&d->ref);
		c->aux = d;
	}
	else if (qid == Qctl || qid == Qusers) {
		if (strcmp(up->env->user, eve) != 0)
			error(Eperm);
		c = devopen(c, omode, 0, 0, devlogfsgennolock);
	}
	else
		c = devopen(c, omode, 0, 0, devlogfsgennolock);
	poperror();
	runlock(&devlogfslist.rwlock);
#ifdef CALLTRACE
	print("devlogfsopen(c = 0x%.8lux, omode = %o) - return\n", (ulong)c, omode);
#endif
	return c;
}
Пример #22
0
static Chan*
rtcopen(Chan* c, int omode)
{
	omode = openmode(omode);
	switch((ulong)c->qid.path){
	case Qrtc:
		if(strcmp(up->user, eve)!=0 && omode!=OREAD)
			error(Eperm);
		break;
	}
	return devopen(c, omode, rtcdir, nelem(rtcdir), devgen);
}
Пример #23
0
static Chan*
i82365open(Chan *c, int omode)
{
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eperm);
	} else
		increfp(slot + SLOTNO(c));
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}
Пример #24
0
static Chan*
srvopen(Chan *c, int omode)
{
	SrvFile *sf;

	openmode(omode);	/* check it */
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eisdir);
		c->mode = omode;
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	sf = c->aux;

	qlock(&dev.l);
	if(waserror()){
		qunlock(&dev.l);
		nexterror();
	}
	devpermcheck(sf->user, sf->perm, omode);
	if(omode&ORCLOSE && strcmp(sf->user, up->env->user) != 0)
		error(Eperm);
	if(sf->perm & DMEXCL && sf->opens != 0)
		error(Einuse);
	sf->opens++;
	if(omode&ORCLOSE)
		sf->flags |= SORCLOSE;
	poperror();
	qunlock(&dev.l);

	c->offset = 0;
	c->flag |= COPEN;
	c->mode = openmode(omode);

	return c;
}
Пример #25
0
static Chan*
flashopen(Chan *c, int omode)
{
	omode = openmode(omode);
	switch(TYPE(c->qid.path)){
	case Qdata:
	case Qctl:
		if(flash.card[c->dev] == nil)
			error(Enodev);
		break;
	}
	return devopen(c, omode, nil, 0, flashgen);
}
Пример #26
0
static Chan*
envcreate(Chan *c, char *name, int omode, ulong)
{
	Egrp *eg;
	Evalue *e;
	Evalue **ent;

	if(c->qid.type != QTDIR || !envwriteable(c))
		error(Eperm);

	if(strlen(name) >= sizeof(up->genbuf))
		error(Etoolong);

	omode = openmode(omode);
	eg = envgrp(c);

	wlock(eg);
	if(waserror()) {
		wunlock(eg);
		nexterror();
	}

	if(envlookup(eg, name, -1) != nil)
		error(Eexist);

	e = smalloc(sizeof(Evalue));
	e->name = smalloc(strlen(name)+1);
	strcpy(e->name, name);

	if(eg->nent == eg->ment){
		eg->ment += 32;
		ent = smalloc(sizeof(eg->ent[0])*eg->ment);
		if(eg->nent)
			memmove(ent, eg->ent, sizeof(eg->ent[0])*eg->nent);
		free(eg->ent);
		eg->ent = ent;
	}
	e->qid.path = ++eg->path;
	e->qid.vers = 0;
	eg->vers++;
	eg->ent[eg->nent++] = e;
	c->qid = e->qid;

	wunlock(eg);
	poperror();

	c->offset = 0;
	c->mode = omode;
	c->flag |= COPEN;
	return c;
}
Пример #27
0
Файл: devfs.c Проект: 8l/inferno
Chan*
fsopen(Chan *c, int mode)
{
	osenter();
	FS(c)->fd = open(FS(c)->name->s, mode);
	osleave();
	if(FS(c)->fd < 0)
		fserr(FS(c));
	c->mode = openmode(mode);
	c->offset = 0;
	FS(c)->offset = 0;
	c->flag |= COPEN;
	return c;
}
Пример #28
0
static Chan*
envcreate(Chan *c, char *name, int omode, ulong)
{
	Egrp *eg;
	Evalue *e;

	if(c->qid.type != QTDIR || !envwriteable(c))
		error(Eperm);

	if(strlen(name) >= sizeof(up->genbuf))
		error(Etoolong);

	omode = openmode(omode);
	eg = envgrp(c);
	wlock(eg);
	if(waserror()) {
		wunlock(eg);
		nexterror();
	}

	if(envlookup(eg, name, -1) != nil)
		error(Eexist);

	if(eg->nent == eg->ment){
		Evalue *tmp;

		eg->ment += DELTAENV;
		if((tmp = realloc(eg->ent, sizeof(eg->ent[0])*eg->ment)) == nil){
			eg->ment -= DELTAENV;
			error(Enomem);
		}
		eg->ent = tmp;
	}
	eg->vers++;
	e = &eg->ent[eg->nent++];
	e->value = nil;
	e->len = 0;
	e->name = smalloc(strlen(name)+1);
	strcpy(e->name, name);
	mkqid(&e->qid, ++eg->path, 0, QTFILE);
	c->qid = e->qid;

	wunlock(eg);
	poperror();

	c->offset = 0;
	c->mode = omode;
	c->flag |= COPEN;
	return c;
}
Пример #29
0
static Chan*
fsopen(Chan *c, int mode)
{
	char *path;
	int m;
	UnixFd *ufd;
	
	ufd = c->aux;
	if(Trace)
		print("fsopen %s %#x\n", ufd->path->s, mode);

	/* protect files whose path does not begin with allowed */
	if(strncmp(ufd->path->s, canopen, strlen(canopen)) != 0)
		error(Eperm);

	if(mode & ~(OTRUNC|ORCLOSE|3))
		error(Ebadarg);

	if((c->qid.type & QTDIR) && mode != OREAD)
		error(Eperm);
	
	if((c->qid.type&QTDIR) && mode != OREAD)
		error(Eperm);

	c->mode = openmode(mode);
	path = fspath(c, nil);
	if(c->qid.type & QTDIR){
		ufd->dir = opendir(path);
		if(ufd->dir == nil){
			free(path);
			oserror();
		}
		ufd->diroffset = 0;
		ufd->nextde = nil;
	}else{
		m = mode & 3;
		if(m == OEXEC)
			m = OREAD;
		if(mode & OTRUNC)
			m |= O_TRUNC;
		if((ufd->fd = open(path, m)) < 0 && opensocket(ufd, path) < 0){
			free(path);
			oserror();
		}
	}
	free(path);
	c->flag |= COPEN;
	return c;
}
Пример #30
0
static Chan*
wsopen(Chan *c, int omode)
{
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eperm);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->aux = nil;
	if(c->qid.path == WSdataqid)
		c->aux = collect();
	return c;
}