Ejemplo n.º 1
0
/* Could pass in the fdt instead of the proc, but we used to need the to_proc
 * for now so we can claim a VFS FD.  Careful, we don't close the old chan. */
int sys_dup_to(struct proc *from_proc, unsigned int from_fd,
               struct proc *to_proc, unsigned int to_fd)
{
	ERRSTACK(1);
	int ret;
	struct chan *c;

	if (waserror()) {
		poperror();
		return -1;
	}
	c = fdtochan(&from_proc->open_files, from_fd, -1, 0, 1);
	if (c->qid.type & QTAUTH) {
		cclose(c);
		error(EPERM, ERROR_FIXME);
	}
	ret = insert_obj_fdt(&to_proc->open_files, c, to_fd, 0, TRUE, FALSE);
	/* drop the ref from fdtochan.  if insert succeeded, there is one other ref
	 * stored in the FDT */
	cclose(c);
	if (ret < 0)
		error(EFAIL, "Can't insert FD %d into FDG", to_fd);
	poperror();
	return 0;
}
Ejemplo n.º 2
0
long
sys_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";

	validaddr(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((uchar*)arg[1], &d);
	
	poperror();
	cclose(c);
	return 0;
}
Ejemplo n.º 3
0
void
sysfwstat(Ar0* ar0, ...)
{
	Chan *c;
	int fd;
	uint8_t *p;
	usize n;
	va_list list;
	va_start(list, ar0);

	/*
	 * int fwstat(int fd, uchar* edir, int nedir);
	 * should really be
	 * usize wstat(int fd, uchar* edir, usize nedir);
	 * but returning an unsigned is probably too
	 * radical.
	 */
	fd = va_arg(list, int);
	p = va_arg(list, uint8_t*);
	n = va_arg(list, usize);

	p = validaddr(p, n, 0);
	validstat(p, n);
	c = fdtochan(fd, -1, 1, 1);
	va_end(list);

	ar0->l = wstat(c, p, n);
}
Ejemplo n.º 4
0
uintptr
sysfversion(va_list list)
{
	uint msize, arglen;
	char *vers;
	Chan *c;
	int fd;

	fd = va_arg(list, int);
	msize = va_arg(list, uint);
	vers = va_arg(list, char*);
	arglen = va_arg(list, uint);
	validaddr((uintptr)vers, arglen, 1);
	/* check there's a NUL in the version string */
	if(arglen==0 || memchr(vers, 0, arglen)==0)
		error(Ebadarg);
	c = fdtochan(fd, ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	msize = mntversion(c, vers, msize, arglen);
	cclose(c);
	poperror();
	return msize;
}
Ejemplo n.º 5
0
void
sysfversion(Ar0* ar0, va_list list)
{
	Chan *c;
	char *version;
	int fd;
	u32int msize;
	usize nversion;

	/*
	 * int fversion(int fd, int bufsize, char *version, int nversion);
	 * should be
	 * usize fversion(int fd, u32int msize, char *version, usize nversion);
	 */
	fd = va_arg(list, int);
	msize = va_arg(list, u32int);
	version = va_arg(list, char*);
	nversion = va_arg(list, usize);
	version = validaddr(version, nversion, 1);
	/* check there's a NUL in the version string */
	if(nversion == 0 || memchr(version, 0, nversion) == nil)
		error(Ebadarg);

	c = fdtochan(fd, ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}

	ar0->u = mntversion(c, msize, version, nversion);

	cclose(c);
	poperror();
}
Ejemplo n.º 6
0
void
sysfd2path(Ar0* ar0, ...)
{
	Chan *c;
	char *buf;
	int fd;
	usize nbuf;
	va_list list;
	va_start(list, ar0);

	/*
	 * int fd2path(int fd, char* buf, int nbuf);
	 * should be
	 * int fd2path(int fd, char* buf, usize nbuf);
	 */
	fd = va_arg(list, int);
	buf = va_arg(list, char*);
	nbuf = va_arg(list, usize);
	va_end(list);
	buf = validaddr(buf, nbuf, 1);

	c = fdtochan(fd, -1, 0, 1);
	snprint(buf, nbuf, "%s", chanpath(c));
	cclose(c);

	ar0->i = 0;
}
Ejemplo n.º 7
0
int sysfversion(int fd, unsigned int msize, char *vers, unsigned int arglen)
{
	ERRSTACK(2);
	int m;
	struct chan *c;

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

	/* check there's a NUL in the version string */
	if (arglen == 0 || memchr(vers, 0, arglen) == 0)
		error(EINVAL, ERROR_FIXME);

	c = fdtochan(&current->open_files, fd, O_RDWR, 0, 1);
	if (waserror()) {
		cclose(c);
		nexterror();
	}

	m = mntversion(c, vers, msize, arglen);

	poperror();
	cclose(c);

	poperror();
	return m;
}
Ejemplo n.º 8
0
long
sysfversion(ulong *arg)
{
	char *vers;
	uint arglen, m, msize;
	Chan *c;

	msize = arg[1];
	vers = (char*)arg[2];
	arglen = arg[3];
	validaddr(arg[2], arglen, 1);
	/* check there's a NUL in the version string */
	if(arglen==0 || memchr(vers, 0, arglen)==0)
		error(Ebadarg);
	c = fdtochan(arg[0], ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}

	m = mntversion(c, vers, msize, arglen);

	cclose(c);
	poperror();
	return m;
}
Ejemplo n.º 9
0
Archivo: devdup.c Proyecto: 8l/inferno
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;
}
Ejemplo n.º 10
0
Archivo: devdup.c Proyecto: 8l/inferno
static long
dupread(Chan *c, void *va, long n, vlong offset)
{
	char *a = va;
	char buf[256];
	int fd, twicefd;

	if(c->qid.type == QTDIR)
		return devdirread(c, a, n, nil, 0, dupgen);
	twicefd = c->qid.path - 1;
	fd = twicefd/2;
	if(twicefd & 1){
		c = fdtochan(up->env->fgrp, fd, -1, 0, 1);
		if(waserror()){
			cclose(c);
			nexterror();
		}
		progfdprint(c, fd, 0, buf, sizeof buf);
		poperror();
		cclose(c);
		return readstr((ulong)offset, va, n, buf);
	}
	panic("dupread");
	return 0;
}
Ejemplo n.º 11
0
long
_sysclose(int fd)
{
	fdtochan(fd, -1, 0, 0);
	fdclose(fd, 0);

	return 0;
}
Ejemplo n.º 12
0
long
sysclose(ulong *arg)
{
	fdtochan(arg[0], -1, 0, 0);
	fdclose(arg[0], 0);

	return 0;
}
Ejemplo n.º 13
0
static vlong
_sysseek(int fd, vlong off, int whence)
{
	Chan *c;
	uchar buf[sizeof(Dir)+100];
	Dir dir;
	int n;

	c = fdtochan(fd, -1, 1, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	if(devtab[c->type]->dc == '|')
		error(Eisstream);

	switch(whence){
	case 0:
		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 = off + c->offset;
		if(off < 0)
			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 + off;
		if(off < 0)
			error(Enegoff);
		c->offset = off;
		break;

	default:
		error(Ebadarg);
	}
	c->uri = 0;
	c->dri = 0;
	cclose(c);
	poperror();
	return off;
}
Ejemplo n.º 14
0
long
sysfd2path(ulong *arg)
{
	Chan *c;

	validaddr(arg[1], arg[2], 1);

	c = fdtochan(arg[0], -1, 0, 1);
	snprint((char*)arg[1], arg[2], "%s", chanpath(c));
	cclose(c);
	return 0;
}
Ejemplo n.º 15
0
static int64_t
sseek(int fd, int64_t offset, int whence)
{
	Proc *up = externup();
	Chan *c;
	uint8_t buf[sizeof(Dir)+100];
	Dir dir;
	int n;

	c = fdtochan(fd, -1, 1, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}
	if(c->dev->dc == '|')
		error(Eisstream);

	switch(whence){
	case 0:
		if((c->qid.type & QTDIR) && offset != 0LL)
			error(Eisdir);
		c->offset = offset;
		break;

	case 1:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		lock(&c->r.l);	/* lock for read/write update */
		offset += c->offset;
		c->offset = offset;
		unlock(&c->r.l);
		break;

	case 2:
		if(c->qid.type & QTDIR)
			error(Eisdir);
		n = c->dev->stat(c, buf, sizeof buf);
		if(convM2D(buf, n, &dir, nil) == 0)
			error("internal error: stat error in seek");
		offset += dir.length;
		c->offset = offset;
		break;

	default:
		error(Ebadarg);
	}
	c->uri = 0;
	c->dri = 0;
	cclose(c);
	poperror();

	return offset;
}
Ejemplo n.º 16
0
long
sysfwstat(ulong *arg)
{
	Chan *c;
	uint l;

	l = arg[2];
	validaddr(arg[1], l, 0);
	validstat((uchar*)arg[1], l);
	c = fdtochan(arg[0], -1, 1, 1);
	return wstat(c, (uchar*)arg[1], l);
}
Ejemplo n.º 17
0
long
sysfwstat(uint32 *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);
}
Ejemplo n.º 18
0
long
sysfd2path(uint32 *arg)
{
	Chan *c;
	char *buf;

	buf = uvalidaddr(arg[1], arg[2], 1);

	c = fdtochan(arg[0], -1, 0, 1);
	snprint(buf, arg[2], "%s", chanpath(c));
	cclose(c);
	return 0;
}
Ejemplo n.º 19
0
static long
dowrite(uint32 *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;
}
Ejemplo n.º 20
0
long
_sysfd2path(int fd, char *buf, uint nbuf)
{
	Chan *c;

	c = fdtochan(fd, -1, 0, 1);

	if(c->name == nil)
		snprint(buf, nbuf, "<null>");
	else
		snprint(buf, nbuf, "%s", c->name->s);
	cclose(c);
	return 0;
}
Ejemplo n.º 21
0
void
sysdup(Ar0* ar0, ...)
{
	Proc *up = externup();
	int nfd, ofd;
	Chan *nc, *oc;
	Fgrp *f;
	va_list list;
	va_start(list, ar0);

	/*
	 * int dup(int oldfd, int newfd);
	 *
	 * Close after dup'ing, so date > #d/1 works
	 */
	ofd = va_arg(list, int);
	oc = fdtochan(ofd, -1, 0, 1);
	nfd = va_arg(list, int);
	va_end(list);

	if(nfd != -1){
		f = up->fgrp;
		lock(&f->r.l);
		if(nfd < 0 || growfd(f, nfd) < 0) {
			unlockfgrp(f);
			cclose(oc);
			error(Ebadfd);
		}
		if(nfd > f->maxfd)
			f->maxfd = nfd;

		nc = f->fd[nfd];
		f->fd[nfd] = oc;
		unlockfgrp(f);
		if(nc != nil)
			cclose(nc);
	}else{
		if(waserror()) {
			cclose(oc);
			nexterror();
		}
		nfd = newfd(oc);
		if(nfd < 0)
			error(Enofd);
		poperror();
	}

	ar0->i = nfd;
}
Ejemplo n.º 22
0
static long
kwrite(int fd, void *buf, long nn, vlong *offp)
{
	Chan *c;
	long m, n;
	vlong off;

	n = 0;
	c = fdtochan(fd, 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 = nn;

	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, buf, n, off);

	if(offp == nil && m < n){
		lock(&c->ref.lk);
		c->offset -= n - m;
		unlock(&c->ref.lk);
	}

	poperror();
	cclose(c);

	return m;
}
Ejemplo n.º 23
0
static Chan *
devlogfskopen(char *name, char *suffix, int mode)
{
	Chan *c;
	char *fn;
	int fd;

	fn = estrconcat(name, suffix, 0);
	fd = kopen(fn, mode);
	logfsfreemem(fn);
	if (fd < 0)
		error(up->env->errstr);
	c = fdtochan(up->env->fgrp, fd, mode, 0, 1);
	kclose(fd);
	return c;
}
Ejemplo n.º 24
0
Archivo: sysfile.c Proyecto: 8l/inferno
int
kfgrpclose(Fgrp *f, int fd)
{
	if(waserror())
		return -1;

	/*
	 * Take no reference on the chan because we don't really need the
	 * data structure, and are calling fdtochan only for error checks.
	 * fdclose takes care of processes racing through here.
	 */
	fdtochan(f, fd, -1, 0, 0);
	fdclose(f, fd);
	poperror();
	return 0;
}
Ejemplo n.º 25
0
void
sysfauth(Ar0* ar0, va_list list)
{
	Chan *c, *ac;
	char *aname;
	int fd;

	/*
	 * int fauth(int fd, char *aname);
	 */
	fd = va_arg(list, int);
	aname = va_arg(list, char*);

	aname = validaddr(aname, 1, 0);
	aname = validnamedup(aname, 1);
	if(waserror()){
		free(aname);
		nexterror();
	}
	c = fdtochan(fd, ORDWR, 0, 1);
	if(waserror()){
		cclose(c);
		nexterror();
	}

	ac = mntauth(c, aname);
	/* at this point ac is responsible for keeping c alive */
	cclose(c);
	poperror();	/* c */
	free(aname);
	poperror();	/* aname */

	if(waserror()){
		cclose(ac);
		nexterror();
	}

	fd = newfd(ac);
	if(fd < 0)
		error(Enofd);
	poperror();	/* ac */

	/* always mark it close on exec */
	ac->flag |= CCEXEC;

	ar0->i = fd;
}
Ejemplo n.º 26
0
static int32_t
write(int fd, void *p, int32_t n, int64_t off, int ispwrite)
{
	Proc *up = externup();
	int32_t r;
	Chan *c;

	r = n;

	p = validaddr(p, n, 0);
	n = 0;
	c = fdtochan(fd, OWRITE, 1, 1);
	if(waserror()) {
		if(!ispwrite){
			lock(&c->r.l);
			c->offset -= n;
			unlock(&c->r.l);
		}
		cclose(c);
		nexterror();
	}

	if(c->qid.type & QTDIR)
		error(Eisdir);

	n = r;

	if(off == ~0LL){	/* use and maintain channel's offset */
		lock(&c->r.l);
		off = c->offset;
		c->offset += n;
		unlock(&c->r.l);
	}

	r = c->dev->write(c, p, n, off);

	if(!ispwrite && r < n){
		lock(&c->r.l);
		c->offset -= n - r;
		unlock(&c->r.l);
	}

	poperror();
	cclose(c);

	return r;
}
Ejemplo n.º 27
0
long
sysfstat(ulong *arg)
{
	Chan *c;
	uint l;

	l = arg[2];
	validaddr(arg[1], l, 1);
	c = fdtochan(arg[0], -1, 0, 1);
	if(waserror()) {
		cclose(c);
		nexterror();
	}
	l = devtab[c->type]->stat(c, (uchar*)arg[1], l);
	poperror();
	cclose(c);
	return l;
}
Ejemplo n.º 28
0
long
_sysfstat(int fd, void *buf, long n)
{
	Chan *c;
	uint l;

	l = n;
	validaddr(buf, l, 1);
	c = fdtochan(fd, -1, 0, 1);
	if(waserror()) {
		cclose(c);
		nexterror();
	}
	l = devtab[c->type]->stat(c, buf, l);
	poperror();
	cclose(c);
	return l;
}
Ejemplo n.º 29
0
void
sysclose(Ar0* ar0, ...)
{
	int fd;
	va_list list;
	va_start(list, ar0);

	/*
	 * int close(int fd);
	 */
	fd = va_arg(list, int);
	va_end(list);

	fdtochan(fd, -1, 0, 0);
	fdclose(fd, 0);

	ar0->i = 0;
}
Ejemplo n.º 30
0
static long
kread(int fd, void *buf, long n, vlong *offp)
{
	int dir;
	Chan *c;
	vlong off;

	c = fdtochan(fd, OREAD, 1, 1);

	if(waserror()) {
		cclose(c);
		nexterror();
	}

	dir = c->qid.type&QTDIR;
	/*
	 * The offset is passed through on directories, normally. sysseek complains but
	 * pread is used by servers and e.g. exportfs that shouldn't need to worry about this issue.
	 */

	if(offp == nil)	/* use and maintain channel's offset */
		off = c->offset;
	else
		off = *offp;

	if(off < 0)
		error(Enegoff);

	if(dir && c->umh)
		n = unionread(c, buf, n);
	else
		n = devtab[c->type]->read(c, buf, n, off);

	if(offp == nil){
		lock(&c->ref.lk);
		c->offset += n;
		unlock(&c->ref.lk);
	}

	poperror();
	cclose(c);

	return n;
}