gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r8252 - in GNUnet/src: include util/os


From: gnunet
Subject: [GNUnet-SVN] r8252 - in GNUnet/src: include util/os
Date: Mon, 16 Feb 2009 01:49:26 -0700

Author: holindho
Date: 2009-02-16 01:49:25 -0700 (Mon, 16 Feb 2009)
New Revision: 8252

Modified:
   GNUnet/src/include/gnunet_util_os.h
   GNUnet/src/util/os/installpath.c
Log:
fix mantis 1453


Modified: GNUnet/src/include/gnunet_util_os.h
===================================================================
--- GNUnet/src/include/gnunet_util_os.h 2009-02-16 07:26:28 UTC (rev 8251)
+++ GNUnet/src/include/gnunet_util_os.h 2009-02-16 08:49:25 UTC (rev 8252)
@@ -312,7 +312,8 @@
   GNUNET_IPK_BINDIR,
   GNUNET_IPK_LIBDIR,
   GNUNET_IPK_DATADIR,
-  GNUNET_IPK_LOCALEDIR
+  GNUNET_IPK_LOCALEDIR,
+  GNUNET_IPK_SELF_PREFIX
 };
 
 /**

Modified: GNUnet/src/util/os/installpath.c
===================================================================
--- GNUnet/src/util/os/installpath.c    2009-02-16 07:26:28 UTC (rev 8251)
+++ GNUnet/src/util/os/installpath.c    2009-02-16 08:49:25 UTC (rev 8252)
@@ -42,12 +42,51 @@
 #include "gnunet_util_config.h"
 #include "gnunet_util_disk.h"
 #include "gnunet_util_os.h"
+#if OSX
+#include <mach-o/ldsyms.h>
+#include <mach-o/dyld.h>
+#endif
 
 #if LINUX
 /**
  * Try to determine path by reading /proc/PID/exe
  */
 static char *
+get_path_from_proc_maps ()
+{
+  char fn[64];
+  char *line;
+  char *dir;
+  FILE * f;
+
+  GNUNET_snprintf (fn, 64, "/proc/%u/maps", getpid());
+  line = GNUNET_malloc (1024);
+  dir = GNUNET_malloc (1024);
+  f = fopen(fn, "r");
+  if (f != NULL) {
+    while (NULL != fgets(line, 1024, f)) {
+      if ( (1 == sscanf(line,
+                       "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s",
+                       dir)) &&
+          (NULL != strstr(dir,
+                          "libgnunetutil")) ) {
+       strstr(dir, "libgnunetutil")[0] = '\0';
+       fclose(f);
+        GNUNET_free (line);
+       return dir;
+      }
+    }
+    fclose(f);
+  }
+  GNUNET_free (dir);
+  GNUNET_free (line);
+  return NULL;
+}
+
+/**
+ * Try to determine path by reading /proc/PID/exe
+ */
+static char *
 get_path_from_proc_exe ()
 {
   char fn[64];
@@ -136,6 +175,31 @@
   path[len] = '\0';
   return path;
 }
+
+static char * get_path_from_dyld_image() {
+  const char * path;
+  char * p, * s;
+  int i;
+  int c;
+
+  p = NULL;
+  c = _dyld_image_count();
+  for (i = 0; i < c; i++) {
+    if (_dyld_get_image_header(i) == &_mh_dylib_header) {
+      path = _dyld_get_image_name(i);
+      if (path != NULL && strlen(path) > 0) {
+        p = strdup(path);
+        s = p + strlen(p);
+        while ( (s > p) && (*s != '/') )
+          s--;
+        s++;
+        *s = '\0';
+      }
+      break;
+    }
+  }
+  return p;
+}
 #endif
 
 static char *
@@ -194,13 +258,13 @@
 }
 
 /*
- * @brief get the path to the executable, including the binary itself
+ * @brief get the path to GNUnet bin/ or lib/, prefering the lib/ path
  * @author Milan
  *
  * @return a pointer to the executable path, or NULL on error
  */
 static char *
-os_get_exec_path ()
+os_get_gnunet_path ()
 {
   char *ret;
 
@@ -208,6 +272,9 @@
   if (ret != NULL)
     return ret;
 #if LINUX
+  ret = get_path_from_proc_maps ();
+  if (ret != NULL)
+    return ret;
   ret = get_path_from_proc_exe ();
   if (ret != NULL)
     return ret;
@@ -218,6 +285,9 @@
     return ret;
 #endif
 #if OSX
+  ret = get_path_from_dyld_image ();
+  if (ret != NULL)
+    return ret;
   ret = get_path_from_NSGetExecutablePath ();
   if (ret != NULL)
     return ret;
@@ -229,10 +299,41 @@
   return NULL;
 }
 
+/*
+ * @brief get the path to current app's bin/
+ * @author Milan
+ *
+ * @return a pointer to the executable path, or NULL on error
+ */
+static char *
+os_get_exec_path ()
+{
+  char *ret;
 
+#if LINUX
+  ret = get_path_from_proc_exe ();
+  if (ret != NULL)
+    return ret;
+#endif
+#if WINDOWS
+  ret = get_path_from_module_filename ();
+  if (ret != NULL)
+    return ret;
+#endif
+#if OSX
+  ret = get_path_from_NSGetExecutablePath ();
+  if (ret != NULL)
+    return ret;
+#endif
+  /* other attempts here */
+  return NULL;
+}
 
+
+
 /*
- * @brief get the path to a specific app dir
+ * @brief get the path to a specific GNUnet installation directory or,
+ * with GNUNET_IPK_SELF_PREFIX, the current running apps installation directory
  * @author Milan
  * @return a pointer to the dir path (to be freed by the caller)
  */
@@ -241,11 +342,19 @@
 {
   size_t n;
   const char *dirname;
-  char *execpath;
+  char *execpath = NULL;
   char *tmp;
 
-  execpath = os_get_exec_path ();
+  /* if wanted, try to get the current app's bin/ */
+  if (dirkind == GNUNET_IPK_SELF_PREFIX)
+    execpath = os_get_exec_path ();
+  
+  /* try to get GNUnet's bin/ or lib/, or if previous was unsuccessful some
+   * guess for the current app */
   if (execpath == NULL)
+    execpath = os_get_gnunet_path ();
+
+  if (execpath == NULL)
     return NULL;
 
   n = strlen (execpath);
@@ -255,20 +364,22 @@
       GNUNET_free (execpath);
       return NULL;
     }
-  if (execpath[n - 1] == DIR_SEPARATOR)
+  while (n > 1 && execpath[n - 1] == DIR_SEPARATOR)
     execpath[--n] = '\0';
 
-  if ((n > 3) && (0 == strcasecmp (&execpath[n - 3], "bin")))
+  if ((n > 3) && ((0 == strcasecmp (&execpath[n - 3], "bin")) ||
+                  (0 == strcasecmp (&execpath[n - 3], "lib"))))
     {
-      /* good, strip of '/bin'! */
+      /* strip '/bin/' or '/lib/' */
       execpath[n - 3] = '\0';
       n -= 3;
-      if (execpath[n - 1] == DIR_SEPARATOR)
+      while (n > 1 && execpath[n - 1] == DIR_SEPARATOR)
         execpath[--n] = '\0';
     }
   switch (dirkind)
     {
     case GNUNET_IPK_PREFIX:
+    case GNUNET_IPK_SELF_PREFIX:
       dirname = DIR_SEPARATOR_STR;
       break;
     case GNUNET_IPK_BINDIR:





reply via email to

[Prev in Thread] Current Thread [Next in Thread]