util/anon_file: const string param
[mesa.git] / src / util / u_process.c
index 5e5927678d831c10af2216798cb5a0223b931538..371335303ec835b06dfa66337e6a3e5c2624adee 100644 (file)
 
 #undef GET_PROGRAM_NAME
 
-#if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__)
-#    if !defined(__GLIBC__) || (__GLIBC__ < 2)
-/* These aren't declared in any libc5 header */
-extern char *program_invocation_name, *program_invocation_short_name;
-#    endif
+#if defined(__linux__) && defined(HAVE_PROGRAM_INVOCATION_NAME)
+
+static char *path = NULL;
+
+static void __freeProgramPath()
+{
+   free(path);
+   path = NULL;
+}
+
 static const char *
 __getProgramName()
 {
    char * arg = strrchr(program_invocation_name, '/');
-   if (arg)
+   if (arg) {
+      /* If the / character was found this is likely a linux path or
+       * an invocation path for a 64-bit wine program.
+       *
+       * However, some programs pass command line arguments into argv[0].
+       * Strip these arguments out by using the realpath only if it was
+       * a prefix of the invocation name.
+       */
+      if (!path) {
+         path = realpath("/proc/self/exe", NULL);
+         atexit(__freeProgramPath);
+      }
+
+      if (path && strncmp(path, program_invocation_name, strlen(path)) == 0) {
+         /* This shouldn't be null because path is a a prefix,
+          * but check it anyway since path is static. */
+         char * name = strrchr(path, '/');
+         if (name)
+            return name + 1;
+      }
+
       return arg+1;
+   }
 
    /* If there was no '/' at all we likely have a windows like path from
     * a wine application.
@@ -54,7 +80,7 @@ __getProgramName()
    return program_invocation_name;
 }
 #    define GET_PROGRAM_NAME() __getProgramName()
-#elif defined(__CYGWIN__)
+#elif defined(HAVE_PROGRAM_INVOCATION_NAME)
 #    define GET_PROGRAM_NAME() program_invocation_short_name
 #elif defined(__FreeBSD__) && (__FreeBSD__ >= 2)
 #    include <osreldate.h>