Exemplo n.º 1
0
static bool FetchTimespec(struct timespec* dest, const struct timespec* user)
{
	if ( !user )
		dest->tv_sec = -1,
		dest->tv_nsec = 0;
	else if ( !CopyFromUser(dest, user, sizeof(*dest)) )
		return false;
	return true;
}
Exemplo n.º 2
0
static struct pollfd* CopyFdsFromUser(struct pollfd* user_fds, size_t nfds)
{
	size_t size = sizeof(struct pollfd) * nfds;
	struct pollfd* fds = new struct pollfd[nfds];
	if ( !fds )
		return NULL;
	if ( !CopyFromUser(fds, user_fds, size) )
	{
		delete[] fds;
		return NULL;
	}
	return fds;
}
Exemplo n.º 3
0
NTSTATUS NtSetTimer(
	HANDLE TimerHandle,
	PLARGE_INTEGER DueTime,
	PTIMER_APC_ROUTINE TimerApcRoutine,
	PVOID TimerContext,
	BOOLEAN Resume,
	LONG Period,
	PBOOLEAN PreviousState)
{
	LARGE_INTEGER due;

	NTSTATUS r = CopyFromUser( &due, DueTime, sizeof due );
	if (r < STATUS_SUCCESS)
		return r;

	TRACE("due = %llx\n", due.QuadPart);

	NTTIMER* timer = 0;
	r = ObjectFromHandle( timer, TimerHandle, TIMER_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

	if (PreviousState)
	{
		r = VerifyForWrite( PreviousState, sizeof *PreviousState );
		if (r < STATUS_SUCCESS)
			return r;
	}

	BOOLEAN prev = FALSE;
	r = timer->Set( due, (PKNORMAL_ROUTINE)TimerApcRoutine, TimerContext, Resume, Period, prev );
	if (r == STATUS_SUCCESS && PreviousState )
		CopyToUser( PreviousState, &prev, sizeof prev );

	return r;
}
Exemplo n.º 4
0
Arquivo: api.c Projeto: Cppowboy/mtcp
/*----------------------------------------------------------------------------*/
int
mtcp_writev(mctx_t mctx, int sockid, struct iovec *iov, int numIOV)
{
	mtcp_manager_t mtcp;
	socket_map_t socket;
	tcp_stream *cur_stream;
	struct tcp_send_vars *sndvar;
	int ret, to_write, i;

	mtcp = GetMTCPManager(mctx);
	if (!mtcp) {
		return -1;
	}

	if (sockid < 0 || sockid >= CONFIG.max_concurrency) {
		TRACE_API("Socket id %d out of range.\n", sockid);
		errno = EBADF;
		return -1;
	}

	socket = &mtcp->smap[sockid];
	if (socket->socktype == MTCP_SOCK_UNUSED) {
		TRACE_API("Invalid socket id: %d\n", sockid);
		errno = EBADF;
		return -1;
	}

	if (socket->socktype != MTCP_SOCK_STREAM) {
		TRACE_API("Not an end socket. id: %d\n", sockid);
		errno = ENOTSOCK;
		return -1;
	}
	
	cur_stream = socket->stream;
	if (!cur_stream || 
			!(cur_stream->state == TCP_ST_ESTABLISHED || 
			  cur_stream->state == TCP_ST_CLOSE_WAIT)) {
		errno = ENOTCONN;
		return -1;
	}

	sndvar = cur_stream->sndvar;
	SBUF_LOCK(&sndvar->write_lock);
#if BLOCKING_SUPPORT
	if (!(socket->opts & MTCP_NONBLOCK)) {
		while (sndvar->snd_wnd <= 0) {
			TRACE_SNDBUF("Waiting for available sending window...\n");
			if (!cur_stream || cur_stream->state != TCP_ST_ESTABLISHED) {
				SBUF_UNLOCK(&sndvar->write_lock);
				errno = EINTR;
				return -1;
			}
			pthread_cond_wait(&sndvar->write_cond, &sndvar->write_lock);
			TRACE_SNDBUF("Sending buffer became ready! snd_wnd: %u\n", 
					sndvar->snd_wnd);
		}
	}
#endif

	/* write from the vectored buffers */ 
	to_write = 0;
	for (i = 0; i < numIOV; i++) {
		if (iov[i].iov_len <= 0)
			continue;

		ret = CopyFromUser(mtcp, cur_stream, iov[i].iov_base, iov[i].iov_len);
		if (ret <= 0)
			break;

		to_write += ret;

		if (ret < iov[i].iov_len)
			break;
	}
	SBUF_UNLOCK(&sndvar->write_lock);

	if (to_write > 0 && !(sndvar->on_sendq || sndvar->on_send_list)) {
		SQ_LOCK(&mtcp->ctx->sendq_lock);
		sndvar->on_sendq = TRUE;
		StreamEnqueue(mtcp->sendq, cur_stream);		/* this always success */
		SQ_UNLOCK(&mtcp->ctx->sendq_lock);
		mtcp->wakeup_flag = TRUE;
	}

	if (to_write == 0 && (socket->opts & MTCP_NONBLOCK)) {
		to_write = -1;
		errno = EAGAIN;
	}

	/* if there are remaining sending buffer, generate write event */
	if (sndvar->snd_wnd > 0) {
		if (socket->epoll & MTCP_EPOLLOUT && !(socket->epoll & MTCP_EPOLLET)) {
			AddEpollEvent(mtcp->ep, 
					USR_SHADOW_EVENT_QUEUE, socket, MTCP_EPOLLOUT);
#if BLOCKING_SUPPORT
		} else if (!(socket->opts & MTCP_NONBLOCK)) {
			if (!cur_stream->on_snd_br_list) {
				cur_stream->on_snd_br_list = TRUE;
				TAILQ_INSERT_TAIL(&mtcp->snd_br_list, 
						cur_stream, sndvar->snd_br_link);
				mtcp->snd_br_list_cnt++;
			}
#endif
		}
	}

	TRACE_API("Stream %d: mtcp_writev() returning %d\n", 
			cur_stream->id, to_write);
	return to_write;
}
Exemplo n.º 5
0
// blocking
NTSTATUS NTAPI NtRemoveIoCompletion(
	HANDLE IoCompletionHandle,
	PULONG IoCompletionKey,
	PULONG IoCompletionValue,
	PIO_STATUS_BLOCK IoStatusBlock,
	PLARGE_INTEGER TimeOut)
{
	NTSTATUS r;

	TRACE("%p %p %p %p %p\n", IoCompletionHandle, IoCompletionKey,
		  IoCompletionValue, IoStatusBlock, TimeOut);

	COMPLETION_PORT_IMPL *port = 0;
	r = ObjectFromHandle( port, IoCompletionHandle, IO_COMPLETION_MODIFY_STATE );
	if (r < STATUS_SUCCESS)
		return r;

	if (IoCompletionKey)
	{
		r = VerifyForWrite( IoCompletionKey, sizeof *IoCompletionKey );
		if (r < STATUS_SUCCESS)
			return r;
	}

	if (IoCompletionValue)
	{
		r = VerifyForWrite( IoCompletionValue, sizeof *IoCompletionValue );
		if (r < STATUS_SUCCESS)
			return r;
	}

	if (IoStatusBlock)
	{
		r = VerifyForWrite( IoStatusBlock, sizeof *IoStatusBlock );
		if (r < STATUS_SUCCESS)
			return r;
	}

	LARGE_INTEGER t;
	t.QuadPart = 0LL;
	if (TimeOut)
	{
		r = CopyFromUser( &t, TimeOut, sizeof t );
		if (r < STATUS_SUCCESS)
			return r;
		TimeOut = &t;
	}

	ULONG key = 0, val = 0;
	IO_STATUS_BLOCK iosb;
	iosb.Status = 0;
	iosb.Information = 0;
	port->Remove( key, val, iosb.Status, iosb.Information, TimeOut );

	if (IoCompletionKey)
		CopyToUser( IoCompletionKey, &key, sizeof key );

	if (IoCompletionValue)
		CopyToUser( IoCompletionValue, &val, sizeof val );

	if (IoStatusBlock)
		CopyToUser( IoStatusBlock, &iosb, sizeof iosb );

	return r;
}