summaryrefslogtreecommitdiffhomepage
path: root/src/internal/ptycon_ntaio_impl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/ptycon_ntaio_impl.c')
-rw-r--r--src/internal/ptycon_ntaio_impl.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/internal/ptycon_ntaio_impl.c b/src/internal/ptycon_ntaio_impl.c
new file mode 100644
index 0000000..c990ff7
--- /dev/null
+++ b/src/internal/ptycon_ntaio_impl.c
@@ -0,0 +1,163 @@
+/*********************************************************/
+/* ptycon: a pty-console bridge */
+/* Copyright (C) 2016 Z. Gilboa */
+/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
+/*********************************************************/
+
+#include <ntapi/ntapi.h>
+
+extern const ntapi_vtbl * ptyc_ntapi;
+
+typedef struct ptyc_file {
+ void * hany;
+} FILE;
+
+int ptyc_fputs(const char * str, FILE * file)
+{
+ int32_t status;
+ nt_runtime_data * rtdata;
+ ntapi_zw_write_file * iofn;
+ void * hio;
+ void * hevent;
+ int fdtype;
+ size_t size;
+ size_t nbytes;
+ nt_iosb iosb;
+
+ /* rtdata */
+ if (ptyc_ntapi->tt_get_runtime_data(&rtdata,0))
+ return -1;
+
+ /* io type */
+ if (file == (void *)0) {
+ hio = rtdata->hstdin;
+ fdtype = rtdata->stdin_type;
+
+ } else if (file == (void *)1) {
+ hio = rtdata->hstdout;
+ fdtype = rtdata->stdout_type;
+
+ } else if (file == (void *)2) {
+ hio = rtdata->hstderr;
+ fdtype = rtdata->stderr_type;
+ } else {
+ return -1;
+ }
+
+ if (!hio)
+ return -1;
+
+ /* buffer */
+ size = ptyc_ntapi->tt_string_null_offset_multibyte(str);
+ nbytes = size;
+
+ /* 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 -1;
+
+ while (nbytes) {
+ /* iowrite */
+ status = iofn(
+ hio,hevent,
+ 0,0,&iosb,
+ (void *)str,
+ nbytes,0,0);
+
+ /* wait */
+ if (status == NT_STATUS_PENDING)
+ status = ptyc_ntapi->zw_wait_for_single_object(
+ hevent,0,0);
+
+ /* check */
+ if (status || iosb.status) {
+ ptyc_ntapi->zw_close(hevent);
+ return -1;
+ }
+
+ str += iosb.info;
+ nbytes -= iosb.info;
+ }
+
+ /* all done */
+ ptyc_ntapi->zw_close(
+ hevent);
+
+ return (int)size;
+}
+
+int ptyc_fprintf(FILE * file, const char * fmt, ...)
+{
+ va_list ap;
+ char * str;
+ size_t buffer[32768/sizeof(size_t)];
+
+ ptyc_ntapi->tt_aligned_block_memset(
+ buffer,0,sizeof(buffer));
+
+ str = (char *)buffer;
+
+ va_start(ap, fmt);
+ ptyc_ntapi->vsnprintf(str, sizeof(buffer), fmt, ap);
+ va_end(ap);
+
+ str[sizeof(buffer)-1] = 0;
+
+ return ptyc_fputs(str,file);
+}
+
+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_fileno(void * any)
+{
+ return (int)(intptr_t)any;
+}