/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016--2017 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <pemagine/pemagine.h>
#include <ntapi/nt_status.h>
#include <ntapi/nt_object.h>
#include <ntapi/nt_thread.h>
#include <ntapi/nt_process.h>
#include <ntapi/nt_string.h>
#include <ntapi/ntapi.h>
#include <ptycon/ptycon.h>
#include "ptycon_driver_impl.h"
int ptyc_spawn(struct ptyc_driver_ctx * dctx)
{
int32_t status;
nt_spawn_process_params sparams;
nt_runtime_data rtctx;
struct ptyc_driver_ctx_impl * ictx;
struct ptyc_client_ctx * clctx;
nt_rtdata * self;
/* init */
if (!(ictx = ptyc_get_driver_ictx(dctx)))
return NT_STATUS_INVALID_HANDLE;
if (!dctx->cctx->eargv)
return NT_STATUS_SUCCESS;
self = ictx->rtdata;
clctx = &ictx->clctx;
/* sparams */
ntapi->tt_aligned_block_memset(
&sparams,0,sizeof(sparams));
sparams.rtctx = &rtctx;
sparams.patharg = dctx->cctx->eargv[0];
sparams.argv = dctx->cctx->eargv;
sparams.envp = self->envp;
sparams.hsession = self->hsession;
sparams.hroot = dctx->cctx->hroot
? dctx->cctx->hroot
: self->hroot;
/* rtctx */
ntapi->tt_aligned_block_memset(
&rtctx,0,sizeof(rtctx));
ntapi->tt_aligned_block_memcpy(
(uintptr_t *)&rtctx.cid_parent,
(uintptr_t *)&self->cid_self,
sizeof(nt_cid));
rtctx.hcwd = self->hcwd;
rtctx.hroot = sparams.hroot;
rtctx.tty_type = self->tty_type;
rtctx.tty_subtype = self->tty_subtype;
rtctx.tty_keys[0] = self->tty_keys[0];
rtctx.tty_keys[1] = self->tty_keys[1];
rtctx.tty_keys[2] = self->tty_keys[2];
rtctx.tty_keys[3] = self->tty_keys[3];
rtctx.tty_keys[4] = self->tty_keys[4];
rtctx.tty_keys[5] = self->tty_keys[5];
ntapi->tt_guid_copy(
&rtctx.tty_guid,
&self->tty_guid);
rtctx.hstdin = NT_INVALID_HANDLE_VALUE;
rtctx.hstdout = NT_INVALID_HANDLE_VALUE;
rtctx.hstderr = NT_INVALID_HANDLE_VALUE;
rtctx.stdin_type = NT_FILE_TYPE_PTY;
rtctx.stdout_type = NT_FILE_TYPE_PTY;
rtctx.stderr_type = NT_FILE_TYPE_PTY;
rtctx.ptyin [0] = clctx->clinfo.any[0];
rtctx.ptyin [1] = clctx->clinfo.any[1];
rtctx.ptyin [2] = clctx->clinfo.any[2];
rtctx.ptyin [3] = clctx->clinfo.any[3];
rtctx.ptyout[0] = clctx->clinfo.any[0];
rtctx.ptyout[1] = clctx->clinfo.any[1];
rtctx.ptyout[2] = clctx->clinfo.any[2];
rtctx.ptyout[3] = clctx->clinfo.any[3];
rtctx.ptyerr[0] = clctx->clinfo.any[0];
rtctx.ptyerr[1] = clctx->clinfo.any[1];
rtctx.ptyerr[2] = clctx->clinfo.any[2];
rtctx.ptyerr[3] = clctx->clinfo.any[3];
rtctx.ptyctl[0] = clctx->clinfo.any[0];
rtctx.ptyctl[1] = clctx->clinfo.any[1];
rtctx.ptyctl[2] = clctx->clinfo.any[2];
rtctx.ptyctl[3] = clctx->clinfo.any[3];
/* hoppla */
if ((status = ntapi->tt_spawn_native_process(&sparams)))
return status;
/* clctx */
clctx->hprocess = sparams.hprocess;
clctx->hthread = sparams.hthread;
clctx->cid.process_id = sparams.cid.process_id;
clctx->cid.thread_id = sparams.cid.thread_id;
/* child ready? */
if (!(sparams.eready.signal_state))
return NT_STATUS_GENERIC_COMMAND_FAILED;
/* finalize */
if (dctx->cctx->drvflags & (PTYC_DRIVER_DBG_RAW|PTYC_DRIVER_DBG_OVEN))
return NT_STATUS_SUCCESS;
if ((status = ntapi->pty_close(ictx->cctx.hpts)))
return status;
ictx->cctx.hpts = 0;
/* all done */
return NT_STATUS_SUCCESS;
}