Browse Source

fix: enforce single-instance check with NSRunningApplication and lockfile guard

main
Ali Alavi 6 days ago
parent
commit
d6c07d036c
  1. 33
      src/main.swift

33
src/main.swift

@ -1,5 +1,38 @@
import Cocoa import Cocoa
func checkSingleInstance() {
let myPid = ProcessInfo.processInfo.processIdentifier
// 1. Check if another instance with bundle ID "com.soniox.voice" is already running
if let bundleID = Bundle.main.bundleIdentifier {
let runningApps = NSRunningApplication.runningApplications(withBundleIdentifier: bundleID)
for app in runningApps {
if app.processIdentifier != myPid {
fputs("SonioxVoice: Another instance (PID \(app.processIdentifier)) is already running. Exiting duplicate PID \(myPid).\n", stderr)
exit(0)
}
}
}
// 2. Fallback OS-level file lock (flock) on lockfile to prevent race conditions
let lockPath = NSTemporaryDirectory() + "com.soniox.voice.lock"
let fd = open(lockPath, O_CREAT | O_RDWR, 0o666)
if fd >= 0 {
if flock(fd, LOCK_EX | LOCK_NB) != 0 {
fputs("SonioxVoice: Lock file \(lockPath) is locked by another process. Exiting duplicate PID \(myPid).\n", stderr)
exit(0)
}
ftruncate(fd, 0)
let pidStr = "\(myPid)\n"
pidStr.withCString { ptr in
_ = write(fd, ptr, strlen(ptr))
}
// Keep fd open for process lifetime to maintain lock
}
}
checkSingleInstance()
let app = NSApplication.shared let app = NSApplication.shared
let delegate = AppDelegate() let delegate = AppDelegate()
app.delegate = delegate app.delegate = delegate

Loading…
Cancel
Save