diff --git a/src/vs/base/node/stdFork.ts b/src/vs/base/node/stdFork.ts deleted file mode 100644 index 17782445328..00000000000 --- a/src/vs/base/node/stdFork.ts +++ /dev/null @@ -1,140 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -'use strict'; - -import * as path from 'path'; -import * as os from 'os'; -import * as net from 'net'; -import * as cp from 'child_process'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; - -export interface IForkOpts { - cwd?: string; - env?: any; - encoding?: string; - execArgv?: string[]; -} - -function makeRandomHexString(length: number): string { - let chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; - let result = ''; - for (let i = 0; i < length; i++) { - let idx = Math.floor(chars.length * Math.random()); - result += chars[idx]; - } - return result; -} - -function generatePipeName(): string { - let randomName = 'vscode-std-' + makeRandomHexString(40); - if (process.platform === 'win32') { - return '\\\\.\\pipe\\' + randomName + '-sock'; - } - - // Mac/Unix: use socket file - return path.join(os.tmpdir(), randomName + '.sock'); -} - -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 = {}; - for (let key in env) { - newEnv[key] = env[key]; - } - - newEnv['STDIN_PIPE_NAME'] = stdInPipeName; - newEnv['STDOUT_PIPE_NAME'] = stdOutPipeName; - newEnv['STDERR_PIPE_NAME'] = stdErrPipeName; - newEnv['ELECTRON_RUN_AS_NODE'] = '1'; - - return newEnv; -} - -export function fork(modulePath: string, args: string[], options: IForkOpts, callback: (error: any, cp: cp.ChildProcess) => void): void { - - let callbackCalled = false; - let resolve = (result: cp.ChildProcess) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(null, result); - }; - let reject = (err: any) => { - if (callbackCalled) { - return; - } - callbackCalled = true; - callback(err, null); - }; - - // Generate three unique pipe names - let stdInPipeName = generatePipeName(); - let stdOutPipeName = generatePipeName(); - let stdErrPipeName = generatePipeName(); - - 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 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 - - stdOutStream.once('data', (chunk: Buffer) => { - // The child process is sending me the `ready` chunk, time to connect to the stdin pipe - childProcess.stdin = net.connect(stdInPipeName); - - // From now on the childProcess.stdout is available for reading - childProcess.stdout = stdOutStream; - - resolve(childProcess); - }); - }); - stdOutServer.listen(stdOutPipeName); - - let serverClosed = false; - let closeServer = () => { - if (serverClosed) { - return; - } - - serverClosed = true; - process.removeListener('exit', closeServer); - stdOutServer.close(); - stdErrServer.close(); - }; - - // Create the process - let bootstrapperPath = (getPathFromAmdModule(require, './stdForkStart.js')); - childProcess = cp.fork(bootstrapperPath, [modulePath].concat(args), { - silent: true, - cwd: options.cwd, - env: newEnv, - execArgv: options.execArgv - }); - - childProcess.once('error', (err: Error) => { - closeServer(); - reject(err); - }); - - childProcess.once('exit', (err: Error) => { - closeServer(); - reject(err); - }); - - // On vscode exit still close server #7758 - process.once('exit', closeServer); -} diff --git a/src/vs/base/node/stdForkStart.js b/src/vs/base/node/stdForkStart.js deleted file mode 100644 index 42226f9a08d..00000000000 --- a/src/vs/base/node/stdForkStart.js +++ /dev/null @@ -1,197 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -const net = require('net'); -const fs = require('fs'); -// const stream = require('stream'); -// const util = require('util'); - -var ENABLE_LOGGING = false; - -var log = (function () { - if (!ENABLE_LOGGING) { - return function () { }; - } - var isFirst = true; - var LOG_LOCATION = 'C:\\stdFork.log'; - return function log(str) { - if (isFirst) { - isFirst = false; - fs.writeFileSync(LOG_LOCATION, str + '\n'); - return; - } - fs.appendFileSync(LOG_LOCATION, str + '\n'); - }; -})(); - -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('ELECTRON_RUN_AS_NODE: ' + process.env['ELECTRON_RUN_AS_NODE']); - -// stdout redirection to named pipe -(function () { - log('Beginning stdout redirection...'); - - // Create a writing stream to the stdout pipe - var stdOutStream = net.connect(stdOutPipeName); - - // unref stdOutStream to behave like a normal standard out - stdOutStream.unref(); - - // 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 stdErrStream; }); - - var fsWriteSyncString = function (fd, str, position, encoding) { - // fs.writeSync(fd, string[, position[, encoding]]); - var buf = Buffer.from(str, encoding || 'utf8'); - return fsWriteSyncBuffer(fd, buf, 0, buf.length); - }; - - var fsWriteSyncBuffer = function (fd, buffer, off, len/* , position */) { - off = Math.abs(off | 0); - len = Math.abs(len | 0); - - // fs.writeSync(fd, buffer, offset, length[, position]); - var buffer_length = buffer.length; - - if (off > buffer_length) { - throw new Error('offset out of bounds'); - } - if (len > buffer_length) { - throw new Error('length out of bounds'); - } - if (((off + len) | 0) < off) { - throw new Error('off + len overflow'); - } - if (buffer_length - off < len) { - // Asking for more than is left over in the buffer - throw new Error('off + len > buffer.length'); - } - - var slicedBuffer = buffer; - if (off !== 0 || len !== buffer_length) { - slicedBuffer = buffer.slice(off, off + len); - } - - if (fd === 1) { - stdOutStream.write(slicedBuffer); - } else { - stdErrStream.write(slicedBuffer); - } - return slicedBuffer.length; - }; - - // handle fs.writeSync(1, ...) and fs.writeSync(2, ...) - var originalWriteSync = fs.writeSync; - fs.writeSync = function (fd, data/* , position, encoding */) { - if (fd !== 1 && fd !== 2) { - return originalWriteSync.apply(fs, arguments); - } - // usage: - // fs.writeSync(fd, buffer, offset, length[, position]); - // OR - // fs.writeSync(fd, string[, position[, encoding]]); - - if (data instanceof Buffer) { - return fsWriteSyncBuffer.apply(null, arguments); - } - - // For compatibility reasons with fs.writeSync, writing null will write "null", etc - if (typeof data !== 'string') { - data += ''; - } - - return fsWriteSyncString.apply(null, arguments); - }; - - log('Finished defining process.stdout, process.stderr and fs.writeSync'); -})(); - -// stdin redirection to named pipe -(function () { - - // Begin listening to stdin pipe - var server = net.createServer(function (stream) { - // Stop accepting new connections, keep the existing one alive - server.close(); - - log('Parent process has connected to my stdin. All should be good now.'); - - // handle process.stdin - process.__defineGetter__('stdin', function () { - return stream; - }); - - // Remove myself from process.argv - process.argv.splice(1, 1); - - // Load the actual program - var program = process.argv[1]; - log('Loading program: ' + program); - - // 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['ELECTRON_RUN_AS_NODE']; - - require(program); - - log('Finished loading program.'); - - var stdinIsReferenced = true; - var timer = setInterval(function () { - var listenerCount = ( - stream.listeners('data').length + - stream.listeners('end').length + - stream.listeners('close').length + - stream.listeners('error').length - ); - // log('listenerCount: ' + listenerCount); - if (listenerCount <= 1) { - // No more "actual" listeners, only internal node - if (stdinIsReferenced) { - stdinIsReferenced = false; - // log('unreferencing stream!!!'); - stream.unref(); - } - } else { - // There are "actual" listeners - if (!stdinIsReferenced) { - stdinIsReferenced = true; - stream.ref(); - } - } - // log( - // '' + stream.listeners('data').length + - // ' ' + stream.listeners('end').length + - // ' ' + stream.listeners('close').length + - // ' ' + stream.listeners('error').length - // ); - }, 1000); - timer.unref(); - }); - - - server.listen(stdInPipeName, function () { - // signal via stdout that the parent process can now begin writing to stdin pipe - process.stdout.write('ready'); - }); - -})();