Socket
Socket
Sign inDemoInstall

linux-device

Package Overview
Dependencies
132
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.10 to 2.0.11

179

lib/DeviceHandle.js

@@ -6,5 +6,19 @@ "use strict";

const util = require('util');
const fs = require('fs');
const _fs = require('fs');
const tty = require('tty');
const net = require('net');
const FH = require('bindings')('DeviceHandle');
const fs = {
open: util.promisify(_fs.open),
close: util.promisify(_fs.close),
writeFile: util.promisify(_fs.writeFile),
fstat: util.promisify(_fs.fstat),
createReadStream: _fs.createReadStream,
createWriteStream: _fs.createWriteStream,
constants: _fs.constants,
};
const kSource = Symbol('source');

@@ -56,2 +70,3 @@

options = options || {};
if(typeof options === 'string') options = {path: options};
const mode = options.mode || CONSTANTS.O_RDWR;

@@ -64,3 +79,2 @@ this[kSource] = {

parser: options.parser || undefined,
handle: new FH(options.path),
reading: 0,

@@ -72,2 +86,80 @@ forcedDataSize: options.absoluteSize,

__onEnd(err) {
if(err) this.close().catch(e => {});
}
__onError(err) {
if(err) this.close().catch(e => {});
this.emit(err);
}
__pushSmart(res) {
let result = true;
if(res && this[kSource].parser) {
if(!this[kSource].emitter) {
this[kSource].emitter = new EventEmitter();
this[kSource].emitter.on('data', (data) => this.push(data));
}
this[kSource].parser(this[kSource].emitter, res);
} if(res && this[kSource].forcedDataSize) {
for(let i = 0; i < res.length; i+= this[kSource].forcedDataSize) {
result = this.push(res.slice(i, i+this[kSource].forcedDataSize));
}
} else {
result = this.push(res);
}
return result;
}
async _createStreams() {
if(tty.isatty(this.fd)) {
if(this[kSource].readable) {
this[kSource].inStream = new tty.ReadStream(this.fd);
this[kSource].inStream.setRawMode(true);
}
if(this[kSource].writable) {
this[kSource].outStream = new tty.WriteStream(this.fd);
}
} else {
const fstat = await fs.fstat(this.fd);
if(fstat.isFile() || fstat.isCharacterDevice() || fstat.isBlockDevice() ) {
if(this[kSource].readable)
this[kSource].inStream = fs.createReadStream(null, {fd: this.fd, autoClose: false});
if(this[kSource].writable)
this[kSource].outStream = fs.createWriteStream(null, {fd: this.fd, autoClose: false});
} else if(fstat.isSocket()) {
this[kSource].inStream = this[kSource].outStream
= new net.Socket({
fd: this.fd,
readable: this[kSource].readable,
writable: this[kSource].writable,
})
} else {
throw new Error("unknown_type");
}
}
if(this[kSource].outStream && this[kSource].outStream != this[kSource].inStream) {
this[kSource].outStream.on('error', err => this.__onError(err));
}
if(this[kSource].inStream) {
this[kSource].inStream.on('error', err => this.__onError(err));
this[kSource].inStream.on('end', err => this.__onEnd(err));
this[kSource].inStream.pause();
this[kSource].inStream.on('data', (data) => {
if(!this.__pushSmart(data)) {
this[kSource].inStream.pause();
}
});
if(this[kSource].resumeOnCreate){
delete this[kSource].resumeOnCreate;
this[kSource].inStream.resume();
}
}
}
/**

@@ -80,4 +172,5 @@ * Opens the device

if(this[kSource].tainted) throw new Error('attempt to reuse closed DeviceHandle');
const res = await this[kSource].handle.open(this[kSource].mode | CONSTANTS.O_DSYNC);
const res = await fs.open(this[kSource].path, this[kSource].mode);
this.fd = res;
await this._createStreams();
this.emit('open', res);

@@ -94,9 +187,15 @@ if(this[kSource].reading) {

async close() {
if(this[kSource].outStream) {
this[kSource].outStream.cork();
this[kSource].outStream.removeAllListeners();
delete this[kSource].outStream;
}
if(this[kSource].inStream) {
this[kSource].inStream.pause();
this[kSource].inStream.removeAllListeners();
delete this[kSource].inStream;
}
if(!this.fd) return;
await fs.close(this.fd);
delete this.fd;
if(this[kSource].readable) {
this.push(null);
this[kSource].tainted = true;
}
await this[kSource].handle.close();
this.emit('close');

@@ -122,3 +221,3 @@ }

if(!this.fd) throw new Error('not_open');
await this[kSource].handle.ioctl(direction, type, cmd, data||Buffer.alloc(0));
await FH.ioctl(this.fd, direction, type, cmd, data||Buffer.alloc(0));
}

@@ -133,3 +232,3 @@

if(!this.fd) throw new Error('not_open');
await this[kSource].handle.ioctlRaw(cmd, data||Buffer.alloc(0));
await FH.ioctlRaw(this.fd, cmd, data||Buffer.alloc(0));
}

@@ -167,10 +266,4 @@

static async gpio(gpio, value) {
return new Promise((resolve, reject) => {
fs.writeFile( SYSFS_GPIO+'/export', ''+gpio, function(err) {
fs.writeFile(SYSFS_GPIO+'/gpio'+gpio+'/direction', value ? 'high': 'low', function(err) {
if(err) return reject(err);
resolve(err);
});
});
});
await fs.writeFile( SYSFS_GPIO+'/export', ''+gpio).catch(e => {});
await fs.writeFile(SYSFS_GPIO+'/gpio'+gpio+'/direction', value ? 'high': 'low');
};

@@ -192,2 +285,9 @@

_read(size) {
if(this[kSource].inStream)
this[kSource].inStream.resume();
else
this[kSource].resumeOnCreate = true;
}
async _writePromise(chunk, encoding) {

@@ -197,47 +297,8 @@ if(!this.fd) throw new Error('not_open');

if(chunk.interval && chunk.repetitions) {
return await this[kSource].handle.writeRepeated(chunk, chunk.interval, chunk.repetitions); //retain chunks
return await FH.writeRepeated(this.fd, chunk, chunk.interval, chunk.repetitions); //retain chunks
} else {
return await this[kSource].handle.write(chunk); //retain chunk
return util.promisify(this[kSource].outStream.write).call(this[kSource].outStream, chunk, encoding); //retain chunk
}
}
_read() {
if(!this[kSource].readable) return;
this[kSource].reading += 1;
if(!this.fd) return;
this[kSource].handle.read((err, res) => {
if(!this.fd) return;
if(err) {
return process.nextTick(() => {
this.destroy(err);
});
}
if(res && this[kSource].parser) {
if(!this[kSource].emitter) {
this[kSource].emitter = new EventEmitter();
this[kSource].emitter.on('data', (data) => this.push(data));
}
this[kSource].parser(this[kSource].emitter, res);
} else if(res && this[kSource].forcedDataSize) {
for(let i = 0; i < res.length; i+= this[kSource].forcedDataSize) {
this.push(res.slice(i, i+this[kSource].forcedDataSize));
}
} else {
this.push(res);
}
if(!res) return this[kSource].handle.stopReading();
this[kSource].reading -= 1;
if(this[kSource].reading < 0) {
this[kSource].reading = 0;
this[kSource].handle.stopReading();
}
});
}
_destroy(error, callback) {

@@ -244,0 +305,0 @@ if(!this.fd) return;

{
"name": "linux-device",
"version": "2.0.10",
"version": "2.0.11",
"description": "Native addon to communicate with linux devices (can also be used for sockets or FIFOs)",

@@ -5,0 +5,0 @@ "main": "index.js",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc