Files
STM32F4-Base/IEC60870-Slave/.build/layout-migration/file-stdio.cjs
T
STF 4c55544f05
CI / L0 静态门禁 (pre-commit) (push) Failing after 45s
CI / L0.5 主机侧单测 (MSVC) (push) Failing after 42s
通信协议代码
2026-10-26 08:31:48 -04:00

62 lines
2.1 KiB
JavaScript

'use strict';
// Local verification adapter: capture real child output in files when the
// environment refuses Node's process pipes. Test assertions stay unchanged.
const cp = require('node:child_process');
const fs = require('node:fs');
const path = require('node:path');
const { PassThrough } = require('node:stream');
const originalSpawn = cp.spawn;
const originalSpawnSync = cp.spawnSync;
let sequence = 0;
function captureFiles() {
const prefix = path.join(__dirname, `child-${process.pid}-${++sequence}`);
return ['stdout', 'stderr'].map(name => {
const file = `${prefix}.${name}.log`;
return { file, fd: fs.openSync(file, 'w'), offset: 0 };
});
}
cp.spawnSync = function (command, args, options = {}) {
const captures = captureFiles();
let result;
try {
result = originalSpawnSync(command, args, {
...options, stdio: ['ignore', ...captures.map(capture => capture.fd)]
});
} finally {
for (const capture of captures) fs.closeSync(capture.fd);
}
result.stdout = fs.readFileSync(captures[0].file, options.encoding || null);
result.stderr = fs.readFileSync(captures[1].file, options.encoding || null);
result.output = [null, result.stdout, result.stderr];
return result;
};
cp.spawn = function (command, args, options = {}) {
const captures = captureFiles();
const child = originalSpawn(command, args, {
...options, stdio: ['ignore', ...captures.map(capture => capture.fd)]
});
for (const capture of captures) fs.closeSync(capture.fd);
const streams = captures.map(() => new PassThrough());
child.stdout = streams[0];
child.stderr = streams[1];
function drain() {
captures.forEach((capture, index) => {
const bytes = fs.readFileSync(capture.file);
if (bytes.length > capture.offset) streams[index].write(bytes.subarray(capture.offset));
capture.offset = bytes.length;
});
}
const interval = setInterval(drain, 10);
function finish() {
clearInterval(interval);
drain();
streams.forEach(stream => stream.end());
}
child.prependOnceListener('exit', finish);
child.once('error', finish);
return child;
};