Blame src/ptycon.c

0efa8c
/*********************************************************/
0efa8c
/*  ptycon: a pty-console bridge                         */
1f983d
/*  Copyright (C) 2016--2017  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
c56314
static const nt_guid ptycon_daemon_guid = PTYC_PORT_GUID_DAEMON;
c56314
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
e9e742
static int ptycon_dbg_helper(int32_t status)
e9e742
{
e9e742
	return status ? -1 : 0;
e9e742
}
e9e742
e9e742
static int ptycon_dbg_init(char ** argv)
e9e742
{
e9e742
	if (argv[1] && !(ntapi->tt_strcmp_multibyte(argv[1],"--wait")))
e9e742
		return ptycon_dbg_helper(
e9e742
			ntapi->tt_wait_for_dummy_event());
e9e742
	return 0;
e9e742
}
e9e742
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_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
e9e742
	/* early debug (optional) */
e9e742
	ptycon_dbg_init(argv);
e9e742
c56314
	/* daemon */
c56314
	if (!(ntapi->tt_guid_compare(
c56314
			&rtdata->srv_guid,
c56314
			&(nt_guid)NT_PORT_GUID_DEFAULT)))
c56314
		ntapi->tt_guid_copy(
c56314
			&rtdata->srv_guid,
c56314
			&ptycon_daemon_guid);
c56314
0efa8c
	/* no tty session? */
0fbfb0
	if (!rtdata->tty_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
0fbfb0
	port_attr.keys.key[0]	= rtdata->tty_keys[0];
0fbfb0
	port_attr.keys.key[1]	= rtdata->tty_keys[1];
0fbfb0
	port_attr.keys.key[2]	= rtdata->tty_keys[2];
0fbfb0
	port_attr.keys.key[3]	= rtdata->tty_keys[3];
0fbfb0
	port_attr.keys.key[4]	= rtdata->tty_keys[4];
0fbfb0
	port_attr.keys.key[5]	= rtdata->tty_keys[5];
0efa8c
0fbfb0
	ntapi->tt_guid_copy(
0efa8c
		&port_attr.guid,
0fbfb0
		&rtdata->tty_guid);
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 */
2bdcda
	if ((status = ntapi->pty_inherit_runtime_ctty(
2bdcda
			rtdata->hsession,
2bdcda
			rtdata)))
2bdcda
		return status;
0efa8c
2bdcda
	/* ctty identification */
2bdcda
	if (rtdata->hctty) {
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(
2bdcda
				rtdata->hctty,&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
faa67f
static int __stdcall ptycon_daemon_entry_point(void * hswap)
0efa8c
{
0efa8c
	int32_t		status;
0efa8c
	int		argc;
0efa8c
	char **		argv;
0efa8c
	char **		envp;
0efa8c
faa67f
	ntapi->zw_set_event(hswap,0);
faa67f
	ntapi->zw_close(hswap);
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;
faa67f
	void *			hswap;
0efa8c
0efa8c
	if ((status = ptyc_init()))
0efa8c
		return status;
0efa8c
faa67f
	if ((status = ntapi->tt_create_private_event(
faa67f
			&hswap,
faa67f
			NT_NOTIFICATION_EVENT,
faa67f
			NT_EVENT_NOT_SIGNALED)))
faa67f
		return status;
faa67f
0efa8c
	ntapi->tt_aligned_block_memset(
0efa8c
		&params,0,sizeof(params));
0efa8c
0efa8c
	params.hprocess		  = NT_CURRENT_PROCESS_HANDLE;
0efa8c
	params.start		  = ptycon_daemon_entry_point;
faa67f
	params.arg                = hswap;
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(&params)))
0efa8c
		ptycon_exit(status);
0efa8c
faa67f
	ntapi->zw_wait_for_single_object(
faa67f
		hswap,NT_SYNC_NON_ALERTABLE,0);
faa67f
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
}