/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include 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; }