⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysfile.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 2 页
字号:
	lock(&c->ref.lk);	c->devoffset += nn;	c->offset += nnn;	unlock(&c->ref.lk);	poperror();	cclose(c);	return nnn;}longsys_read(ulong *arg){	return doread(arg, nil);}longsyspread(ulong *arg){	vlong v;	// Plan 9 VX replaced dodgy varargs code	v = *(vlong*)&arg[3];	if(v == ~0ULL)		return doread(arg, nil);	return doread(arg, &v);}static longdowrite(ulong *arg, vlong *offp){	Chan *c;	long m, n;	vlong off;	uchar *p;	p = uvalidaddr(arg[1], arg[2], 0);	n = 0;	c = fdtochan(arg[0], OWRITE, 1, 1);	if(waserror()) {		if(offp == nil){			lock(&c->ref.lk);			c->offset -= n;			unlock(&c->ref.lk);		}		cclose(c);		nexterror();	}	if(c->qid.type & QTDIR)		error(Eisdir);	n = arg[2];	if(offp == nil){	/* use and maintain channel's offset */		lock(&c->ref.lk);		off = c->offset;		c->offset += n;		unlock(&c->ref.lk);	}else		off = *offp;	if(off < 0)		error(Enegoff);	m = devtab[c->type]->write(c, p, n, off);	if(offp == nil && m < n){		lock(&c->ref.lk);		c->offset -= n - m;		unlock(&c->ref.lk);	}	poperror();	cclose(c);	return m;}longsys_write(ulong *arg){	return dowrite(arg, nil);}longsyspwrite(ulong *arg){	vlong v;	// Plan 9 VX replaced dodgy varargs code	v = *(vlong*)&arg[3];	if(v == ~0ULL)		return dowrite(arg, nil);	return dowrite(arg, &v);}static voidsseek(ulong *arg){	Chan *c;	uchar buf[sizeof(Dir)+100];	Dir dir;	int n;	vlong off;	union {		vlong v;		ulong u[2];	} o;	c = fdtochan(arg[1], -1, 1, 1);	if(waserror()){		cclose(c);		nexterror();	}	if(devtab[c->type]->dc == '|')		error(Eisstream);	off = 0;	o.u[0] = arg[2];	o.u[1] = arg[3];	switch(arg[4]){	case 0:		off = o.v;		if((c->qid.type & QTDIR) && off != 0)			error(Eisdir);		if(off < 0)			error(Enegoff);		c->offset = off;		break;	case 1:		if(c->qid.type & QTDIR)			error(Eisdir);		lock(&c->ref.lk);	/* lock for read/write update */		off = o.v + c->offset;		if(off < 0){			unlock(&c->ref.lk);			error(Enegoff);		}		c->offset = off;		unlock(&c->ref.lk);		break;	case 2:		if(c->qid.type & QTDIR)			error(Eisdir);		n = devtab[c->type]->stat(c, buf, sizeof buf);		if(convM2D(buf, n, &dir, nil) == 0)			error("internal error: stat error in seek");		off = dir.length + o.v;		if(off < 0)			error(Enegoff);		c->offset = off;		break;	default:		error(Ebadarg);	}	*(vlong*)arg[0] = off;	/* caller translated arg[0] already */	c->uri = 0;	c->dri = 0;	cclose(c);	poperror();}longsysseek(ulong *arg){	arg[0] = (ulong)uvalidaddr(arg[0], BY2V, 1);	sseek(arg);	return 0;}longsysoseek(ulong *arg){	union {		vlong v;		ulong u[2];	} o;	ulong a[5];	o.v = (long)arg[1];	a[0] = (ulong)&o.v;	a[1] = arg[0];	a[2] = o.u[0];	a[3] = o.u[1];	a[4] = arg[2];	sseek(a);	return o.v;}voidvalidstat(uchar *s, int n){	int m;	char buf[64];	if(statcheck(s, n) < 0)		error(Ebadstat);	/* verify that name entry is acceptable */	s += STATFIXLEN - 4*BIT16SZ;	/* location of first string */	/*	 * s now points at count for first string.	 * if it's too long, let the server decide; this is	 * only for his protection anyway. otherwise	 * we'd have to allocate and waserror.	 */	m = GBIT16(s);	s += BIT16SZ;	if(m+1 > sizeof buf)		return;	memmove(buf, s, m);	buf[m] = '\0';	/* name could be '/' */	if(strcmp(buf, "/") != 0)		validname(buf, 0);}static char*pathlast(Path *p){	char *s;	if(p == nil)		return nil;	if(p->len == 0)		return nil;	s = strrchr(p->s, '/');	if(s)		return s+1;	return p->s;}longsysfstat(ulong *arg){	Chan *c;	uint l;	uchar *p;	l = arg[2];	p = uvalidaddr(arg[1], l, 1);	c = fdtochan(arg[0], -1, 0, 1);	if(waserror()) {		cclose(c);		nexterror();	}	l = devtab[c->type]->stat(c, p, l);	poperror();	cclose(c);	return l;}longsysstat(ulong *arg){	char *name;	Chan *c;	uint l;	uchar *p;	l = arg[2];	p = uvalidaddr(arg[1], l, 1);	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Aaccess, 0, 0);	if(waserror()){		cclose(c);		nexterror();	}	l = devtab[c->type]->stat(c, p, l);	name = pathlast(c->path);	if(name)		l = dirsetname(name, strlen(name), p, l, arg[2]);	poperror();	cclose(c);	return l;}longsyschdir(ulong *arg){	Chan *c;	char *name;	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Atodir, 0, 0);	cclose(up->dot);	up->dot = c;	return 0;}longbindmount(int ismount, int fd, int afd, char* arg0, char* arg1, ulong flag, char* spec){	int ret;	Chan *c0, *c1, *ac, *bc;	struct{		Chan	*chan;		Chan	*authchan;		char	*spec;		int	flags;	}bogus;	if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER))		error(Ebadarg);	bogus.flags = flag & MCACHE;	if(ismount){		if(up->pgrp->noattach)			error(Enoattach);		ac = nil;		bc = fdtochan(fd, ORDWR, 0, 1);		if(waserror()) {			if(ac)				cclose(ac);			cclose(bc);			nexterror();		}		if(afd >= 0)			ac = fdtochan(afd, ORDWR, 0, 1);		bogus.chan = bc;		bogus.authchan = ac;		bogus.spec = spec;		if(waserror())			error(Ebadspec);		spec = validnamedup(spec, 1);		poperror();				if(waserror()){			free(spec);			nexterror();		}		ret = devno('M', 0);		c0 = devtab[ret]->attach((char*)&bogus);		poperror();	/* spec */		free(spec);		poperror();	/* ac bc */		if(ac)			cclose(ac);		cclose(bc);	}else{		bogus.spec = 0;		c0 = namec(arg0, Abind, 0, 0);	}	if(waserror()){		cclose(c0);		nexterror();	}	c1 = namec(arg1, Amount, 0, 0);	if(waserror()){		cclose(c1);		nexterror();	}	ret = cmount(&c0, c1, flag, bogus.spec);	poperror();	cclose(c1);	poperror();	cclose(c0);	if(ismount)		fdclose(fd, 0);	return ret;}longsysbind(ulong *arg){	return bindmount(0, -1, -1, uvalidaddr(arg[0], 1, 0), uvalidaddr(arg[1], 1, 0), arg[2], nil);}longsysmount(ulong *arg){	return bindmount(1, arg[0], arg[1], nil, uvalidaddr(arg[2], 1, 0), arg[3], uvalidaddr(arg[4], 1, 0));}longsys_mount(ulong *arg){	return bindmount(1, arg[0], -1, nil, uvalidaddr(arg[1], 1, 0), arg[2], uvalidaddr(arg[3], 1, 0));}longsysunmount(ulong *arg){	Chan *cmount, *cmounted;	char *mount, *mounted;	cmounted = 0;	mount = uvalidaddr(arg[1], 1, 0);	cmount = namec(mount, Amount, 0, 0);	if(arg[0]) {		if(waserror()) {			cclose(cmount);			nexterror();		}		mounted = uvalidaddr(arg[0], 1, 0);		/*		 * This has to be namec(..., Aopen, ...) because		 * if arg[0] is something like /srv/cs or /fd/0,		 * opening it is the only way to get at the real		 * Chan underneath.		 */		cmounted = namec(mounted, Aopen, OREAD, 0);		poperror();	}	if(waserror()) {		cclose(cmount);		if(cmounted)			cclose(cmounted);		nexterror();	}	cunmount(cmount, cmounted);	cclose(cmount);	if(cmounted)		cclose(cmounted);	poperror();	return 0;}longsyscreate(ulong *arg){	int fd;	Chan *c = 0;	char *name;	openmode(arg[1]&~OEXCL);	/* error check only; OEXCL okay here */	if(waserror()) {		if(c)			cclose(c);		nexterror();	}	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Acreate, arg[1], arg[2]);	fd = newfd(c);	if(fd < 0)		error(Enofd);	poperror();	return fd;}longsysremove(ulong *arg){	Chan *c;	char *name;	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Aremove, 0, 0);	/*	 * Removing mount points is disallowed to avoid surprises	 * (which should be removed: the mount point or the mounted Chan?).	 */	if(c->ismtpt){		cclose(c);		error(Eismtpt);	}	if(waserror()){		c->type = 0;	/* see below */		cclose(c);		nexterror();	}	devtab[c->type]->remove(c);	/*	 * Remove clunks the fid, but we need to recover the Chan	 * so fake it up.  rootclose() is known to be a nop.	 */	c->type = 0;	poperror();	cclose(c);	return 0;}static longwstat(Chan *c, uchar *d, int nd){	long l;	int namelen;	if(waserror()){		cclose(c);		nexterror();	}	if(c->ismtpt){		/*		 * Renaming mount points is disallowed to avoid surprises		 * (which should be renamed? the mount point or the mounted Chan?).		 */		dirname(d, &namelen);		if(namelen)			nameerror(chanpath(c), Eismtpt);	}	l = devtab[c->type]->wstat(c, d, nd);	poperror();	cclose(c);	return l;}longsyswstat(ulong *arg){	Chan *c;	uint l;	char *name;	uchar *p;	l = arg[2];	p = uvalidaddr(arg[1], l, 0);	validstat(p, l);	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Aaccess, 0, 0);	return wstat(c, p, l);}longsysfwstat(ulong *arg){	Chan *c;	uint l;	uchar *p;	l = arg[2];	p = uvalidaddr(arg[1], l, 0);	validstat(p, l);	c = fdtochan(arg[0], -1, 1, 1);	return wstat(c, p, l);}static voidpackoldstat(uchar *buf, Dir *d){	uchar *p;	ulong q;	/* lay down old stat buffer - grotty code but it's temporary */	p = buf;	strncpy((char*)p, d->name, 28);	p += 28;	strncpy((char*)p, d->uid, 28);	p += 28;	strncpy((char*)p, d->gid, 28);	p += 28;	q = d->qid.path & ~DMDIR;	/* make sure doesn't accidentally look like directory */	if(d->qid.type & QTDIR)	/* this is the real test of a new directory */		q |= DMDIR;	PBIT32(p, q);	p += BIT32SZ;	PBIT32(p, d->qid.vers);	p += BIT32SZ;	PBIT32(p, d->mode);	p += BIT32SZ;	PBIT32(p, d->atime);	p += BIT32SZ;	PBIT32(p, d->mtime);	p += BIT32SZ;	PBIT64(p, d->length);	p += BIT64SZ;	PBIT16(p, d->type);	p += BIT16SZ;	PBIT16(p, d->dev);}longsys_stat(ulong *arg){	Chan *c;	uint l;	uchar buf[128];	/* old DIRLEN plus a little should be plenty */	char strs[128], *name, *elem;	Dir d;	char old[] = "old stat system call - recompile";	uchar *p;	p = uvalidaddr(arg[1], 116, 1);	name = uvalidaddr(arg[0], 1, 0);	c = namec(name, Aaccess, 0, 0);	if(waserror()){		cclose(c);		nexterror();	}	l = devtab[c->type]->stat(c, buf, sizeof buf);	/* buf contains a new stat buf; convert to old. yuck. */	if(l <= BIT16SZ)	/* buffer too small; time to face reality */		error(old);	elem = pathlast(c->path);	if(elem)		l = dirsetname(elem, strlen(elem), buf, l, sizeof buf);	l = convM2D(buf, l, &d, strs);	if(l == 0)		error(old);	packoldstat(p, &d);		poperror();	cclose(c);	return 0;}longsys_fstat(ulong *arg){	Chan *c;	char *name;	uint l;	uchar buf[128];	/* old DIRLEN plus a little should be plenty */	char strs[128];	Dir d;	char old[] = "old fstat system call - recompile";	uchar *p;	p = uvalidaddr(arg[1], 116, 1);	c = fdtochan(arg[0], -1, 0, 1);	if(waserror()){		cclose(c);		nexterror();	}	l = devtab[c->type]->stat(c, buf, sizeof buf);	/* buf contains a new stat buf; convert to old. yuck. */	if(l <= BIT16SZ)	/* buffer too small; time to face reality */		error(old);	name = pathlast(c->path);	if(name)		l = dirsetname(name, strlen(name), buf, l, sizeof buf);	l = convM2D(buf, l, &d, strs);	if(l == 0)		error(old);	packoldstat(p, &d);		poperror();	cclose(c);	return 0;}longsys_wstat(ulong *u){	error("old wstat system call - recompile");	return -1;}longsys_fwstat(ulong *u){	error("old fwstat system call - recompile");	return -1;}// Plan 9 VX additionslongkbind(char *new, char *old, int flag){	return bindmount(0, -1, -1, new, old, flag, nil);}longsyspassfd(ulong *u){	error("passfd unimplemented");	return -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -