diff --git a/lib/repl.ts b/lib/repl.ts index 27b23d5c2e..d76e7b3f8e 100644 --- a/lib/repl.ts +++ b/lib/repl.ts @@ -20,7 +20,7 @@ export const Repl = new class { /** * Contains the pathnames of all active REPL sockets. */ - socketPathnames: Set = new Set(); + socketPathnames = new Set(); listenersSetup = false; @@ -57,6 +57,41 @@ export const Repl = new class { }; } + /** + * Delete old sockets in the REPL directory (presumably from a crashed + * previous launch of PS). + * + * Does everything synchronously, so that the directory is guaranteed + * clean and ready for new REPL sockets by the time this function returns. + */ + cleanup() { + const config = typeof Config !== 'undefined' ? Config : {}; + if (!config.repl) return; + + // Clean up old REPL sockets. + const directory = path.dirname( + path.resolve(FS.ROOT_PATH, config.replsocketprefix || 'logs/repl', 'app') + ); + let files; + try { + files = fs.readdirSync(directory); + } catch {} + if (files) { + for (const file of files) { + const pathname = path.resolve(directory, file); + const stat = fs.statSync(pathname); + if (!stat.isSocket()) continue; + + const socket = net.connect(pathname, () => { + socket.end(); + socket.destroy(); + }).on('error', () => { + fs.unlinkSync(pathname); + }); + } + } + } + /** * Starts a REPL server, using a UNIX socket for IPC. The eval function * parametre is passed in because there is no other way to access a file's @@ -64,38 +99,13 @@ export const Repl = new class { */ start(filename: string, evalFunction: (input: string) => any) { const config = typeof Config !== 'undefined' ? Config : {}; - if (config.repl !== undefined && !config.repl) return; + if (!config.repl) return; // TODO: Windows does support the REPL when using named pipes. For now, // this only supports UNIX sockets. Repl.setupListeners(filename); - if (filename === 'app') { - // Clean up old REPL sockets. - const directory = path.dirname( - path.resolve(FS.ROOT_PATH, config.replsocketprefix || 'logs/repl', 'app') - ); - let files; - try { - files = fs.readdirSync(directory); - } catch {} - if (files) { - for (const file of files) { - const pathname = path.resolve(directory, file); - const stat = fs.statSync(pathname); - if (!stat.isSocket()) continue; - - const socket = net.connect(pathname, () => { - socket.end(); - socket.destroy(); - }).on('error', () => { - fs.unlink(pathname, () => {}); - }); - } - } - } - const server = net.createServer(socket => { repl.start({ input: socket, diff --git a/server/index.ts b/server/index.ts index 83e7455e46..a0f29c9ef4 100644 --- a/server/index.ts +++ b/server/index.ts @@ -71,6 +71,7 @@ function setupGlobals() { void Monitor.version().then((hash: any) => { global.__version.tree = hash; }); + Repl.cleanup(); if (Config.watchconfig) { FS('config/config.js').onModify(() => {