|
|
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 |
}
|