From c7eee168f152d811cb1c576f772c98e034895b35 Mon Sep 17 00:00:00 2001 From: LEE KYU WON Date: Wed, 8 Apr 2026 22:09:45 +0900 Subject: [PATCH] fix(windows): use unique named pipe paths derived from PM2_HOME Windows named pipes live in a flat global namespace (\.\pipe\*). The current hardcoded names (rpc.sock, pub.sock, interactor.sock) cause EPERM errors when: - Multiple users run PM2 on the same machine - A zombie pipe from a crashed daemon blocks the name - PM2 is started from different elevation levels (admin vs user) This has been a known issue since 2017 (see #2946, #5212, #5510) and the code already contained a @todo comment acknowledging it. The fix derives a short hash from PM2_HOME and embeds it in the pipe name (e.g. \.\pipe\pm2-a1b2c3d4-rpc.sock), ensuring each PM2_HOME gets its own isolated set of IPC pipes. Note: The same fix is needed in @pm2/agent/constants.js which duplicates the Windows pipe name logic. Fixes #5510 Fixes #2946 Co-Authored-By: Claude Opus 4.6 (1M context) --- paths.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/paths.js b/paths.js index b1e83823c5..1fad51d6f2 100644 --- a/paths.js +++ b/paths.js @@ -81,10 +81,14 @@ module.exports = function(PM2_HOME) { if (process.platform === 'win32' || process.platform === 'win64') { - //@todo instead of static unique rpc/pub file custom with PM2_HOME or UID - pm2_file_stucture.DAEMON_RPC_PORT = '\\\\.\\pipe\\rpc.sock'; - pm2_file_stucture.DAEMON_PUB_PORT = '\\\\.\\pipe\\pub.sock'; - pm2_file_stucture.INTERACTOR_RPC_PORT = '\\\\.\\pipe\\interactor.sock'; + // Use PM2_HOME-based unique pipe names to avoid global collisions. + // Windows named pipes are kernel objects in a flat global namespace; + // hardcoded names cause EPERM when another user/session holds the pipe. + var crypto = require('crypto'); + var pipeId = crypto.createHash('md5').update(PM2_HOME).digest('hex').slice(0, 8); + pm2_file_stucture.DAEMON_RPC_PORT = '\\\\.\\pipe\\pm2-' + pipeId + '-rpc.sock'; + pm2_file_stucture.DAEMON_PUB_PORT = '\\\\.\\pipe\\pm2-' + pipeId + '-pub.sock'; + pm2_file_stucture.INTERACTOR_RPC_PORT = '\\\\.\\pipe\\pm2-' + pipeId + '-interactor.sock'; } return pm2_file_stucture;