* Decide whether `profileDir` holds a stale Chromium SingletonLock. Chromium * writes the lock as a symlink whose target is ` - `. If the * hostname differs from ours (different container) or the pid isn't alive, * the lock is left over from a prior process and Brave will refuse to l
(profileDir: string)
| 270 | * until it's removed. |
| 271 | */ |
| 272 | function lockIsStale(profileDir: string): boolean { |
| 273 | const lockPath = path.join(profileDir, 'SingletonLock'); |
| 274 | let target: string; |
| 275 | try { |
| 276 | target = fs.readlinkSync(lockPath); |
| 277 | } catch (err) { |
| 278 | if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false; |
| 279 | // File exists but isn't a symlink we can read — unparseable, treat as |
| 280 | // stale so we clear it rather than leave Brave wedged. |
| 281 | return true; |
| 282 | } |
| 283 | |
| 284 | // Hostnames can contain hyphens (Docker uses 12-char hex which can't, but |
| 285 | // be defensive), so split from the right. |
| 286 | const dash = target.lastIndexOf('-'); |
| 287 | if (dash < 0) return true; |
| 288 | const host = target.slice(0, dash); |
| 289 | const pid = Number(target.slice(dash + 1)); |
| 290 | |
| 291 | if (host !== os.hostname()) return true; |
| 292 | if (!Number.isFinite(pid) || pid <= 0) return true; |
| 293 | |
| 294 | try { |
| 295 | process.kill(pid, 0); |
| 296 | return false; |
| 297 | } catch { |
| 298 | return true; |
| 299 | } |
| 300 | } |
| 301 | |
| 302 | /** |
| 303 | * Walk every profile under `~/.corebrain/browser-profiles/` and remove |
no test coverage detected