]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blobdiff - linux/src/daemon/lad.c
lad: Allow only one instance of the daemon
[ipc/ipcdev.git] / linux / src / daemon / lad.c
index 11dc1a79c58e64613bfd494f85bd63a57113b2cd..c18e3dc357502e2a96ddbfc1ac9d23eeb0b8511f 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <ti/ipc/Std.h>
 
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -45,6 +46,7 @@
 #include <sys/types.h>
 #include <signal.h>
 #include <unistd.h>
+#include <dirent.h>
 
 #include <ti/ipc/MessageQ.h>
 #include <_MessageQ.h>
@@ -61,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;
@@ -79,7 +83,9 @@ 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);
 static Int connectToLAD(String clientName, Int pid, String clientProto, Int *clientIdPtr);
 static Void disconnectFromLAD(Int clientId);
@@ -145,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) {
 
@@ -160,6 +171,8 @@ int main(int argc, char * argv[])
                     "\nERROR: Failed to change to LAD's working directory!\n");
             exit(EXIT_FAILURE);
         }
+    } else {
+        cleanupFifos();
     }
 
     /* process command line args */
@@ -862,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 ========
  */
@@ -882,6 +963,38 @@ static LAD_ClientHandle assignClientId(Void)
     return(clientId);
 }
 
+/*
+ *  ======== cleanupFifos ========
+ */
+static void cleanupFifos(Void)
+{
+    DIR *dir;
+    struct dirent entry;
+    struct dirent *result;
+    size_t dirnamelen;
+    size_t maxcopy;
+    Char pathname[PATH_MAX];
+    Char *namep;
+
+    if ((dir = opendir(LAD_WORKINGDIR)) == NULL)
+        return;
+
+    dirnamelen = snprintf(pathname, sizeof(pathname), "%s/", LAD_WORKINGDIR);
+    if (dirnamelen >= sizeof(pathname)) {
+        closedir(dir);
+        return;
+    }
+    namep = pathname + dirnamelen;
+    maxcopy = PATH_MAX - dirnamelen;
+    while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
+        /* Delete old FIFOs left over */
+        if ((entry.d_type == DT_FIFO) && (strlen(entry.d_name) < maxcopy)) {
+            strncpy(namep, entry.d_name, maxcopy);
+            unlink(pathname);
+        }
+    }
+    closedir(dir);
+}
 
 /*
  *  ======== cleanupDepartedClients ========
@@ -983,9 +1096,6 @@ static Int connectToLAD(String clientName, Int pid, String clientProto, Int *cli
 
 openResponseFIFO:
 
-    /* if response FIFO exists from previous LAD session delete it now */
-    unlink(clientName);
-
     /* create the dedicated response FIFO to the client */
     statusIO = mkfifo(clientName, 0777);
     if (statusIO != 0) {