Skip to content

Commit e35ad88

Browse files
committed
Add single-instance check to prevent duplicate daemon processes
AF_NDRV sockets allow multiple binds but only the first process receives packets. This caused silent failures when a previous lltdDaemon was still running. Now uses flock() on /tmp/lltdDaemon.lock to ensure only one instance runs at a time.
1 parent a32123b commit e35ad88

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

lltdDaemon/darwin/darwin-main.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111

1212
#include "../lltdDaemon.h"
13+
#include <sys/file.h>
14+
#include <fcntl.h>
15+
#include <unistd.h>
16+
#include <errno.h>
1317

1418
void SignalHandler(int Signal) {
1519
log_debug("Interrupted by signal #%d", Signal);
@@ -684,6 +688,41 @@ void deviceAppeared(void *refCon, io_iterator_t iterator){
684688
}
685689

686690

691+
//==============================================================================
692+
//
693+
// Check if another instance of lltdDaemon is already running.
694+
// Uses an exclusive lock on a file to ensure single instance.
695+
// Returns the lock fd on success, -1 if another instance is running.
696+
//
697+
//==============================================================================
698+
static int acquireInstanceLock(void) {
699+
const char *lockPath = "/tmp/lltdDaemon.lock";
700+
int lockFd = open(lockPath, O_CREAT | O_RDWR, 0644);
701+
if (lockFd < 0) {
702+
fprintf(stderr, "Warning: Could not open lock file %s: %s\n", lockPath, strerror(errno));
703+
return -1;
704+
}
705+
706+
if (flock(lockFd, LOCK_EX | LOCK_NB) < 0) {
707+
if (errno == EWOULDBLOCK) {
708+
fprintf(stderr, "Error: Another instance of lltdDaemon is already running.\n");
709+
fprintf(stderr, "Kill the existing process or wait for it to exit.\n");
710+
} else {
711+
fprintf(stderr, "Warning: Could not acquire lock: %s\n", strerror(errno));
712+
}
713+
close(lockFd);
714+
return -1;
715+
}
716+
717+
// Write our PID to the lock file for debugging
718+
ftruncate(lockFd, 0);
719+
char pidStr[32];
720+
snprintf(pidStr, sizeof(pidStr), "%d\n", getpid());
721+
write(lockFd, pidStr, strlen(pidStr));
722+
723+
return lockFd;
724+
}
725+
687726
//==============================================================================
688727
//
689728
// main
@@ -696,7 +735,16 @@ int main(int argc, const char *argv[]){
696735
mach_port_t masterPort;
697736
CFRunLoopSourceRef runLoopSource;
698737
io_iterator_t newDevicesIterator;
699-
738+
int lockFd;
739+
740+
//
741+
// Check for existing instance before doing anything else
742+
//
743+
lockFd = acquireInstanceLock();
744+
if (lockFd < 0) {
745+
return EXIT_FAILURE;
746+
}
747+
700748
//
701749
// Create a new Apple System Log facility entry
702750
// of Daemon type with the LLTD name

0 commit comments

Comments
 (0)