Exemplo n.º 1
0
arg_t _pipe(void)
{
	int8_t u1, u2, oft1, oft2;
	inoptr ino;

/* bug fix SN */
	if ((u1 = uf_alloc()) == -1)
		goto nogood;
	if ((oft1 = oft_alloc()) == -1)
		goto nogood;
	udata.u_files[u1] = oft1;

	if ((u2 = uf_alloc()) == -1)
		goto nogood2;
	if ((oft2 = oft_alloc()) == -1)
		goto nogood2;

	if (!(ino = i_open(root_dev, 0))) {
		oft_deref(oft2);
		goto nogood2;
	}

	udata.u_files[u2] = oft2;

	of_tab[oft1].o_ptr = 0;
	of_tab[oft1].o_inode = ino;
	of_tab[oft1].o_access = O_RDONLY;

	of_tab[oft2].o_ptr = 0;
	of_tab[oft2].o_inode = ino;
	of_tab[oft2].o_access = O_WRONLY;

	++ino->c_refs;
	ino->c_node.i_mode = F_PIPE | 0777;	/* No permissions necessary on pipes */
	ino->c_node.i_nlink = 0;	/* a pipe is not in any directory */

	// write results to userspace
	uputw(u1, fildes);
	uputw(u2, fildes + 1);
	return (0);

      nogood2:
	oft_deref(oft1);
	udata.u_files[u1] = NO_FILE;
      nogood:
	return (-1);
}
Exemplo n.º 2
0
arg_t make_socket(struct sockinfo *s, struct socket **np)
{
	struct socket *n;
	int8_t uindex;
	int8_t oftindex;
	inoptr ino;

	/* RAW sockets are superuser */
	if (s->priv && esuper())
		return -1;

	if (np)
		n = *np;
	else {
		n = alloc_socket();
		if (n == NULL)
			return -1;
	}
	n->s_type = s - socktypes;	/* Pointer or uint8_t best ? */
	n->s_state = SS_INIT;

	if (net_init(n) == -1)
		goto nosock;

	/* Start by getting the file and inode table entries */
	if ((uindex = uf_alloc()) == -1)
		goto nosock;
	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	/* We need an inode : FIXME - do we want a pipedev aka Unix ? */
	if (!(ino = i_open(root_dev, 0)))
		goto noalloc;
	/* All good - now set it up */
	/* The nlink cheat needs to be taught to fsck! */
	ino->c_node.i_mode = F_SOCK | 0777;
	ino->c_node.i_nlink = n->s_num;	/* Cheat !! */
	ino->c_readers = 1;
	ino->c_writers = 1;

	of_tab[oftindex].o_inode = ino;
	of_tab[oftindex].o_access = O_RDWR;

	udata.u_files[uindex] = oftindex;

	sock_wait_leave(n, 0, SS_INIT);
	if (np)
		*np = n;
	return uindex;

noalloc:
	oft_deref(oftindex);	/* Will call i_deref! */
nooft:
	udata.u_files[uindex] = NO_FILE;
nosock:
	n->s_state = SS_UNUSED;
	return -1;
}
Exemplo n.º 3
0
arg_t _dup(void)
{
	int8_t newd;
	if (getinode(oldd) == NULLINODE)
		return (-1);
	if ((newd = uf_alloc()) == -1)
		return (-1);

	udata.u_files[newd] = udata.u_files[oldd];
	++of_tab[udata.u_files[oldd]].o_refs;

	return (newd);
}
Exemplo n.º 4
0
arg_t make_socket(struct sockinfo *s, int8_t *np)
{
	int8_t n;
	int8_t uindex;
	int8_t oftindex;
	inoptr ino;

	/* RAW sockets are superuser */
	if (s->priv && esuper())
		return -1;

	/* Start by getting the file and inode table entries */
	if ((uindex = uf_alloc()) == -1)
		return -1;
	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	if (np)
		n = *np;
	else {
		n = alloc_socket();
		if (n == -1)
			goto noalloc;
	}
	/* We need an inode : FIXME - do we want a pipedev aka Unix ? */
	if (!(ino = i_open(root_dev, 0)))
		goto noalloc;
	/* All good - now set it up */
	/* The nlink cheat needs to be taught to fsck! */
	ino->c_node.i_mode = F_SOCK | 0777;
	ino->c_node.i_nlink = n;	/* Cheat !! */

	of_tab[oftindex].o_inode = ino;
	of_tab[oftindex].o_access = O_RDWR;

	udata.u_files[uindex] = oftindex;

	sockets[n].s_inode = ino;
	sockets[n].s_type = s - socktypes;	/* Pointer or uint8_t best ? */
	sockets[n].s_state = SS_UNCONNECTED;

	if (np)
		*np = n;
	return uindex;

noalloc:
	oft_deref(oftindex);	/* Will call i_deref! */
nooft:
	udata.u_files[uindex] = NO_FILE;
	return -1;
}
Exemplo n.º 5
0
arg_t _open(void)
{
	int8_t uindex;
	int8_t oftindex;
	staticfast inoptr ino;
	int16_t perm;
	staticfast inoptr parent;
	char fname[FILENAME_LEN + 1];
	int trunc;
	int r;
	int w;
	int j;

	parent = NULLINODE;

	trunc = flag & O_TRUNC;
	r = (flag + 1) & 1;
	w = (flag + 1) & 2;

	if (O_ACCMODE(flag) == 3 || (flag & O_BADBITS)) {
		udata.u_error = EINVAL;
		return (-1);
	}
	if ((uindex = uf_alloc()) == -1)
		return (-1);

	if ((oftindex = oft_alloc()) == -1)
		goto nooft;

	ino = n_open(name, &parent);
	if (ino) {
		i_deref(parent);
		/* O_EXCL test */
		if ((flag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) {
			udata.u_error = EEXIST;
			goto idrop;
		}
	} else {
		/* The n_open failed */
		if (udata.u_error == EFAULT)
			goto cantopen;
		/* New file */
		if (!(flag & O_CREAT)) {
			udata.u_error = ENOENT;
			goto cantopen;
		}
		filename(name, fname);
		/* newfile drops parent for us */
		if (parent && (ino = newfile(parent, fname))) {
			ino->c_node.i_mode =
			    (F_REG | (mode & MODE_MASK & ~udata.u_mask));
			setftime(ino, A_TIME | M_TIME | C_TIME);
			wr_inode(ino);
		} else {
			udata.u_error = ENFILE;	/* FIXME, should be set in newfile
						   not bodged to a guessed code */
			goto cantopen;
		}
	}
	/* Book our slot in case we block opening a device */
	of_tab[oftindex].o_inode = ino;

	perm = getperm(ino);
	if ((r && !(perm & OTH_RD)) || (w && !(perm & OTH_WR))) {
		udata.u_error = EACCES;
		goto cantopen;
	}
	if (w) {
		if (getmode(ino) == F_DIR ) {
			udata.u_error = EISDIR;
			goto cantopen;
		}
		if (ino->c_flags & CRDONLY) {
			udata.u_error = EROFS;
			goto cantopen;
		}
	}

	if (isdevice(ino)) {
		inoptr *iptr = &of_tab[oftindex].o_inode;
		/* d_open may block and thus ino may become invalid as may
		   parent (but we don't need it again). It may also be changed
		   by the call to dev_openi */

		if (dev_openi(iptr, flag) != 0)
			goto cantopen;

		/* May have changed */
		/* get the static pointer back in case it changed via dev 
		   usage or just because we blocked */
		ino = *iptr;
	}

	if (trunc && getmode(ino) == F_REG) {
		if (f_trunc(ino))
			goto idrop;
		for (j = 0; j < OFTSIZE; ++j)
			/* Arguably should fix at read/write */
			if (of_tab[j].o_inode == ino)
				of_tab[j].o_ptr = 0;
	}

	udata.u_files[uindex] = oftindex;

	of_tab[oftindex].o_ptr = 0;
	of_tab[oftindex].o_access = flag;	/* Save the low bits only */
	if (flag & O_CLOEXEC)
		udata.u_cloexec |= (1 << oftindex);
	/* FIXME: ATIME ? */

/*
 *         Sleep process if no writer or reader
 */
	if (getmode(ino) == F_PIPE && of_tab[oftindex].o_refs == 1
	    && !(flag & O_NDELAY))
		psleep(ino);

        /* From the moment of the psleep ino is invalid */

	return (uindex);
      idrop:
	i_deref(ino);
      cantopen:
	oft_deref(oftindex);	/* This will call i_deref() */
      nooft:
	udata.u_files[uindex] = NO_FILE;
	return (-1);
}