Files
TeslaRel410/emulator/pod-launch/ChildProcess.cs
T
CydandClaude Opus 4.8 9df87f2c01 Deploy: pod install scaffold -- supervisor entry-point, postinstall, packaging
Network-agnostic, air-gapped pod install for the two DOSBox titles (BT/RP 4.10),
fitting the existing TeslaConsole/TeslaLauncher pod-bay architecture.

emulator/DEPLOYMENT-PLAN.md
  Full design: bridge on the one NIC (pods form a source-proven P2P TCP mesh, so
  NAT/slirp is out); launcher keeps the bay IP, the DOSBox guest bridges at
  bayIP+100 (egg/mesh/game endpoint); two-edit +100 convention (postinstall +
  console DOSBox flag); static, air-gapped, <=32 pods.

emulator/pod-launch/  (C# net8 supervising entry-point)
  Creates a Job Object (KILL_ON_JOB_CLOSE), launches DOSBox-X + the render bridge
  into it and blocks -- kill this process and both die (kernel-enforced, even on
  a hard TerminateProcess of a hung session; verified). Mode dispatch: bt/rp
  wired (also serve camera + live mission-review via egg hostType); review +
  diagnostics recognized but fail clean until their DOS launch args are known.

emulator/deploy/  (install side)
  postinstall.bat (thin elevated wrapper) + configure.ps1 (NIC detect, realnic
  bind as a contiguous letter-leading GUID fragment, game IP = bayIP+100, stable
  MAC, render net_*.conf templates, stamp WATTCP.CFG my_ip) + tokenized conf
  templates + package.ps1 (assemble the zip). Render/bind/stamp + packaging
  verified against a scratch tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 10:36:30 -05:00

54 lines
2.2 KiB
C#

// Launch a child process and put it in the job immediately, redirecting its
// stdout/stderr to log files (matches the pod_out/err.txt + bridge_out/err.txt
// the old launch_pod.ps1 produced).
//
// The assign happens right after Start(), before DOSBox/pythonw has a chance to
// spawn anything, so the whole tree is captured. (A CREATE_SUSPENDED launch
// would close even that microscopic gap; neither of these children forks at
// startup, so Start()+assign is sufficient here.)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
namespace VwePod
{
internal static class ChildProcess
{
public static Process StartInJob(
JobObject job, string exe, string args,
IDictionary<string, string> extraEnv,
string outPath, string errPath, string workingDir)
{
var psi = new ProcessStartInfo
{
FileName = exe,
Arguments = args,
UseShellExecute = false, // inherit our env; allow job assign
CreateNoWindow = false, // children make their own windows
RedirectStandardOutput = true,
RedirectStandardError = true,
};
if (!string.IsNullOrEmpty(workingDir)) psi.WorkingDirectory = workingDir;
if (extraEnv != null)
foreach (var kv in extraEnv) psi.Environment[kv.Key] = kv.Value;
var proc = new Process { StartInfo = psi };
var outWriter = new StreamWriter(outPath, false) { AutoFlush = true };
var errWriter = new StreamWriter(errPath, false) { AutoFlush = true };
proc.OutputDataReceived += (s, e) => { if (e.Data != null) lock (outWriter) outWriter.WriteLine(e.Data); };
proc.ErrorDataReceived += (s, e) => { if (e.Data != null) lock (errWriter) errWriter.WriteLine(e.Data); };
proc.Exited += (s, e) => { try { outWriter.Dispose(); errWriter.Dispose(); } catch { } };
proc.EnableRaisingEvents = true;
proc.Start();
job.Add(proc.Handle); // capture before it can spawn a child
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
return proc;
}
}
}