changeset 383:5eb7ee4ee819

Look up executable name based on /proc/self/exe
author Andre Heinecke <andre.heinecke@intevation.de>
date Tue, 15 Apr 2014 17:47:07 +0200
parents 124f08a85532
children 638db75f0fdf
files cinst/nssstore_linux.c
diffstat 1 files changed, 74 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/cinst/nssstore_linux.c	Tue Apr 15 17:46:16 2014 +0200
+++ b/cinst/nssstore_linux.c	Tue Apr 15 17:47:07 2014 +0200
@@ -11,11 +11,57 @@
 #include <sys/wait.h>
 #include <string.h>
 #include <stdlib.h>
+#include <limits.h>
 
 #include "nssstore.h"
 #include "logging.h"
 #include "strhelp.h"
 
+#define NSS_PROCESS_NAME "mozilla"
+
+/**@brief get the current path of the executable
+ *
+ * Looks up the current executables directory. The caller
+ * has to free the return value.
+ *
+ * The returned value includes the last /
+ *
+ * @returns the absolute directory of the currently executed executable or NULL
+ */
+char *
+get_exe_dir()
+{
+  char *retval = NULL,
+       *p = NULL,
+       buf[PATH_MAX];
+  ssize_t ret;
+  size_t path_len = 0;
+
+  ret = readlink ("/proc/self/exe", buf, PATH_MAX);
+  if (ret <= 0)
+    {
+      ERRORPRINTF ("readlink failed\n");
+      return NULL;
+    }
+
+  buf[ret] = '\0';
+
+  /* cut off the filename */
+  p = strrchr (buf, '/');
+  if (p == NULL)
+    {
+      ERRORPRINTF ("No filename found.\n");
+      return NULL;
+    }
+  *(p + 1) = '\0';
+
+  path_len = strlen (buf);
+  retval = xmalloc (path_len + 1);
+  strncpy (retval, buf, path_len);
+
+  return retval;
+}
+
 /**@brief Start the process to install / remove
  *
  * This forks the process and executes the NSS installation
@@ -35,9 +81,11 @@
 {
   int pipe_fd[2];
   pid_t pid = 0;
-  char *argv[] = {"mozilla", NULL},
-       *envp[2];
-  size_t homedir_len = 0;
+  char *argv[2] = {NULL, NULL},
+       *envp[2] = {NULL, NULL},
+       *inst_dir = NULL;
+  size_t homedir_len = 0,
+         exe_path_len = 0;
   int ret = -1,
       i = 0;
   FILE *stream = NULL;
@@ -64,7 +112,25 @@
       return -1;
     }
 
-  DEBUGPRINTF ("Home: %s \n", envp[0]);
+  /* Set up the file name of the installer process */
+  inst_dir = get_exe_dir();
+  if (inst_dir == NULL)
+    {
+      ERRORPRINTF ("Failed to find installation directory.\n");
+      xfree (envp[0]);
+      return -1;
+    }
+
+  exe_path_len = strlen(inst_dir) + strlen(NSS_PROCESS_NAME);
+  argv[0] = xmalloc (exe_path_len + 1);
+
+  ret = snprintf(argv[0], exe_path_len + 1, "%s%s", inst_dir, NSS_PROCESS_NAME);
+  if (ret < 0 || (size_t) ret != exe_path_len)
+    {
+      ERRORPRINTF ("Error setting executable variable.\n");
+      xfree (argv[0]);
+      return -1;
+    }
 
   if (pipe (pipe_fd))
     {
@@ -92,7 +158,7 @@
       dup2 (pipe_fd[0], 0);
       close (pipe_fd[0]);
       /* TODO find path based on current executable */
-      execve ("mozilla", argv, envp);
+      execve (argv[0], argv, envp);
       exit (127);
     }
 
@@ -129,9 +195,10 @@
   if (stream) {
     fclose (stream);
   }
+  xfree (argv[0]);
   xfree (envp[0]);
-  close(pipe_fd[0]);
-  close(pipe_fd[1]);
+  close (pipe_fd[0]);
+  close (pipe_fd[1]);
 
   if (success)
     {
@@ -171,7 +238,6 @@
           ERRORPRINTF ("Waitpid failed.\n");
           return -1;
         }
-      DEBUGPRINTF ("Child returned status: %i\n", WEXITSTATUS(status));
 
       return 0;
     }

http://wald.intevation.org/projects/trustbridge/