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