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