예제 #1
0
static int idesc_pipe_close(struct idesc_pipe *cur, struct idesc_pipe *other) {

	cur->idesc.idesc_amode = 0;

	if (other->idesc.idesc_amode) {
		idesc_notify(&other->idesc, POLLERR);
	} else {
		return 1;
	}

	return 0;
}
예제 #2
0
static ssize_t pipe_write(struct idesc *idesc, const void *buf, size_t nbyte) {
	struct pipe *pipe;
	const void *cbuf;
	int len;
	ssize_t res;

	assert(buf);
	assert(idesc);
	assert(idesc->idesc_ops == &idesc_pipe_ops);
	assert(idesc->idesc_amode == FS_MAY_WRITE);

	cbuf = buf;
	/* nbyte == 0 is ok to passthrough */

	pipe = idesc_to_pipe(idesc);
	mutex_lock(&pipe->mutex);
	do {
		/* No data can be readed at all */
		if (idesc_pipe_isclosed(&pipe->read_desc)) {
			res = -EPIPE;
			break;
		}

		/* Try to write some data */
		len = ring_buff_enqueue(pipe->buff, (void *) cbuf, nbyte);
		if (len > 0) {
			/* Notzero was written, adjust pointers and notify
 			 * (read end can't be closed) */
			cbuf += len;
			nbyte -= len;

			idesc_notify(&pipe->read_desc.idesc, POLLIN);
		}

		/* Have nothing to write, exit*/
		if (!nbyte) {
			res = cbuf - buf;
			break;
		}

		res = pipe_wait(idesc, pipe, POLLOUT | POLLERR);
	} while (res == 0);
	mutex_unlock(&pipe->mutex);

	return res;
}
예제 #3
0
static ssize_t pipe_read(struct idesc *idesc, void *buf, size_t nbyte) {
	struct pipe *pipe;
	ssize_t res;

	assert(buf);
	assert(idesc);
	assert(idesc->idesc_ops == &idesc_pipe_ops);
	assert(idesc->idesc_amode == FS_MAY_READ);

	if (!nbyte) {
		return 0;
	}

	pipe = idesc_to_pipe(idesc);
	mutex_lock(&pipe->mutex);
	do {
		res = ring_buff_dequeue(pipe->buff, buf, nbyte);

		if (idesc_pipe_isclosed(&pipe->write_desc)) {
			/* Nothing to do, what's read, that's read */
			break;
		}

		if (res > 0) {
			/* Smth read, notify write end (can't be closed,
 			 * checked already) */
			idesc_notify(&pipe->write_desc.idesc, POLLOUT);
			break;
		}

		res = pipe_wait(idesc, pipe, POLLIN | POLLERR);
	} while (res == 0);
	mutex_unlock(&pipe->mutex);

	return res;
}
예제 #4
0
static inline void tty_notify(struct tty *t, int mask) {
	assert(t);
	if (t->idesc)
		idesc_notify(t->idesc, mask);
}