Blame src/internal/toksvc_ntaio_impl.c

ca007d
/*********************************************************/
ca007d
/*  toksvc: a framework-native token broker service      */
ca007d
/*  Copyright (C) 2020  Z. Gilboa                        */
ca007d
/*  Released under GPLv2 and GPLv3; see COPYING.TOKSVC.  */
ca007d
/*********************************************************/
ca007d
ca007d
#include <ntapi/ntapi.h>
ca007d
#include <stdio.h>
ca007d
ca007d
extern const ntapi_vtbl * toks_ntapi;
ca007d
ca007d
int toks_sprintf(char * str, const char * fmt, ...)
ca007d
{
ca007d
	int     ret;
ca007d
	va_list ap;
ca007d
ca007d
	va_start(ap, fmt);
ca007d
	ret = toks_ntapi->vsprintf(str, fmt, ap);
ca007d
	va_end(ap);
ca007d
ca007d
	return ret;
ca007d
}
ca007d
ca007d
int toks_snprintf(char * str, size_t n, const char * fmt, ...)
ca007d
{
ca007d
	int     ret;
ca007d
	va_list ap;
ca007d
ca007d
	va_start(ap, fmt);
ca007d
	ret = toks_ntapi->vsnprintf(str, n, fmt, ap);
ca007d
	va_end(ap);
ca007d
ca007d
	return ret;
ca007d
}
ca007d
ca007d
int toks_isatty(int fildes)
ca007d
{
ca007d
	nt_runtime_data * rtdata;
ca007d
ca007d
	if ((toks_ntapi->tt_get_runtime_data(&rtdata,0)))
ca007d
		return 0;
ca007d
ca007d
	if (fildes == 0)
ca007d
		return (rtdata->stdin_type == NT_FILE_TYPE_PTY);
ca007d
ca007d
	else if (fildes == 1)
ca007d
		return (rtdata->stdout_type == NT_FILE_TYPE_PTY);
ca007d
ca007d
	else if (fildes == 2)
ca007d
		return (rtdata->stderr_type == NT_FILE_TYPE_PTY);
ca007d
ca007d
	else
ca007d
		return 0;
ca007d
}
ca007d
ca007d
int toks_write(int fd, const void * buf, size_t size)
ca007d
{
ca007d
	int32_t			status;
ca007d
	nt_runtime_data *	rtdata;
ca007d
	ntapi_zw_write_file *	iofn;
ca007d
	void *			hio;
ca007d
	void *			hevent;
ca007d
	int			fdtype;
ca007d
	nt_iosb			iosb;
ca007d
ca007d
	/* size */
ca007d
	if (size >= 0x80000000)
ca007d
		return NT_STATUS_INVALID_PARAMETER;
ca007d
ca007d
	/* rtdata */
ca007d
	if (toks_ntapi->tt_get_runtime_data(&rtdata,0))
ca007d
		return NT_STATUS_REINITIALIZATION_NEEDED;
ca007d
ca007d
	/* hio, io type */
ca007d
	if (fd == STDIN_FILENO) {
ca007d
		hio    = rtdata->hstdin;
ca007d
		fdtype = rtdata->stdin_type;
ca007d
ca007d
	} else if (fd == STDOUT_FILENO) {
ca007d
		hio    = rtdata->hstdout;
ca007d
		fdtype = rtdata->stdout_type;
ca007d
ca007d
	} else if (fd == STDERR_FILENO) {
ca007d
		hio    = rtdata->hstderr;
ca007d
		fdtype = rtdata->stderr_type;
ca007d
	} else {
ca007d
		return NT_STATUS_INVALID_PARAMETER;
ca007d
	}
ca007d
ca007d
	if (!hio)
ca007d
		return NT_STATUS_INVALID_HANDLE;
ca007d
ca007d
	/* iofn */
ca007d
	iofn = (fdtype ==  NT_FILE_TYPE_PTY)
ca007d
		? (ntapi_zw_write_file *)toks_ntapi->pty_write
ca007d
		: toks_ntapi->zw_write_file;
ca007d
ca007d
	/* hevent */
ca007d
	if ((status = toks_ntapi->tt_create_private_event(
ca007d
			&hevent,
ca007d
			NT_NOTIFICATION_EVENT,
ca007d
			NT_EVENT_NOT_SIGNALED)))
ca007d
		return status;
ca007d
ca007d
	/* iowrite */
ca007d
	status = iofn(
ca007d
		hio,hevent,
ca007d
		0,0,&iosb,
ca007d
		(void *)buf,size,
ca007d
		0,0);
ca007d
ca007d
	/* wait */
ca007d
	switch (status) {
ca007d
		case NT_STATUS_PENDING:
ca007d
			status = toks_ntapi->zw_wait_for_single_object(
ca007d
				hevent,0,0);
ca007d
			break;
ca007d
ca007d
		default:
ca007d
			iosb.status = status;
ca007d
			break;
ca007d
	}
ca007d
ca007d
	/* hevent */
ca007d
	toks_ntapi->zw_close(hevent);
ca007d
ca007d
	/* ret */
ca007d
	return iosb.status ? iosb.status : iosb.info;
ca007d
}