/*********************************************************/ /* ptycon: a pty-console bridge */ /* Copyright (C) 2016--2017 SysDeer Technologies, LLC */ /* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ /*********************************************************/ #include #include #include #include #include #include #include #include #include #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.hntpipcdir = self->hntpipcdir; rtctx.hpidmapdir = self->hpidmapdir; rtctx.hpidanydir = self->hpidanydir; rtctx.hntpgrpdir = self->hntpgrpdir; rtctx.htmpfsldir = self->htmpfsldir; rtctx.htmpfslroot = self->htmpfslroot; rtctx.hshmctldir = self->hshmctldir; rtctx.hshmctlroot = self->hshmctlroot; rtctx.hshmkeydir = self->hshmkeydir; rtctx.hshmkeyroot = self->hshmkeyroot; 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; }