// Beweis-Test 2: Kann Node eine Windows-Arbeitsgruppe (Job Object) setzen, // die Kindprozesse mitreisst, wenn der Elternprozess HART beendet wird? // Das ist der Mechanismus aus SAVEPOINT v4.0-rc10 — ohne ihn ueberlebt // makemkvcon Rippy und haelt das Laufwerk fest. const koffi = require('koffi'); const { spawn } = require('child_process'); const kernel32 = koffi.load('kernel32.dll'); const CreateJobObjectW = kernel32.func('void* __stdcall CreateJobObjectW(void *lpJobAttributes, str16 lpName)'); const SetInformationJobObject = kernel32.func('bool __stdcall SetInformationJobObject(void *hJob, int JobObjectInformationClass, void *lpJobObjectInformation, uint32_t cbJobObjectInformationLength)'); const AssignProcessToJobObject = kernel32.func('bool __stdcall AssignProcessToJobObject(void *hJob, void *hProcess)'); const GetCurrentProcess = kernel32.func('void* __stdcall GetCurrentProcess()'); const GetLastError = kernel32.func('uint32_t __stdcall GetLastError()'); // JobObjectExtendedLimitInformation = 9 (winnt.h) const JobObjectExtendedLimitInformation = 9; // JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000 (winnt.h) const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x2000; const job = CreateJobObjectW(null, null); if (koffi.address(job) === 0n) { console.log('CreateJobObjectW fehlgeschlagen, Win32-Fehler', GetLastError()); process.exit(1); } console.log('1. CreateJobObjectW -> Arbeitsgruppe angelegt'); // JOBOBJECT_EXTENDED_LIMIT_INFORMATION ist 144 Byte auf x64. // LimitFlags liegt im eingebetteten BASIC_LIMIT_INFORMATION bei Offset 16. const info = Buffer.alloc(144); info.writeUInt32LE(JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, 16); if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, info, 144)) { console.log('SetInformationJobObject fehlgeschlagen, Win32-Fehler', GetLastError()); process.exit(1); } console.log('2. SetInformationJobObject -> KILL_ON_JOB_CLOSE gesetzt'); if (!AssignProcessToJobObject(job, GetCurrentProcess())) { console.log('AssignProcessToJobObject fehlgeschlagen, Win32-Fehler', GetLastError()); process.exit(1); } console.log('3. AssignProcessToJobObject -> dieser Prozess haengt in der Gruppe'); // Ein langlebiges Kind starten — der Platzhalter fuer makemkvcon. const kind = spawn('ping', ['-n', '300', '127.0.0.1'], { stdio: 'ignore' }); console.log('4. Kindprozess gestartet, PID ' + kind.pid); console.log('ELTERN-PID=' + process.pid); console.log('KIND-PID=' + kind.pid); // Offen halten, bis uns jemand hart abschiesst. setTimeout(() => { console.log('Zeit abgelaufen'); process.exit(0); }, 60000);