libtool-patches
[Top][All Lists]
Advanced

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

[PATCH] libtool on cygwin [4/4]: wrapperexe [resend]


From: Charles Wilson
Subject: [PATCH] libtool on cygwin [4/4]: wrapperexe [resend]
Date: Wed, 05 Nov 2003 05:21:30 -0500
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624

See changelog for explanation.

--
Chuck

2003-07-12  Charles Wilson  <address@hidden>

        * ltmain.in: binary wrapper used with uninstalled
        executables on cygwin/mingw breaks when invoked
        via execlp/execvp (that is, via $PATH).  Add new
        C functions find_executable() and check_executable()
        to handle that case.
Index: ltmain.in
===================================================================
RCS file: /cvsroot/libtool/libtool/ltmain.in,v
retrieving revision 1.352
diff -u -r1.352 ltmain.in
--- ltmain.in   1 Nov 2003 15:03:09 -0000       1.352
+++ ltmain.in   3 Nov 2003 16:33:43 -0000
@@ -4607,6 +4607,7 @@
 #include <malloc.h>
 #include <stdarg.h>
 #include <assert.h>
+#include <sys/stat.h>
 
 #if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
@@ -4617,15 +4618,19 @@
 #endif
 
 #ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
 #endif
 
 #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
   defined (__OS2__)
-#define HAVE_DOS_BASED_FILE_SYSTEM
-#ifndef DIR_SEPARATOR_2
-#define DIR_SEPARATOR_2 '\\'
-#endif
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2 
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2 
+#  define PATH_SEPARATOR_2 ';'
+# endif
 #endif
 
 #ifndef DIR_SEPARATOR_2
@@ -4635,17 +4640,30 @@
         (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
 #endif /* DIR_SEPARATOR_2 */
 
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
 #define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
 #define XFREE(stale) do { \
   if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...) 
+#endif
+
 const char *program_name = NULL;
 
 void * xmalloc (size_t num);
 char * xstrdup (const char *string);
 char * basename (const char *name);
-char * fnqualify(const char *path);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
 char * strendzap(char *str, const char *pat);
 void lt_fatal (const char *message, ...);
 
@@ -4656,6 +4674,8 @@
   int i;
 
   program_name = (char *) xstrdup ((char *) basename (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
   newargz = XMALLOC(char *, argc+2);
 EOF
 
@@ -4664,13 +4684,23 @@
 EOF
 
            cat >> $cwrappersource <<"EOF"
-  newargz[1] = fnqualify(argv[0]);
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
   /* we know the script has the same name, without the .exe */
   /* so make sure newargz[1] doesn't end in .exe */
   strendzap(newargz[1],".exe");
   for (i = 1; i < argc; i++)
     newargz[i+1] = xstrdup(argv[i]);
   newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
 EOF
 
            cat >> $cwrappersource <<EOF
@@ -4714,31 +4744,125 @@
   return (char *) base;
 }
 
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : 
"NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (((st.st_mode & S_IXOTH) == S_IXOTH) ||
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+       ((st.st_mode & S_IXUSR) == S_IXUSR)))
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
 char *
-fnqualify(const char *path)
+find_executable (const char* wrapper)
 {
-  size_t size;
-  char *p;
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  struct stat st;
+  /* static buffer for getcwd */
   char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
 
-  assert(path != NULL);
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") 
: "NULL!");
+  
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
 
-  /* Is it qualified already? */
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha (wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
+#endif
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
-  if (isalpha (path[0]) && path[1] == ':')
-    return xstrdup (path);
+  }
 #endif
-  if (IS_DIR_SEPARATOR (path[0]))
-    return xstrdup (path);
 
-  /* prepend the current directory */
-  /* doesn't handle '~' */
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
   if (getcwd (tmp, LT_PATHMAX) == NULL)
     lt_fatal ("getcwd failed");
-  size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
-  p = XMALLOC(char, size);
-  sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
-  return p;
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
 }
 
 char *

reply via email to

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