cdt-gdb-adapter
Advanced tools
Comparing version 0.0.15-next.20210107134406.82df2f0.0 to 0.0.15-next.20210120232126.d3ec2b3.0
@@ -54,3 +54,3 @@ "use strict"; | ||
const pty = new Pty(); | ||
let args = [gdb, '-ex', `new-ui mi2 ${pty.name}`]; | ||
let args = [gdb, '-ex', `new-ui mi2 ${pty.slave_name}`]; | ||
if (requestArgs.gdbArguments) { | ||
@@ -60,4 +60,4 @@ args = args.concat(requestArgs.gdbArguments); | ||
yield cb(args); | ||
this.out = pty.master; | ||
return this.parser.parse(pty.master); | ||
this.out = pty.writer; | ||
return this.parser.parse(pty.reader); | ||
}); | ||
@@ -64,0 +64,0 @@ } |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
/********************************************************************* | ||
@@ -11,7 +10,10 @@ * Copyright (c) 2018 Ericsson and others | ||
*********************************************************************/ | ||
import { Socket } from 'net'; | ||
export declare class Pty { | ||
master: Socket; | ||
readonly name: string; | ||
import { File } from './file'; | ||
export { File }; | ||
/** | ||
* Represents the master-side of a pseudo-terminal master/slave pair. | ||
*/ | ||
export declare class Pty extends File { | ||
readonly slave_name: string; | ||
constructor(); | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Pty = void 0; | ||
/********************************************************************* | ||
@@ -13,15 +11,16 @@ * Copyright (c) 2018 Ericsson and others | ||
*********************************************************************/ | ||
const net_1 = require("net"); | ||
// tslint:disable-next-line:variable-name | ||
const tty_wrap = process.binding('tty_wrap'); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Pty = exports.File = void 0; | ||
const file_1 = require("./file"); | ||
Object.defineProperty(exports, "File", { enumerable: true, get: function () { return file_1.File; } }); | ||
// tslint:disable-next-line:no-var-requires | ||
const pty = require('../../build/Release/pty.node'); | ||
class Pty { | ||
/** | ||
* Represents the master-side of a pseudo-terminal master/slave pair. | ||
*/ | ||
class Pty extends file_1.File { | ||
constructor() { | ||
const handles = pty.create_pty(); | ||
const backup = tty_wrap.guessHandleType; | ||
tty_wrap.guessHandleType = () => 'PIPE'; | ||
this.master = new net_1.Socket({ fd: handles.master_fd }); | ||
tty_wrap.guessHandleType = backup; | ||
this.name = handles.slave_name; | ||
super(handles.master_fd); | ||
this.slave_name = handles.slave_name; | ||
} | ||
@@ -28,0 +27,0 @@ } |
@@ -0,1 +1,10 @@ | ||
/********************************************************************* | ||
* Copyright (c) 2019 Ericsson and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
export {}; |
"use strict"; | ||
/********************************************************************* | ||
* Copyright (c) 2019 Ericsson and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -12,19 +21,8 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/********************************************************************* | ||
* Copyright (c) 2019 Ericsson and others | ||
* | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*********************************************************************/ | ||
const chai_1 = require("chai"); | ||
const fs = require("fs"); | ||
const os = require("os"); | ||
const stream_1 = require("stream"); | ||
const pty_1 = require("../native/pty"); | ||
const forked_file_1 = require("../native/forked-file"); | ||
// Allow non-arrow functions: https://mochajs.org/#arrow-functions | ||
// tslint:disable:only-arrow-functions no-console no-bitwise | ||
if (os.platform() !== 'win32') { | ||
if (process.platform !== 'win32') { | ||
describe('pty creation', function () { | ||
@@ -41,33 +39,27 @@ let master; | ||
}); | ||
it('should be able to open a ptmx/pts pair', function () { | ||
it('should be able to open a ptmx/pts pair', failFast(function (fail) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const pty = new pty_1.Pty(); | ||
master = pty.master; | ||
slave = new File(fs.openSync(pty.name, 'r+')); | ||
function onError(error) { | ||
console.error(error); | ||
throw error; | ||
} | ||
master.on('error', onError); | ||
slave.on('error', onError); | ||
let masterStream = ''; | ||
let slaveStream = ''; | ||
master.on('data', (data) => masterStream += data.toString('utf8')); | ||
slave.on('data', (data) => slaveStream += data.toString('utf8')); | ||
chai_1.expect(masterStream).eq(''); | ||
chai_1.expect(slaveStream).eq(''); | ||
yield sendAndAwait('master2slave', master, slave); | ||
chai_1.expect(masterStream).eq(''); | ||
chai_1.expect(slaveStream).eq('master2slave'); | ||
yield sendAndAwait('slave2master', slave, master); | ||
chai_1.expect(masterStream).eq('slave2master'); | ||
chai_1.expect(slaveStream).eq('master2slave'); | ||
master = new pty_1.Pty(); | ||
slave = new forked_file_1.ForkedFile(master.slave_name); | ||
let masterBuffer = ''; | ||
let slaveBuffer = ''; | ||
master.reader.on('error', fail); | ||
slave.reader.on('error', fail); | ||
master.reader.on('data', data => masterBuffer += data.toString('utf8')); | ||
slave.reader.on('data', data => slaveBuffer += data.toString('utf8')); | ||
yield sendAndAwait('master2slave', master.writer, slave.reader); | ||
chai_1.expect(masterBuffer).eq(''); | ||
chai_1.expect(slaveBuffer).eq('master2slave'); | ||
yield sendAndAwait('slave2master', slave.writer, master.reader); | ||
chai_1.expect(masterBuffer).eq('slave2master'); | ||
chai_1.expect(slaveBuffer).eq('master2slave'); | ||
}); | ||
}); | ||
})); | ||
}); | ||
/** | ||
* Assumes that we are the only one writing to | ||
* @param str | ||
* @param writeTo | ||
* @param readFrom | ||
* What goes in should come out. Useful to test PTYs since what we write on `master` should come out of `slave` and vice-versa. | ||
* | ||
* @param str payload | ||
* @param writeTo where to write into | ||
* @param readFrom where to wait for it to come out | ||
*/ | ||
@@ -80,36 +72,16 @@ function sendAndAwait(str, writeTo, readFrom) { | ||
} | ||
class File extends stream_1.Duplex { | ||
constructor(fd, bufferSize = File.DEFAULT_BUFFER_SIZE) { | ||
super(); | ||
this.fd = fd; | ||
this.destroyed = false; | ||
this.buffer = Buffer.alloc(Math.max(bufferSize, File.MIN_BUFFER_SIZE)); | ||
} | ||
_write(str, encoding, callback) { | ||
fs.write(this.fd, Buffer.from(str, encoding), callback); | ||
} | ||
_read(size) { | ||
fs.read(this.fd, this.buffer, 0, Math.min(this.buffer.length, size), null, (error, bytesRead, readBuffer) => { | ||
if (error) { | ||
if (this.destroyed) { | ||
return; | ||
} | ||
throw error; | ||
} | ||
this.push(readBuffer.slice(0, bytesRead)); | ||
}); | ||
} | ||
_destroy(error, callback) { | ||
this.destroyed = true; | ||
if (error) { | ||
throw error; | ||
} | ||
if (callback) { | ||
fs.close(this.fd, callback); | ||
} | ||
} | ||
/** | ||
* Allows an async function to reject early. | ||
*/ | ||
function failFast(callback) { | ||
let fail; | ||
const abortPromise = new Promise((_, reject) => { fail = reject; }); | ||
return function () { | ||
return Promise.race([ | ||
abortPromise, | ||
callback.call(this, fail), | ||
]); | ||
}; | ||
} | ||
File.MIN_BUFFER_SIZE = 1 << 10; | ||
File.DEFAULT_BUFFER_SIZE = 1 << 16; | ||
} | ||
//# sourceMappingURL=pty.spec.js.map |
{ | ||
"name": "cdt-gdb-adapter", | ||
"version": "0.0.15-next.20210107134406.82df2f0.0", | ||
"version": "0.0.15-next.20210120232126.d3ec2b3.0", | ||
"description": "gdb adapter implementing the debug adapter protocol", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -67,3 +67,3 @@ /********************************************************************* | ||
const pty = new Pty(); | ||
let args = [gdb, '-ex', `new-ui mi2 ${pty.name}`]; | ||
let args = [gdb, '-ex', `new-ui mi2 ${pty.slave_name}`]; | ||
if (requestArgs.gdbArguments) { | ||
@@ -73,4 +73,4 @@ args = args.concat(requestArgs.gdbArguments); | ||
await cb(args); | ||
this.out = pty.master; | ||
return this.parser.parse(pty.master); | ||
this.out = pty.writer; | ||
return this.parser.parse(pty.reader); | ||
} | ||
@@ -77,0 +77,0 @@ |
@@ -10,8 +10,7 @@ /********************************************************************* | ||
*********************************************************************/ | ||
import { expect } from 'chai'; | ||
import * as fs from 'fs'; | ||
import { Socket } from 'net'; | ||
import * as os from 'os'; | ||
import { Duplex, Readable, Writable } from 'stream'; | ||
import { Readable, Writable } from 'stream'; | ||
import { Pty } from '../native/pty'; | ||
import { ForkedFile } from '../native/forked-file'; | ||
@@ -21,7 +20,7 @@ // Allow non-arrow functions: https://mochajs.org/#arrow-functions | ||
if (os.platform() !== 'win32') { | ||
if (process.platform !== 'win32') { | ||
describe('pty creation', function() { | ||
let master: Socket; | ||
let slave: File; | ||
let master: Pty; | ||
let slave: ForkedFile; | ||
@@ -37,45 +36,36 @@ afterEach(function() { | ||
it('should be able to open a ptmx/pts pair', async function() { | ||
const pty = new Pty(); | ||
it('should be able to open a ptmx/pts pair', failFast(async function (fail) { | ||
master = new Pty(); | ||
slave = new ForkedFile(master.slave_name); | ||
master = pty.master; | ||
slave = new File(fs.openSync(pty.name, 'r+')); | ||
let masterBuffer = ''; | ||
let slaveBuffer = ''; | ||
function onError(error: Error) { | ||
console.error(error); | ||
throw error; | ||
} | ||
master.on('error', onError); | ||
slave.on('error', onError); | ||
master.reader.on('error', fail); | ||
slave.reader.on('error', fail); | ||
let masterStream = ''; | ||
let slaveStream = ''; | ||
master.reader.on('data', data => masterBuffer += data.toString('utf8')); | ||
slave.reader.on('data', data => slaveBuffer += data.toString('utf8')); | ||
master.on('data', (data) => masterStream += data.toString('utf8')); | ||
slave.on('data', (data) => slaveStream += data.toString('utf8')); | ||
await sendAndAwait('master2slave', master.writer, slave.reader); | ||
expect(masterStream).eq(''); | ||
expect(slaveStream).eq(''); | ||
expect(masterBuffer).eq(''); | ||
expect(slaveBuffer).eq('master2slave'); | ||
await sendAndAwait('master2slave', master, slave); | ||
await sendAndAwait('slave2master', slave.writer, master.reader); | ||
expect(masterStream).eq(''); | ||
expect(slaveStream).eq('master2slave'); | ||
await sendAndAwait('slave2master', slave, master); | ||
expect(masterStream).eq('slave2master'); | ||
expect(slaveStream).eq('master2slave'); | ||
}); | ||
expect(masterBuffer).eq('slave2master'); | ||
expect(slaveBuffer).eq('master2slave'); | ||
})); | ||
}); | ||
/** | ||
* Assumes that we are the only one writing to | ||
* @param str | ||
* @param writeTo | ||
* @param readFrom | ||
* What goes in should come out. Useful to test PTYs since what we write on `master` should come out of `slave` and vice-versa. | ||
* | ||
* @param str payload | ||
* @param writeTo where to write into | ||
* @param readFrom where to wait for it to come out | ||
*/ | ||
function sendAndAwait(str: string, writeTo: Writable, readFrom: Readable): Promise<void> { | ||
return new Promise<void | never>((resolve) => { | ||
return new Promise<void>((resolve) => { | ||
readFrom.once('data', () => resolve()); | ||
@@ -86,45 +76,15 @@ writeTo.write(str); | ||
class File extends Duplex { | ||
public static MIN_BUFFER_SIZE = 1 << 10; | ||
public static DEFAULT_BUFFER_SIZE = 1 << 16; | ||
protected destroyed = false; | ||
protected buffer: Buffer; | ||
constructor( | ||
public fd: number, | ||
bufferSize: number = File.DEFAULT_BUFFER_SIZE, | ||
) { | ||
super(); | ||
this.buffer = Buffer.alloc(Math.max(bufferSize, File.MIN_BUFFER_SIZE)); | ||
/** | ||
* Allows an async function to reject early. | ||
*/ | ||
function failFast<T>(callback: (this: T, fail: (error: Error) => void) => Promise<void>): (this: T) => Promise<void> { | ||
let fail!: (error: Error) => void; | ||
const abortPromise = new Promise<never>((_, reject) => { fail = reject; }) | ||
return function (this: T) { | ||
return Promise.race([ | ||
abortPromise, | ||
callback.call(this, fail), | ||
]); | ||
} | ||
public _write(str: string, encoding: string, callback: (error?: Error | null) => void): void { | ||
fs.write(this.fd, Buffer.from(str, encoding), callback); | ||
} | ||
public _read(size: number): void { | ||
fs.read(this.fd, this.buffer, 0, Math.min(this.buffer.length, size), null, | ||
(error, bytesRead, readBuffer) => { | ||
if (error) { | ||
if (this.destroyed) { return; } | ||
throw error; | ||
} | ||
this.push(readBuffer.slice(0, bytesRead)); | ||
}, | ||
); | ||
} | ||
public _destroy(error: Error | null, callback?: (error: Error | null) => void): void { | ||
this.destroyed = true; | ||
if (error) { | ||
throw error; | ||
} | ||
if (callback) { | ||
fs.close(this.fd, callback); | ||
} | ||
} | ||
} | ||
} |
@@ -10,8 +10,9 @@ /********************************************************************* | ||
*********************************************************************/ | ||
import { Socket } from 'net'; | ||
// tslint:disable-next-line:variable-name | ||
const tty_wrap = (process as any).binding('tty_wrap'); | ||
import { File } from './file'; | ||
export { File }; | ||
// tslint:disable-next-line:no-var-requires | ||
const pty = require('../../build/Release/pty.node'); | ||
interface PtyHandles { | ||
@@ -22,15 +23,14 @@ master_fd: number; | ||
export class Pty { | ||
/** | ||
* Represents the master-side of a pseudo-terminal master/slave pair. | ||
*/ | ||
export class Pty extends File { | ||
public master: Socket; | ||
public readonly name: string; | ||
public readonly slave_name: string; | ||
constructor() { | ||
const handles: PtyHandles = pty.create_pty(); | ||
const backup = tty_wrap.guessHandleType; | ||
tty_wrap.guessHandleType = () => 'PIPE'; | ||
this.master = new Socket({ fd: handles.master_fd }); | ||
tty_wrap.guessHandleType = backup; | ||
this.name = handles.slave_name; | ||
const handles = pty.create_pty() as PtyHandles; | ||
super(handles.master_fd); | ||
this.slave_name = handles.slave_name; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 8 instances in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 7 instances in 1 package
527849
142
8286
23
13