mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-14 15:22:15 +01:00
@@ -37,7 +37,7 @@ function generatePipeName(): string {
|
||||
return path.join(os.tmpdir(), randomName + '.sock');
|
||||
}
|
||||
|
||||
function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string): any {
|
||||
function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string, stdErrPipeName:string): any {
|
||||
// Set the two unique pipe names and the electron flag as process env
|
||||
|
||||
var newEnv:any = {};
|
||||
@@ -47,6 +47,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string
|
||||
|
||||
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
|
||||
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
|
||||
newEnv['STDERR_PIPE_NAME'] = stdErrPipeName;
|
||||
newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
|
||||
|
||||
return newEnv;
|
||||
@@ -70,29 +71,38 @@ export function fork(modulePath: string, args: string[], options: IForkOptions,
|
||||
callback(err, null);
|
||||
};
|
||||
|
||||
// Generate two unique pipe names
|
||||
// Generate three unique pipe names
|
||||
var stdInPipeName = generatePipeName();
|
||||
var stdOutPipeName = generatePipeName();
|
||||
let stdErrPipeName = generatePipeName();
|
||||
|
||||
var newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName);
|
||||
|
||||
var newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName, stdErrPipeName);
|
||||
|
||||
var childProcess: cp.ChildProcess;
|
||||
|
||||
// Begin listening to stderr pipe
|
||||
let stdErrServer = net.createServer((stdErrStream) => {
|
||||
// From now on the childProcess.stderr is available for reading
|
||||
childProcess.stderr = stdErrStream;
|
||||
});
|
||||
stdErrServer.listen(stdErrPipeName);
|
||||
|
||||
// Begin listening to stdout pipe
|
||||
var server = net.createServer((stream) => {
|
||||
let stdOutServer = net.createServer((stdOutStream) => {
|
||||
// The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe
|
||||
|
||||
stream.once('data', (chunk:Buffer) => {
|
||||
stdOutStream.once('data', (chunk:Buffer) => {
|
||||
// The child process is sending me the `ready` chunk, time to connect to the stdin pipe
|
||||
childProcess.stdin = <any>net.connect(stdInPipeName);
|
||||
|
||||
// From now on the childProcess.stdout is available for reading
|
||||
childProcess.stdout = stream;
|
||||
childProcess.stdout = stdOutStream;
|
||||
|
||||
resolve(childProcess);
|
||||
});
|
||||
});
|
||||
server.listen(stdOutPipeName);
|
||||
stdOutServer.listen(stdOutPipeName);
|
||||
|
||||
var serverClosed = false;
|
||||
var closeServer = () => {
|
||||
@@ -100,7 +110,8 @@ export function fork(modulePath: string, args: string[], options: IForkOptions,
|
||||
return;
|
||||
}
|
||||
serverClosed = true;
|
||||
server.close();
|
||||
stdOutServer.close();
|
||||
stdErrServer.close();
|
||||
};
|
||||
|
||||
// Create the process
|
||||
|
||||
@@ -26,9 +26,11 @@ var log = (function() {
|
||||
|
||||
var stdInPipeName = process.env['STDIN_PIPE_NAME'];
|
||||
var stdOutPipeName = process.env['STDOUT_PIPE_NAME'];
|
||||
var stdErrPipeName = process.env['STDERR_PIPE_NAME'];
|
||||
|
||||
log('STDIN_PIPE_NAME: ' + stdInPipeName);
|
||||
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
|
||||
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
|
||||
log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
|
||||
|
||||
// stdout redirection to named pipe
|
||||
@@ -44,8 +46,14 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
// handle process.stdout
|
||||
(<any>process).__defineGetter__('stdout', function() { return stdOutStream; });
|
||||
|
||||
// Create a writing stream to the stderr pipe
|
||||
var stdErrStream = net.connect(stdErrPipeName);
|
||||
|
||||
// unref stdErrStream to behave like a normal standard out
|
||||
stdErrStream.unref();
|
||||
|
||||
// handle process.stderr
|
||||
(<any>process).__defineGetter__('stderr', function() { return stdOutStream; });
|
||||
(<any>process).__defineGetter__('stderr', function() { return stdErrStream; });
|
||||
|
||||
var fsWriteSyncString = function(fd, str, position, encoding) {
|
||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
||||
@@ -79,14 +87,18 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
slicedBuffer = buffer.slice(off, off + len);
|
||||
}
|
||||
|
||||
stdOutStream.write(slicedBuffer);
|
||||
if (fd === 1) {
|
||||
stdOutStream.write(slicedBuffer);
|
||||
} else {
|
||||
stdErrStream.write(slicedBuffer);
|
||||
}
|
||||
return slicedBuffer.length;
|
||||
};
|
||||
|
||||
// handle fs.writeSync(1, ...)
|
||||
var originalWriteSync = fs.writeSync;
|
||||
fs.writeSync = function(fd, data, position, encoding) {
|
||||
if (fd !== 1) {
|
||||
if (fd !== 1 || fd !== 2) {
|
||||
return originalWriteSync.apply(fs, arguments);
|
||||
}
|
||||
// usage:
|
||||
@@ -134,6 +146,7 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
// Unset the custom environmental variables that should not get inherited
|
||||
delete process.env['STDIN_PIPE_NAME'];
|
||||
delete process.env['STDOUT_PIPE_NAME'];
|
||||
delete process.env['STDERR_PIPE_NAME'];
|
||||
delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
||||
|
||||
require(program);
|
||||
|
||||
@@ -38,7 +38,7 @@ function generatePipeName(): string {
|
||||
return path.join(os.tmpdir(), randomName + '.sock');
|
||||
}
|
||||
|
||||
function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string): any {
|
||||
function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string, stdErrPipeName:string): any {
|
||||
// Set the two unique pipe names and the electron flag as process env
|
||||
|
||||
let newEnv:any = {};
|
||||
@@ -48,6 +48,7 @@ function generatePatchedEnv(env:any, stdInPipeName:string, stdOutPipeName:string
|
||||
|
||||
newEnv['STDIN_PIPE_NAME'] = stdInPipeName;
|
||||
newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName;
|
||||
newEnv['STDERR_PIPE_NAME'] = stdErrPipeName;
|
||||
newEnv['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = '1';
|
||||
|
||||
return newEnv;
|
||||
@@ -71,29 +72,37 @@ export function fork(modulePath: string, args: string[], options: IForkOpts, cal
|
||||
callback(err, null);
|
||||
};
|
||||
|
||||
// Generate two unique pipe names
|
||||
// Generate three unique pipe names
|
||||
let stdInPipeName = generatePipeName();
|
||||
let stdOutPipeName = generatePipeName();
|
||||
let stdErrPipeName = generatePipeName();
|
||||
|
||||
let newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName);
|
||||
let newEnv = generatePatchedEnv(options.env || process.env, stdInPipeName, stdOutPipeName, stdErrPipeName);
|
||||
|
||||
let childProcess: cp.ChildProcess;
|
||||
|
||||
// Begin listening to stderr pipe
|
||||
let stdErrServer = net.createServer((stdErrStream) => {
|
||||
// From now on the childProcess.stderr is available for reading
|
||||
childProcess.stderr = stdErrStream;
|
||||
});
|
||||
stdErrServer.listen(stdErrPipeName);
|
||||
|
||||
// Begin listening to stdout pipe
|
||||
let server = net.createServer((stream) => {
|
||||
let stdOutServer = net.createServer((stdOutStream) => {
|
||||
// The child process will write exactly one chunk with content `ready` when it has installed a listener to the stdin pipe
|
||||
|
||||
stream.once('data', (chunk:Buffer) => {
|
||||
stdOutStream.once('data', (chunk:Buffer) => {
|
||||
// The child process is sending me the `ready` chunk, time to connect to the stdin pipe
|
||||
childProcess.stdin = <any>net.connect(stdInPipeName);
|
||||
|
||||
// From now on the childProcess.stdout is available for reading
|
||||
childProcess.stdout = stream;
|
||||
childProcess.stdout = stdOutStream;
|
||||
|
||||
resolve(childProcess);
|
||||
});
|
||||
});
|
||||
server.listen(stdOutPipeName);
|
||||
stdOutServer.listen(stdOutPipeName);
|
||||
|
||||
let serverClosed = false;
|
||||
let closeServer = () => {
|
||||
@@ -101,7 +110,8 @@ export function fork(modulePath: string, args: string[], options: IForkOpts, cal
|
||||
return;
|
||||
}
|
||||
serverClosed = true;
|
||||
server.close();
|
||||
stdOutServer.close();
|
||||
stdErrServer.close();
|
||||
};
|
||||
|
||||
// Create the process
|
||||
|
||||
@@ -28,9 +28,11 @@ var log = (function() {
|
||||
|
||||
var stdInPipeName = process.env['STDIN_PIPE_NAME'];
|
||||
var stdOutPipeName = process.env['STDOUT_PIPE_NAME'];
|
||||
var stdErrPipeName = process.env['STDERR_PIPE_NAME'];
|
||||
|
||||
log('STDIN_PIPE_NAME: ' + stdInPipeName);
|
||||
log('STDOUT_PIPE_NAME: ' + stdOutPipeName);
|
||||
log('STDERR_PIPE_NAME: ' + stdErrPipeName);
|
||||
log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE']);
|
||||
|
||||
// stdout redirection to named pipe
|
||||
@@ -46,8 +48,14 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
// handle process.stdout
|
||||
process.__defineGetter__('stdout', function() { return stdOutStream; });
|
||||
|
||||
// Create a writing stream to the stderr pipe
|
||||
var stdErrStream = net.connect(stdErrPipeName);
|
||||
|
||||
// unref stdErrStream to behave like a normal standard out
|
||||
stdErrStream.unref();
|
||||
|
||||
// handle process.stderr
|
||||
process.__defineGetter__('stderr', function() { return stdOutStream; });
|
||||
process.__defineGetter__('stderr', function() { return stdErrStream; });
|
||||
|
||||
var fsWriteSyncString = function(fd, str, position, encoding) {
|
||||
// fs.writeSync(fd, string[, position[, encoding]]);
|
||||
@@ -81,14 +89,18 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
slicedBuffer = buffer.slice(off, off + len);
|
||||
}
|
||||
|
||||
stdOutStream.write(slicedBuffer);
|
||||
if (fd === 1) {
|
||||
stdOutStream.write(slicedBuffer);
|
||||
} else {
|
||||
stdErrStream.write(slicedBuffer);
|
||||
}
|
||||
return slicedBuffer.length;
|
||||
};
|
||||
|
||||
// handle fs.writeSync(1, ...)
|
||||
var originalWriteSync = fs.writeSync;
|
||||
fs.writeSync = function(fd, data, position, encoding) {
|
||||
if (fd !== 1) {
|
||||
if (fd !== 1 || fd !== 2) {
|
||||
return originalWriteSync.apply(fs, arguments);
|
||||
}
|
||||
// usage:
|
||||
@@ -136,6 +148,7 @@ log('ATOM_SHELL_INTERNAL_RUN_AS_NODE: ' + process.env['ATOM_SHELL_INTERNAL_RUN_A
|
||||
// Unset the custom environmental variables that should not get inherited
|
||||
delete process.env['STDIN_PIPE_NAME'];
|
||||
delete process.env['STDOUT_PIPE_NAME'];
|
||||
delete process.env['STDERR_PIPE_NAME'];
|
||||
delete process.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'];
|
||||
|
||||
require(program);
|
||||
|
||||
Reference in New Issue
Block a user