[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