Blame src/internal/ptycon_ntaio_impl.c

0efa8c
/*********************************************************/
0efa8c
/*  ptycon: a pty-console bridge                         */
1f983d
/*  Copyright (C) 2016--2017  Z. Gilboa                  */
0efa8c
/*  Released under GPLv2 and GPLv3; see COPYING.PTYCON.  */
0efa8c
/*********************************************************/
0efa8c
0efa8c
#include <ntapi/ntapi.h>
af27df
#include <stdio.h>
0efa8c
0efa8c
extern const ntapi_vtbl * ptyc_ntapi;
0efa8c
0efa8c
typedef struct ptyc_file {
0efa8c
        void *  hany;
0efa8c
} FILE;
0efa8c
0efa8c
int ptyc_fputs(const char * str, FILE * file)
0efa8c
{
0efa8c
	int32_t			status;
0efa8c
	nt_runtime_data *	rtdata;
0efa8c
	ntapi_zw_write_file *	iofn;
0efa8c
	void *			hio;
0efa8c
	void *			hevent;
0efa8c
	int			fdtype;
0efa8c
	size_t			size;
0efa8c
	size_t			nbytes;
0efa8c
	nt_iosb			iosb;
0efa8c
0efa8c
	/* rtdata */
0efa8c
	if (ptyc_ntapi->tt_get_runtime_data(&rtdata,0))
0efa8c
		return -1;
0efa8c
0efa8c
	/* io type */
0efa8c
	if (file == (void *)0) {
0efa8c
		hio    = rtdata->hstdin;
0efa8c
		fdtype = rtdata->stdin_type;
0efa8c
0efa8c
	} else if (file == (void *)1) {
0efa8c
		hio    = rtdata->hstdout;
0efa8c
		fdtype = rtdata->stdout_type;
0efa8c
0efa8c
	} else if (file == (void *)2) {
0efa8c
		hio    = rtdata->hstderr;
0efa8c
		fdtype = rtdata->stderr_type;
0efa8c
	} else {
0efa8c
		return -1;
0efa8c
	}
0efa8c
0efa8c
	if (!hio)
0efa8c
		return -1;
0efa8c
0efa8c
	/* buffer */
0efa8c
	size   = ptyc_ntapi->tt_string_null_offset_multibyte(str);
0efa8c
	nbytes = size;
0efa8c
0efa8c
	/* iofn */
0efa8c
	iofn = (fdtype ==  NT_FILE_TYPE_PTY)
0efa8c
		? (ntapi_zw_write_file *)ptyc_ntapi->pty_write
0efa8c
		: ptyc_ntapi->zw_write_file;
0efa8c
0efa8c
	/* hevent */
0efa8c
	if ((status = ptyc_ntapi->tt_create_private_event(
0efa8c
			&hevent,
0efa8c
			NT_NOTIFICATION_EVENT,
0efa8c
			NT_EVENT_NOT_SIGNALED)))
0efa8c
		return -1;
0efa8c
0efa8c
	while (nbytes) {
0efa8c
		/* iowrite */
0efa8c
		status = iofn(
0efa8c
			hio,hevent,
0efa8c
			0,0,&iosb,
0efa8c
			(void *)str,
a79b9f
			(uint32_t)nbytes,0,0);
0efa8c
0efa8c
		/* wait */
0efa8c
		if (status == NT_STATUS_PENDING)
0efa8c
			status = ptyc_ntapi->zw_wait_for_single_object(
0efa8c
				hevent,0,0);
0efa8c
0efa8c
		/* check */
0efa8c
		if (status || iosb.status) {
0efa8c
			ptyc_ntapi->zw_close(hevent);
0efa8c
			return -1;
0efa8c
		}
0efa8c
0efa8c
		str    += iosb.info;
0efa8c
		nbytes -= iosb.info;
0efa8c
	}
0efa8c
0efa8c
	/* all done */
0efa8c
	ptyc_ntapi->zw_close(
0efa8c
		hevent);
0efa8c
0efa8c
	return (int)size;
0efa8c
}
0efa8c
0efa8c
int ptyc_fprintf(FILE * file, const char * fmt, ...)
0efa8c
{
0efa8c
	va_list	ap;
0efa8c
	char *	str;
0efa8c
	size_t	buffer[32768/sizeof(size_t)];
0efa8c
0efa8c
	ptyc_ntapi->tt_aligned_block_memset(
0efa8c
		buffer,0,sizeof(buffer));
0efa8c
0efa8c
	str = (char *)buffer;
0efa8c
0efa8c
	va_start(ap, fmt);
0efa8c
	ptyc_ntapi->vsnprintf(str, sizeof(buffer), fmt, ap);
0efa8c
	va_end(ap);
0efa8c
0efa8c
	str[sizeof(buffer)-1] = 0;
0efa8c
0efa8c
	return ptyc_fputs(str,file);
0efa8c
}
0efa8c
0efa8c
int ptyc_sprintf(char * str, const char * fmt, ...)
0efa8c
{
0efa8c
	int     ret;
0efa8c
	va_list ap;
0efa8c
0efa8c
	va_start(ap, fmt);
0efa8c
	ret = ptyc_ntapi->vsprintf(str, fmt, ap);
0efa8c
	va_end(ap);
0efa8c
0efa8c
	return ret;
0efa8c
}
0efa8c
0efa8c
int ptyc_snprintf(char * str, size_t n, const char * fmt, ...)
0efa8c
{
0efa8c
	int     ret;
0efa8c
	va_list ap;
0efa8c
0efa8c
	va_start(ap, fmt);
0efa8c
	ret = ptyc_ntapi->vsnprintf(str, n, fmt, ap);
0efa8c
	va_end(ap);
0efa8c
0efa8c
	return ret;
0efa8c
}
0efa8c
0efa8c
int ptyc_isatty(int fildes)
0efa8c
{
0efa8c
	nt_runtime_data * rtdata;
0efa8c
0efa8c
	if ((ptyc_ntapi->tt_get_runtime_data(&rtdata,0)))
0efa8c
		return 0;
0efa8c
0efa8c
	if (fildes == 0)
0efa8c
		return (rtdata->stdin_type == NT_FILE_TYPE_PTY);
0efa8c
0efa8c
	else if (fildes == 1)
0efa8c
		return (rtdata->stdout_type == NT_FILE_TYPE_PTY);
0efa8c
0efa8c
	else if (fildes == 2)
0efa8c
		return (rtdata->stderr_type == NT_FILE_TYPE_PTY);
0efa8c
0efa8c
	else
0efa8c
		return 0;
0efa8c
}
0efa8c
0efa8c
int ptyc_fileno(void * any)
0efa8c
{
0efa8c
	return (int)(intptr_t)any;
0efa8c
}
af27df
af27df
int ptyc_write(int fd, const void * buf, size_t size)
af27df
{
af27df
	int32_t			status;
af27df
	nt_runtime_data *	rtdata;
af27df
	ntapi_zw_write_file *	iofn;
af27df
	void *			hio;
af27df
	void *			hevent;
af27df
	int			fdtype;
af27df
	nt_iosb			iosb;
af27df
af27df
	/* size */
af27df
	if (size >= 0x80000000)
af27df
		return NT_STATUS_INVALID_PARAMETER;
af27df
af27df
	/* rtdata */
af27df
	if (ptyc_ntapi->tt_get_runtime_data(&rtdata,0))
af27df
		return NT_STATUS_REINITIALIZATION_NEEDED;
af27df
af27df
	/* hio, io type */
af27df
	if (fd == STDIN_FILENO) {
af27df
		hio    = rtdata->hstdin;
af27df
		fdtype = rtdata->stdin_type;
af27df
af27df
	} else if (fd == STDOUT_FILENO) {
af27df
		hio    = rtdata->hstdout;
af27df
		fdtype = rtdata->stdout_type;
af27df
af27df
	} else if (fd == STDERR_FILENO) {
af27df
		hio    = rtdata->hstderr;
af27df
		fdtype = rtdata->stderr_type;
af27df
	} else {
af27df
		return NT_STATUS_INVALID_PARAMETER;
af27df
	}
af27df
af27df
	if (!hio)
af27df
		return NT_STATUS_INVALID_HANDLE;
af27df
af27df
	/* iofn */
af27df
	iofn = (fdtype ==  NT_FILE_TYPE_PTY)
af27df
		? (ntapi_zw_write_file *)ptyc_ntapi->pty_write
af27df
		: ptyc_ntapi->zw_write_file;
af27df
af27df
	/* hevent */
af27df
	if ((status = ptyc_ntapi->tt_create_private_event(
af27df
			&hevent,
af27df
			NT_NOTIFICATION_EVENT,
af27df
			NT_EVENT_NOT_SIGNALED)))
af27df
		return status;
af27df
af27df
	/* iowrite */
af27df
	status = iofn(
af27df
		hio,hevent,
af27df
		0,0,&iosb,
af27df
		(void *)buf,size,
af27df
		0,0);
af27df
af27df
	/* wait */
af27df
	if (status == NT_STATUS_PENDING)
af27df
		status = ptyc_ntapi->zw_wait_for_single_object(
af27df
			hevent,0,0);
af27df
af27df
	/* hevent */
af27df
	ptyc_ntapi->zw_close(hevent);
af27df
af27df
	/* ret */
af27df
	return status ? status : iosb.status;
af27df
}