257 lines
9.5 KiB
JavaScript
257 lines
9.5 KiB
JavaScript
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createMessageConnection = exports.createServerSocketTransport = exports.createClientSocketTransport = exports.createServerPipeTransport = exports.createClientPipeTransport = exports.generateRandomPipeName = exports.StreamMessageWriter = exports.StreamMessageReader = exports.SocketMessageWriter = exports.SocketMessageReader = exports.PortMessageWriter = exports.PortMessageReader = exports.IPCMessageWriter = exports.IPCMessageReader = void 0;
|
|
/* --------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
* ----------------------------------------------------------------------------------------- */
|
|
const ril_1 = require("./ril");
|
|
// Install the node runtime abstract.
|
|
ril_1.default.install();
|
|
const path = require("path");
|
|
const os = require("os");
|
|
const crypto_1 = require("crypto");
|
|
const net_1 = require("net");
|
|
const api_1 = require("../common/api");
|
|
__exportStar(require("../common/api"), exports);
|
|
class IPCMessageReader extends api_1.AbstractMessageReader {
|
|
constructor(process) {
|
|
super();
|
|
this.process = process;
|
|
let eventEmitter = this.process;
|
|
eventEmitter.on('error', (error) => this.fireError(error));
|
|
eventEmitter.on('close', () => this.fireClose());
|
|
}
|
|
listen(callback) {
|
|
this.process.on('message', callback);
|
|
return api_1.Disposable.create(() => this.process.off('message', callback));
|
|
}
|
|
}
|
|
exports.IPCMessageReader = IPCMessageReader;
|
|
class IPCMessageWriter extends api_1.AbstractMessageWriter {
|
|
constructor(process) {
|
|
super();
|
|
this.process = process;
|
|
this.errorCount = 0;
|
|
const eventEmitter = this.process;
|
|
eventEmitter.on('error', (error) => this.fireError(error));
|
|
eventEmitter.on('close', () => this.fireClose);
|
|
}
|
|
write(msg) {
|
|
try {
|
|
if (typeof this.process.send === 'function') {
|
|
this.process.send(msg, undefined, undefined, (error) => {
|
|
if (error) {
|
|
this.errorCount++;
|
|
this.handleError(error, msg);
|
|
}
|
|
else {
|
|
this.errorCount = 0;
|
|
}
|
|
});
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
catch (error) {
|
|
this.handleError(error, msg);
|
|
return Promise.reject(error);
|
|
}
|
|
}
|
|
handleError(error, msg) {
|
|
this.errorCount++;
|
|
this.fireError(error, msg, this.errorCount);
|
|
}
|
|
end() {
|
|
}
|
|
}
|
|
exports.IPCMessageWriter = IPCMessageWriter;
|
|
class PortMessageReader extends api_1.AbstractMessageReader {
|
|
constructor(port) {
|
|
super();
|
|
this.onData = new api_1.Emitter;
|
|
port.on('close', () => this.fireClose);
|
|
port.on('error', (error) => this.fireError(error));
|
|
port.on('message', (message) => {
|
|
this.onData.fire(message);
|
|
});
|
|
}
|
|
listen(callback) {
|
|
return this.onData.event(callback);
|
|
}
|
|
}
|
|
exports.PortMessageReader = PortMessageReader;
|
|
class PortMessageWriter extends api_1.AbstractMessageWriter {
|
|
constructor(port) {
|
|
super();
|
|
this.port = port;
|
|
this.errorCount = 0;
|
|
port.on('close', () => this.fireClose());
|
|
port.on('error', (error) => this.fireError(error));
|
|
}
|
|
write(msg) {
|
|
try {
|
|
this.port.postMessage(msg);
|
|
return Promise.resolve();
|
|
}
|
|
catch (error) {
|
|
this.handleError(error, msg);
|
|
return Promise.reject(error);
|
|
}
|
|
}
|
|
handleError(error, msg) {
|
|
this.errorCount++;
|
|
this.fireError(error, msg, this.errorCount);
|
|
}
|
|
end() {
|
|
}
|
|
}
|
|
exports.PortMessageWriter = PortMessageWriter;
|
|
class SocketMessageReader extends api_1.ReadableStreamMessageReader {
|
|
constructor(socket, encoding = 'utf-8') {
|
|
super((0, ril_1.default)().stream.asReadableStream(socket), encoding);
|
|
}
|
|
}
|
|
exports.SocketMessageReader = SocketMessageReader;
|
|
class SocketMessageWriter extends api_1.WriteableStreamMessageWriter {
|
|
constructor(socket, options) {
|
|
super((0, ril_1.default)().stream.asWritableStream(socket), options);
|
|
this.socket = socket;
|
|
}
|
|
dispose() {
|
|
super.dispose();
|
|
this.socket.destroy();
|
|
}
|
|
}
|
|
exports.SocketMessageWriter = SocketMessageWriter;
|
|
class StreamMessageReader extends api_1.ReadableStreamMessageReader {
|
|
constructor(readable, encoding) {
|
|
super((0, ril_1.default)().stream.asReadableStream(readable), encoding);
|
|
}
|
|
}
|
|
exports.StreamMessageReader = StreamMessageReader;
|
|
class StreamMessageWriter extends api_1.WriteableStreamMessageWriter {
|
|
constructor(writable, options) {
|
|
super((0, ril_1.default)().stream.asWritableStream(writable), options);
|
|
}
|
|
}
|
|
exports.StreamMessageWriter = StreamMessageWriter;
|
|
const XDG_RUNTIME_DIR = process.env['XDG_RUNTIME_DIR'];
|
|
const safeIpcPathLengths = new Map([
|
|
['linux', 107],
|
|
['darwin', 103]
|
|
]);
|
|
function generateRandomPipeName() {
|
|
const randomSuffix = (0, crypto_1.randomBytes)(21).toString('hex');
|
|
if (process.platform === 'win32') {
|
|
return `\\\\.\\pipe\\vscode-jsonrpc-${randomSuffix}-sock`;
|
|
}
|
|
let result;
|
|
if (XDG_RUNTIME_DIR) {
|
|
result = path.join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`);
|
|
}
|
|
else {
|
|
result = path.join(os.tmpdir(), `vscode-${randomSuffix}.sock`);
|
|
}
|
|
const limit = safeIpcPathLengths.get(process.platform);
|
|
if (limit !== undefined && result.length > limit) {
|
|
(0, ril_1.default)().console.warn(`WARNING: IPC handle "${result}" is longer than ${limit} characters.`);
|
|
}
|
|
return result;
|
|
}
|
|
exports.generateRandomPipeName = generateRandomPipeName;
|
|
function createClientPipeTransport(pipeName, encoding = 'utf-8') {
|
|
let connectResolve;
|
|
const connected = new Promise((resolve, _reject) => {
|
|
connectResolve = resolve;
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
let server = (0, net_1.createServer)((socket) => {
|
|
server.close();
|
|
connectResolve([
|
|
new SocketMessageReader(socket, encoding),
|
|
new SocketMessageWriter(socket, encoding)
|
|
]);
|
|
});
|
|
server.on('error', reject);
|
|
server.listen(pipeName, () => {
|
|
server.removeListener('error', reject);
|
|
resolve({
|
|
onConnected: () => { return connected; }
|
|
});
|
|
});
|
|
});
|
|
}
|
|
exports.createClientPipeTransport = createClientPipeTransport;
|
|
function createServerPipeTransport(pipeName, encoding = 'utf-8') {
|
|
const socket = (0, net_1.createConnection)(pipeName);
|
|
return [
|
|
new SocketMessageReader(socket, encoding),
|
|
new SocketMessageWriter(socket, encoding)
|
|
];
|
|
}
|
|
exports.createServerPipeTransport = createServerPipeTransport;
|
|
function createClientSocketTransport(port, encoding = 'utf-8') {
|
|
let connectResolve;
|
|
const connected = new Promise((resolve, _reject) => {
|
|
connectResolve = resolve;
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
const server = (0, net_1.createServer)((socket) => {
|
|
server.close();
|
|
connectResolve([
|
|
new SocketMessageReader(socket, encoding),
|
|
new SocketMessageWriter(socket, encoding)
|
|
]);
|
|
});
|
|
server.on('error', reject);
|
|
server.listen(port, '127.0.0.1', () => {
|
|
server.removeListener('error', reject);
|
|
resolve({
|
|
onConnected: () => { return connected; }
|
|
});
|
|
});
|
|
});
|
|
}
|
|
exports.createClientSocketTransport = createClientSocketTransport;
|
|
function createServerSocketTransport(port, encoding = 'utf-8') {
|
|
const socket = (0, net_1.createConnection)(port, '127.0.0.1');
|
|
return [
|
|
new SocketMessageReader(socket, encoding),
|
|
new SocketMessageWriter(socket, encoding)
|
|
];
|
|
}
|
|
exports.createServerSocketTransport = createServerSocketTransport;
|
|
function isReadableStream(value) {
|
|
const candidate = value;
|
|
return candidate.read !== undefined && candidate.addListener !== undefined;
|
|
}
|
|
function isWritableStream(value) {
|
|
const candidate = value;
|
|
return candidate.write !== undefined && candidate.addListener !== undefined;
|
|
}
|
|
function createMessageConnection(input, output, logger, options) {
|
|
if (!logger) {
|
|
logger = api_1.NullLogger;
|
|
}
|
|
const reader = isReadableStream(input) ? new StreamMessageReader(input) : input;
|
|
const writer = isWritableStream(output) ? new StreamMessageWriter(output) : output;
|
|
if (api_1.ConnectionStrategy.is(options)) {
|
|
options = { connectionStrategy: options };
|
|
}
|
|
return (0, api_1.createMessageConnection)(reader, writer, logger, options);
|
|
}
|
|
exports.createMessageConnection = createMessageConnection;
|