[AD] No more END_OF_MAIN on *nix!

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


well, with the attached patch at least, which is an update of my previous 
patch that adds procfs support to get_executable_name.

This patch gets rid of the magic_main mangling in UNIX, using procfs if 
available to grab a copy of the running program.
If procfs is not available, it tries to shell out and get the name of the 
executable from the pid by querying the ps command. This is not as good as 
using procfs, but in my tests not less reliable than depending on argv[0]. 
It depends on the ps command being available (not a big demand IMO) and 
delivering its output in the same format across platforms (this may be 
more of a concern).

Comments?

Evert
diff -r -u allegro/docs/src/allegro._tx alleg_no_magic_main/docs/src/allegro._tx
--- allegro/docs/src/allegro._tx	2004-08-01 15:30:42.000000000 +0200
+++ alleg_no_magic_main/docs/src/allegro._tx	2004-08-01 14:34:08.000000000 +0200
@@ -4761,9 +4761,6 @@
    circle, 64 a right angle, etc. All rotation functions can draw between any
    two bitmaps, even screen bitmaps or bitmaps of different color depth.
 
-   Positive increments of the angle will make the sprite rotate clockwise
-   on the screen, as demonstrated by the Allegro example.
-
 @@void @rotate_sprite_v_flip(BITMAP *bmp, BITMAP *sprite, int x, int y, fixed angle);
 @xref rotate_sprite, rotate_scaled_sprite_v_flip
 @xref pivot_sprite_v_flip, pivot_scaled_sprite_v_flip
diff -r -u allegro/include/allegro/platform/alunix.h alleg_no_magic_main/include/allegro/platform/alunix.h
--- allegro/include/allegro/platform/alunix.h	2004-04-09 12:37:45.000000000 +0200
+++ alleg_no_magic_main/include/allegro/platform/alunix.h	2004-08-01 16:00:01.000000000 +0200
@@ -21,21 +21,6 @@
 #endif
 
 
-/* magic to capture name of executable file */
-extern int    __crt0_argc;
-extern char **__crt0_argv;
-
-#ifndef ALLEGRO_NO_MAGIC_MAIN
-   #define ALLEGRO_MAGIC_MAIN
-   #define main _mangled_main
-   #undef END_OF_MAIN
-   #define END_OF_MAIN() void *_mangled_main_address = (void*) _mangled_main;
-#else
-   #undef END_OF_MAIN
-   #define END_OF_MAIN() void *_mangled_main_address;
-#endif
-
-
 
 /**************************************/
 /************ General Unix ************/
diff -r -u allegro/src/unix/usystem.c alleg_no_magic_main/src/unix/usystem.c
--- allegro/src/unix/usystem.c	2004-07-28 19:56:56.000000000 +0200
+++ alleg_no_magic_main/src/unix/usystem.c	2004-08-01 16:27:13.000000000 +0200
@@ -16,6 +16,7 @@
  */
 
 
+#include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -240,45 +241,50 @@
 #ifndef ALLEGRO_MACOSX
 
 /* _unix_get_executable_name:
- *  Return full path to the current executable.
+ *  Return full path to the current executable, use proc fs if available.
  */
 void _unix_get_executable_name(char *output, int size)
 {
+   FILE *pipe;
+   char linkname[1024];
+   char filename[1024];
+   struct stat buf;
    char *path;
-
-   /* If argv[0] has no explicit path, but we do have $PATH, search there */
-   if (!strchr (__crt0_argv[0], '/') && (path = getenv("PATH"))) {
-      char *start = path, *end = path, *buffer = NULL, *temp;
-      struct stat finfo;
-
-      while (*end) {
-	 end = strchr (start, ':');
-	 if (!end) end = strchr (start, '\0');
-
-	 /* Resize `buffer' for path component, slash, argv[0] and a '\0' */
-	 temp = realloc (buffer, end - start + 1 + strlen (__crt0_argv[0]) + 1);
-	 if (temp) {
-	    buffer = temp;
-
-	    _al_sane_strncpy (buffer, start, end - start);
-	    *(buffer + (end - start)) = '/';
-	    _al_sane_strncpy (buffer + (end - start) + 1, __crt0_argv[0], end - start + 1 + strlen (__crt0_argv[0]) + 1);
-
-	    if ((stat(buffer, &finfo)==0) && (!S_ISDIR (finfo.st_mode))) {
-	       do_uconvert (buffer, U_ASCII, output, U_CURRENT, size);
-	       free (buffer);
-	       return;
-	    }
-	 } /* else... ignore the failure; `buffer' is still valid anyway. */
-
-	 start = end + 1;
+   pid_t pid;
+   int len;
+   
+   /* get symolic link to executable from proc fs */
+   pid = getpid();
+   uszprintf (filename, sizeof(filename), "/proc/%d/exe", pid);
+   do_uconvert (filename, U_CURRENT, linkname, U_ASCII, size);
+   
+   if (stat (linkname, &buf) == 0) {
+      len = readlink (linkname, filename, sizeof(filename)-1);
+      if (len>-1) {
+	 filename[len] = '\0';
+         
+	 do_uconvert (filename, U_ASCII, output, U_CURRENT, size);
+	 return;
       }
-      /* Path search failed */
-      free (buffer);
    }
-
-   /* If argv[0] had a slash, or the path search failed, just return argv[0] */
-   do_uconvert (__crt0_argv[0], U_ASCII, output, U_CURRENT, size);
+   
+   /* Cannot stat file or resolve symlink */
+   /* Try using the output of the ps command to at least find the name of */
+   /* the file if not the full path */
+   uszprintf (linkname, sizeof(linkname), "ps -o \"%%a\" -p %d", pid);
+   do_uconvert (linkname, U_CURRENT, filename, U_ASCII, size);
+   pipe = popen(filename, "r");
+   if (pipe) {
+      /* First line of output is junk, second line is the info we want */
+      fgets(filename, sizeof(filename), pipe);
+      fgets(filename, sizeof(filename), pipe);
+      pclose(pipe);
+      do_uconvert (filename, U_ASCII, output, U_CURRENT, size);
+      return;
+   }
+   
+   /* Give up; return empty string */
+   do_uconvert ("", U_ASCII, output, U_CURRENT, size);
 }
 
 #endif


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/