123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- // Simple interface for making a socat process and interacting with it.
- // Assumes access to the `socat` command as a child process; if it's not
- // present, it will fall back to just writing to the specified file.
- import {spawn} from 'node:child_process'
- import {writeFile} from 'node:fs/promises'
- import EventEmitter from 'node:events'
- import path from 'node:path'
- import {killProcess, commandExists} from './general-util.js'
- export default class Socat extends EventEmitter {
- constructor(path) {
- super()
- this.setPath(path)
- }
- setPath(path) {
- this.stop()
- this.path = path
- }
- async start() {
- this.stop()
- if (await commandExists('socat')) {
- this.subprocess = spawn('socat', ['-', this.path])
- this.subprocess.stdout.on('data', data => this.emit('data', data))
- this.subprocess.on('close', () => {
- this.subprocess = null
- })
- this.subprocess.stdin.on('error', () => {
- this.stop()
- })
- }
- }
- async stop() {
- const proc = this.subprocess
- if (proc) {
- this.subprocess = null
- await killProcess(proc)
- }
- }
- async dispose() {
- // Don't accept any more messages.
- this.disposed = true
- await this.stop()
- }
- async send(message) {
- if (this.disposed) {
- return
- }
- if (!this.subprocess) {
- await this.start()
- }
- if (this.subprocess) {
- try {
- this.subprocess.stdin.write(message + '\r\n')
- } catch (error) {
- // There's no guarantee we'll actually suceed to write - the process
- // or pipe we're writing to could have closed unexpectedly. If that
- // happens, unestablish the socat process; it'll try to reconnect if
- // we send another message.
- this.stop()
- }
- } else {
- try {
- await writeFile(path.resolve(process.cwd(), this.path), message + '\r\n')
- } catch (error) {
- // :shrug: We tried!
- // -- It's possible to get here if the specified path isn't an actual
- // device, which is the case on Linux. Writing to that file (hopefully)
- // works on Windows though, which is the case we're trying to support
- // here. (On Linux you should have socat installed.)
- }
- }
- }
- }
|