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