lad: Allow only one instance of the daemon
authorMisael Lopez Cruz <misael.lopez@ti.com>
Thu, 3 Dec 2015 00:29:11 +0000 (18:29 -0600)
committerAngela Stegmaier <angelabaker@ti.com>
Tue, 5 Jan 2016 18:59:26 +0000 (12:59 -0600)
Make sure only one instance of the LAD daemon is running
at a time.  This implementation is based on syslink's
daemon.

Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
linux/src/daemon/lad.c

index 1c7c7072e7a506b7aded1c82b3b7701b5ba34422..c18e3dc357502e2a96ddbfc1ac9d23eeb0b8511f 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <ti/ipc/Std.h>
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -62,6 +63,8 @@
 
 #define DAEMON        1           /* 1 = run as a daemon; 0 = run as app */
 
+#define READ_BUF_SIZE 50
+
 Bool logFile = FALSE;
 FILE *logPtr = NULL;
 struct timeval start_tv;
@@ -80,6 +83,7 @@ static Char clientFIFOName[LAD_MAXNUMCLIENTS][LAD_MAXLENGTHFIFONAME];
 static FILE * responseFIFOFilePtr[LAD_MAXNUMCLIENTS];
 
 /* local internal routines */
+static Bool isDaemonRunning(Char *pidName);
 static LAD_ClientHandle assignClientId(Void);
 static Void cleanupFifos(Void);
 static Void cleanupDepartedClients(Void);
@@ -147,6 +151,11 @@ int main(int argc, char * argv[])
         }
     }
 
+    if (isDaemonRunning(argv[0])) {
+        printf("Multiple instances of LAD are not supported!\n");
+        exit(EXIT_FAILURE);
+    }
+
     /* change to LAD's working directory */
     if ((chdir(LAD_WORKINGDIR)) < 0) {
 
@@ -866,6 +875,74 @@ exitNow:
 }
 
 
+/*
+ *  ======== isDaemonRunning ========
+ */
+static Bool isDaemonRunning(Char *pidName)
+{
+    DIR *dir;
+    pid_t pid;
+    Int dirNum;
+    FILE *fp;
+    struct dirent * next;
+    Bool isRunning = FALSE;
+    Char filename [READ_BUF_SIZE];
+    Char buffer [READ_BUF_SIZE];
+    Char *bptr = buffer;
+    Char *name;
+
+    pid = getpid();
+    dir = opendir("/proc");
+    if (!dir) {
+        printf("Warning: Cannot open /proc filesystem\n");
+        return isRunning;
+    }
+
+    name = strrchr(pidName, '/');
+    if (name) {
+        pidName = (name + 1);
+    }
+
+    while ((next = readdir(dir)) != NULL) {
+        /* If it isn't a number, we don't want it */
+        if (!isdigit(*next->d_name)) {
+            continue;
+        }
+
+        dirNum = strtol(next->d_name, NULL, 10);
+        if (dirNum == pid) {
+            continue;
+        }
+
+        snprintf(filename, READ_BUF_SIZE, "/proc/%s/cmdline", next->d_name);
+        if (!(fp = fopen(filename, "r"))) {
+            continue;
+        }
+        if (fgets(buffer, READ_BUF_SIZE, fp) == NULL) {
+            fclose(fp);
+            continue;
+        }
+        fclose (fp);
+
+        name = strrchr(buffer, '/');
+        if (name && (name + 1)) {
+            bptr = name + 1;
+        }
+        else {
+            bptr = buffer;
+        }
+
+        /* Buffer should contain the entire command line */
+        if (strcmp(bptr, pidName) == 0) {
+            isRunning = TRUE;
+            break;
+        }
+    }
+    closedir (dir);
+
+    return isRunning;
+}
+
 /*
  *  ======== assignClientId ========
  */