diff options
author | midipix <writeonce@midipix.org> | 2016-07-09 03:13:18 -0400 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2016-07-21 03:47:26 -0400 |
commit | 9cf365c988f71229f6132c60287b272ddfd2f294 (patch) | |
tree | e16014dfba3f130ead13dd366bfa2f19c00a95ea | |
parent | e9e742b0e892ca72576c745ac389eabb56c978a1 (diff) | |
download | ptycon-9cf365c988f71229f6132c60287b272ddfd2f294.tar.bz2 ptycon-9cf365c988f71229f6132c60287b272ddfd2f294.tar.xz |
debug: ptyc_dbg_cat(): implementation and integration.
-rw-r--r-- | project/common.mk | 1 | ||||
-rw-r--r-- | src/console/ptyc_console_alloc.c | 5 | ||||
-rw-r--r-- | src/debug/ptyc_dbg_cat.c | 167 |
3 files changed, 173 insertions, 0 deletions
diff --git a/project/common.mk b/project/common.mk index 1e54767..603b3fc 100644 --- a/project/common.mk +++ b/project/common.mk @@ -4,6 +4,7 @@ COMMON_SRCS = \ src/console/ptyc_console_poller.c \ src/console/ptyc_console_reader.c \ src/console/ptyc_console_writer.c \ + src/debug/ptyc_dbg_cat.c \ src/debug/ptyc_dbg_event.c \ src/debug/ptyc_dbg_oven.c \ src/debug/ptyc_dbg_raw.c \ diff --git a/src/console/ptyc_console_alloc.c b/src/console/ptyc_console_alloc.c index 16d1f80..16fb139 100644 --- a/src/console/ptyc_console_alloc.c +++ b/src/console/ptyc_console_alloc.c @@ -19,10 +19,12 @@ int ptyc_console_reader(void *); int ptyc_console_writer(void *);; int ptyc_console_poller(void *); +int ptyc_dbg_cat(struct ptyc_driver_ctx *); int ptyc_dbg_event(void *); int ptyc_dbg_oven(void *); int ptyc_dbg_raw(void *); + struct ptyc_loop_thread_ctx { nt_thread_start_routine * entry; struct ptyc_driver_ctx_impl * ictx; @@ -192,6 +194,9 @@ int ptyc_alloc_console(struct ptyc_driver_ctx * dctx) ictx,ptyc_dbg_raw))) return ptyc_set_status(dctx,status); + if ((status = ptyc_dbg_cat(dctx))) + return ptyc_set_status(dctx,status); + return ptyc_set_status(dctx,NT_STATUS_SUCCESS); } diff --git a/src/debug/ptyc_dbg_cat.c b/src/debug/ptyc_dbg_cat.c new file mode 100644 index 0000000..4e5e63b --- /dev/null +++ b/src/debug/ptyc_dbg_cat.c @@ -0,0 +1,167 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include <psxtypes/psxtypes.h> +#include <ntcon/ntcon.h> +#include <ntapi/ntapi.h> + +#include <ptycon/ptycon.h> +#include "ptycon_driver_impl.h" + +static int32_t ptyc_open(void ** hfile, void * hat, const char * arg) +{ + int32_t status; + nt_oa oa; + nt_iosb iosb; + nt_unicode_string path; + nt_unicode_conversion_params_utf8_to_utf16 params = {0,0,0,0,0,0,0,0,0}; + wchar16_t buffer[4096]; + wchar16_t * wch; + size_t nbytes; + + /* utf-8 --> utf-16 */ + params.src = (const unsigned char *)arg; + params.src_size_in_bytes= ntapi->tt_string_null_offset_multibyte(arg); + params.dst = buffer; + params.dst_size_in_bytes= sizeof(buffer); + + if ((status = ntapi->uc_convert_unicode_stream_utf8_to_utf16(¶ms))) + return status; + + /* convenience */ + for (wch=buffer, nbytes=params.bytes_written; nbytes; ) { + if (*wch == '/') + *wch = '\\'; + + nbytes -= sizeof(wchar16_t); + wch++; + } + + /* path */ + path.maxlen = 0; + path.strlen = (uint16_t)params.bytes_written; + path.buffer = buffer; + + /* oa */ + oa.len = sizeof(nt_oa); + oa.root_dir = hat; + oa.obj_name = &path; + oa.obj_attr = 0; + oa.sec_desc = 0; + oa.sec_qos = 0; + + /* open */ + return ntapi->zw_open_file( + hfile, + NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA, + &oa,&iosb, + NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE, + NT_FILE_NON_DIRECTORY_FILE | NT_FILE_SYNCHRONOUS_IO_ALERT); +} + +static int32_t ptyc_cat( + struct ptyc_driver_ctx* dctx, + void * hat, + const char * unit, + void * hevent) +{ + int32_t status; + void * hfile; + nt_iosb iosb; + intptr_t nread; + uintptr_t buffer[32768/sizeof(uintptr_t)]; + char * ch; + + if ((status = ptyc_open(&hfile,hat,unit))) + return status; + + status = ntapi->zw_read_file( + hfile, + 0,0,0, + &iosb, + buffer,sizeof(buffer), + 0,0); + + while (status == NT_STATUS_SUCCESS) { + ch = (char *)buffer; + nread = iosb.info; + + for ( ; nread; ) { + status = ntapi->pty_write( + dctx->cctx->hpts, + hevent,0,0, + &iosb, + ch,nread, + 0,0); + + if (status == NT_STATUS_PENDING) + status = ntapi->zw_wait_for_single_object( + hevent,NT_SYNC_ALERTABLE,0); + + if (status || iosb.status) { + ntapi->zw_close(hfile); + return status ? status : iosb.status; + } + + ch += iosb.info; + nread -= iosb.info; + } + + status = ntapi->zw_read_file( + hfile, + 0,0,0, + &iosb, + buffer,sizeof(buffer), + 0,0); + } + + ntapi->zw_close(hfile); + + return (status == NT_STATUS_END_OF_FILE) + ? NT_STATUS_SUCCESS + : status; +} + +int ptyc_dbg_cat(struct ptyc_driver_ctx * dctx) +{ + int32_t status; + void * hevent; + const char ** punit; + nt_rtdata * rtdata; + nt_peb * peb; + void * hat; + + if (!dctx->units[0]) + return 0; + + if ((status = ntapi->tt_create_private_event( + &hevent, + NT_NOTIFICATION_EVENT, + NT_EVENT_NOT_SIGNALED))) + return status; + + if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) + return status; + + if (!(peb = (nt_peb *)pe_get_peb_address())) + return NT_STATUS_INTERNAL_ERROR; + + if (!peb->process_params) + return NT_STATUS_INTERNAL_ERROR; + + hat = rtdata->hcwd + ? rtdata->hcwd + : peb->process_params->cwd_handle; + + for (punit=dctx->units, status=0; *punit && !status; punit++) + status = ptyc_cat( + dctx,hat, + *punit, + hevent); + + ntapi->zw_close(hevent); + return status; +} |