/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016 Z. Gilboa */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include #include #include #include "ptycon_init_impl.h" #include "ptycon_driver_impl.h" static const nt_tty_affiliation tty_affiliation __attr_section__(".midipix") = NT_TTY_AFFILIATION_DEFAULT; static void ptycon_exit(int code) { /* posix exit code? */ if (code <= 0xff) code <<= 8; ntapi->zw_terminate_process( NT_CURRENT_PROCESS_HANDLE, code); } static int32_t ptycon_start(int argc, char ** argv, char ** envp) { int32_t status; nt_runtime_data * rtdata; nt_port_attr port_attr; nt_pty_client_info client_info; nt_pty * hpty; nt_iosb iosb; /* rtdata */ if ((status = ntapi->tt_get_runtime_data(&rtdata,0))) return status; if (rtdata->argv) { argc = rtdata->argc; argv = rtdata->argv; envp = rtdata->envp; } /* no tty session? */ if (!rtdata->srv_keys[0]) return ptyc_main(argc,argv,envp); /* tty */ ntapi->tt_aligned_block_memset( &port_attr,0,sizeof(port_attr)); port_attr.type = NT_PORT_TYPE_SUBSYSTEM; port_attr.subtype = NT_PORT_SUBTYPE_DEFAULT; port_attr.keys.key[0] = rtdata->srv_keys[0]; port_attr.keys.key[1] = rtdata->srv_keys[1]; port_attr.keys.key[2] = rtdata->srv_keys[2]; port_attr.keys.key[3] = rtdata->srv_keys[3]; port_attr.keys.key[4] = rtdata->srv_keys[4]; port_attr.keys.key[5] = rtdata->srv_keys[5]; ntapi->tt_port_guid_from_type( &port_attr.guid, port_attr.type, port_attr.subtype); if ((status = ntapi->tty_join_session( &rtdata->hsession,0, &port_attr, NT_TTY_SESSION_PRIMARY))) return status; /* pty */ client_info.any[0] = rtdata->ptyany[0]; client_info.any[1] = rtdata->ptyany[1]; client_info.any[2] = rtdata->ptyany[2]; client_info.any[3] = rtdata->ptyany[3]; status = ntapi->pty_inherit( rtdata->hsession, &hpty, &client_info); /* ntaio */ if (status == NT_STATUS_SUCCESS) { if (rtdata->stdin_type == NT_FILE_TYPE_PTY) rtdata->hstdin = hpty; if (rtdata->stdout_type == NT_FILE_TYPE_PTY) rtdata->hstdout = hpty; if (rtdata->stderr_type == NT_FILE_TYPE_PTY) rtdata->hstderr = hpty; /* ctty identification */ client_info.any[0] = 0; client_info.any[1] = 0; client_info.any[2] = 0; client_info.any[3] = 0; if ((status = ntapi->pty_set( hpty,&iosb, &client_info,sizeof(client_info), NT_PTY_CLIENT_INFORMATION))) return status; } /* ready */ if (rtdata->hready) if ((status = ntapi->zw_set_event(rtdata->hready,0))) return status; /* main */ return ptyc_main(argc,argv,envp); } static int ptycon_daemon_entry_point(void * arg) { int32_t status; int argc; char ** argv; char ** envp; (void)arg; (void)tty_affiliation; if ((status = ntapi->tt_get_argv_envp_utf8( &argc,&argv,&envp, 0,0,0))) ptycon_exit(status); ptycon_exit(ptycon_start( argc,argv,envp)); return NT_STATUS_INTERNAL_ERROR; } int ptycon_entry_point(void) { int32_t status; nt_thread_params params; if ((status = ptyc_init())) return status; ntapi->tt_aligned_block_memset( ¶ms,0,sizeof(params)); params.hprocess = NT_CURRENT_PROCESS_HANDLE; params.start = ptycon_daemon_entry_point; params.stack_size_commit = 128 * 1024; params.stack_size_reserve = 128 * 1024; params.creation_flags = NT_CREATE_LOCAL_THREAD; if ((status = ntapi->tt_create_thread(¶ms))) ptycon_exit(status); ntapi->zw_close( params.hthread); ntapi->zw_terminate_thread( NT_CURRENT_THREAD_HANDLE, NT_STATUS_SUCCESS); return NT_STATUS_INTERNAL_ERROR; }