[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [cygwin] cwrapper emits wrapper script
From: |
Charles Wilson |
Subject: |
Re: [cygwin] cwrapper emits wrapper script |
Date: |
Fri, 27 Apr 2007 15:27:15 -0400 |
User-agent: |
Thunderbird 1.5.0.10 (Windows/20070221) |
This is a revised version of the patch that first appeared here:
http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00050.html
Please refer to that message for a discussion of the theory of this
patch, its effects, and justification.
This patch is "phase 2" in the 3-phase sequence of changes intended to
eliminate the presence of both "foo.exe" and "foo" wrappers in the same
directory, which (a) is confusing to humans (b) is sometimes confusing
to cygwin/mingw tools, given evolving behavior with respect to .exe
suffix presence/absence, and (c) is totally broken on cygwin if the
'transparent_exe' option is active.
Hopefully this patch address the concerns raised by Ralf and others in
response to the original post. Also note that this patch fixes a
long-standing breakage in the executable wrapper on mingw -- although I
could not use Ralf's suggesting directly:
lt_mingwSHELL=`( cmd //c echo $SHELL ) 2>/dev/null || echo $SHELL`
because 'cmd' appends an empty space to the end of lt_mingwSHELL,
eventually leading to "C:/blah/blah/blah/sh .exe". Bad. I used this,
instead:
lt_sed_strip_trailing_spaces="s/[ ]*\$//"
lt_newargv0=`( cmd //c echo $SHELL | $SED -e
"$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Technically, this "patch" is divided into two separate patches: the
first implements the new functionality and addressed all but one of the
criticisms (I hope). The second addresses this comment:
> Please use GCS formatting, as far as possible (several instances),
To effect this change, I iteratively performed the following sequence of
steps:
(1) used libtool to generate a wrapped executable, and grabbed a copy of
the lt-*.c executable wrapper source code.
(2) using the options listed here:
http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
invoked indent on the source code
(3) generate a before-vs-after diff between the two versions of the
source code
(4) edit ltmain.m4sh (func_emit_libtool_cwrapperexe_source) to replicate
these changes (obviously, the diff can't actually be applied to the
.m4sh file)
(5) repeat from (1) until the diff generated in (3) is empty [*].
[*] actually, it never did get completely empty, because indent insists
on rearranging the last few lines of the embedded wrapper script:
216,219c216
< " exit 1\n"
< " fi\n"
< "fi\n"
< ;
---
> " exit 1\n" " fi\n" "fi\n";
I figured that small deviation from GCS didn't matter.
This limitation still applies:
POSSIBLE LIMITATION:
assumes that if S_ISLNK is defined, then $host has lstat() and
realpath(). Since the only place this matters (at present) is cygwin
and mingw, this assumption is safe: cygwin has all three, mingw has
none. The new code [chase_symlinks()] which makes this assumption was
added so that symlinks to the wrapper executable would work as expected
(on systems where symlinks exist) just like symlinks to the wrapper
script work.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TESTING:
Ran full test suite on cygwin, mingw, and linux. No regressions from here:
http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00081.html
http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00073.html
although the test numbers have changed.
__________________________________________________________
Tested on cygwin (full testsuite) with expected results:
======================
All 115 tests passed
(9 tests were not run)
======================
14: Java convenience archives FAILED (convenience.at:273)
16: Link order of deplibs. FAILED (link-order2.at:129)
52: Run tests with low max_cmd_len FAILED (cmdline_wrap.at:43)
This is the expected output, for now.
___________________________________________________________
Linux, full testsuite:
====================
All 106 tests passed
====================
50 tests behaved as expected.
2 tests were skipped.
___________________________________________________________
mingw, full testsuite:
======================
All 115 tests passed
(9 tests were not run)
======================
14: Java convenience archives FAILED (convenience.at:273)
16: Link order of deplibs. FAILED (link-order2.at:129)
25: DESTDIR with in-package deplibs FAILED (destdir.at:131)
33: installable libltdl FAILED (standalone.at:69)
37: installable libltdl FAILED (subproject.at:99)
41: installable libltdl FAILED (nonrecursive.at:143)
44: installable libltdl FAILED (recursive.at:113)
52: Run tests with low max_cmd_len FAILED (cmdline_wrap.at:43)
As noted previously, 33,37,41,44 appear to be due to msys trying to
execute "INSTALL" as if it were install.exe. Not sure about 25, but
14/16/51 are the same as cygwin. None of these errors represent
regressions from
http://lists.gnu.org/archive/html/libtool-patches/2007-04/msg00081.html
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ChangeLog(s):
Note: libtool-cwrapper-emits-shwrapper-20070427.patch should be applied
first, then libtool-use-GCS-for-cwrapper-20070427.patch -- so in the
real ChangeLog, the following two entries should be reversed.
2007-04-27 Charles Wilson <address@hidden>
* ltmain.m4sh (func_emit_libtool_wrapper_script): add
code block to handle cases when wrapper script is in $objdir.
(func_emit_libtool_cwrapperexe_source): replace DEBUG() macro
with namespace-safe LTWRAPPER_DEBUGPRINTF(). Call
func_emit_libtool_wrapper_script() with appropriate filters to
embed script text in C char* static variable.
(f_e_l_c_s: main): add new option --lt-dump-script, parse argv[]
for it, and take appropriate action. Call chase_symlinks()
on argv[0], in case this.exe was launched via one. Use chased
value to determine full absolute pathname of wrapper script, in
$objdir. Unconditionally write script out to this pathname and
set permission bits. Remove extraneous ';' from debugging loop.
(f_e_l_c_s: main) [mingw]: DOS-ize $SHELL before populating
newargv[0]; if $TARGETSHELL environment variable is set, use
it instead of $SHELL and do not DOS-ize. Ensure newargv[1]
(wrapper script absolute path) uses only '/', not '\'. Make
sure to call execv() with DOS-ized $SHELL (or un-DOS-ized
$TARGETSHELL, if set)
(f_e_l_c_s: make_executable): new function
(f_e_l_c_s: chase_symlinks): new function (no-op if !S_ISLNK)
2007-04-27 Charles Wilson <address@hidden>
* ltmain.m4sh (func_emit_libtool_cwrapperexe_source):
ensure that generated source follows GCS as nearly as
possible.
--
Chuck
Index: libltdl/config/ltmain.m4sh
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v
retrieving revision 1.74
diff -u -r1.74 ltmain.m4sh
--- libltdl/config/ltmain.m4sh 2007-04-24 23:04:28.546875000 -0400
+++ libltdl/config/ltmain.m4sh 2007-04-27 03:52:20.109375000 -0400
@@ -2301,6 +2301,20 @@
file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
done
+ # cygwin/mingw cwrapper will rewrite this line:
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e
's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
# Try to get the absolute directory name.
absdir=\`cd \"\$thisdir\" && pwd\`
test -n \"\$absdir\" && thisdir=\"\$absdir\"
@@ -2424,7 +2438,7 @@
This wrapper executable should never be moved out of the build directory.
If it is, it will not operate correctly.
- Currently, it simply execs the wrapper *script* "/bin/sh $output",
+ Currently, it simply execs the wrapper *script* "$SHELL $output",
but could eventually absorb all of the scripts functionality and
exec $objdir/$outputname directly.
*/
@@ -2438,6 +2452,7 @@
#include <assert.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include <sys/stat.h>
#if defined(PATH_MAX)
@@ -2482,12 +2497,11 @@
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
-/* -DDEBUG is fairly common in CFLAGS. */
-#undef DEBUG
+#undef LTWRAPPER_DEBUGPRINTF
#if defined DEBUGWRAPPER
-# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+# define LTWRAPPER_DEBUGPRINTF(format, ...) fprintf(stderr, format,
__VA_ARGS__)
#else
-# define DEBUG(format, ...)
+# define LTWRAPPER_DEBUGPRINTF(format, ...)
#endif
const char *program_name = NULL;
@@ -2496,42 +2510,145 @@
char * xstrdup (const char *string);
const char * base_name (const char *name);
char * find_executable(const char *wrapper);
+char * chase_symlinks(const char *pathspec);
+int make_executable(const char *path);
int check_executable(const char *path);
char * strendzap(char *str, const char *pat);
void lt_fatal (const char *message, ...);
+static const char* script_text =
+EOF
+
+ func_emit_libtool_wrapper_script |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/\(WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\)=.*/\1=yes/' \
+ -e 's/^/"/' -e 's/$/\\n"/'
+ echo ";"
+
+ cat <<EOF
int
main (int argc, char *argv[])
{
char **newargz;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *shwrapper_name;
+ FILE *shwrapper;
+
+ const char* dumpscript_opt = "--lt-dump-script";
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
- DEBUG("(main) argv[0] : %s\n",argv[0]);
- DEBUG("(main) program_name : %s\n",program_name);
+ LTWRAPPER_DEBUGPRINTF("(main) argv[0] : %s\n",argv[0]);
+ LTWRAPPER_DEBUGPRINTF("(main) program_name : %s\n",program_name);
+
+ /* very simple arg parsing; don't want to rely on getopt */
+ for (i=1; i<argc; i++)
+ {
+ if (strcmp(argv[i], dumpscript_opt) == 0)
+ {
+ printf("%s", script_text);
+ return 0;
+ }
+ }
+
newargz = XMALLOC(char *, argc+2);
EOF
- cat <<EOF
- newargz[0] = (char *) xstrdup("$SHELL");
+ if test -n "$TARGETSHELL" ; then
+ # no path translation at all
+ lt_newargv0=$TARGETSHELL
+ else
+ case "$host" in
+ *mingw* )
+ # awkward: cmd appends spaces to result
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ lt_newargv0=`( cmd //c echo $SHELL | $SED -e
"$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
+ case $lt_newargv0 in
+ *.exe | *.EXE) ;;
+ *) lt_newargv0=$lt_newargv0.exe ;;
+ esac
+ ;;
+ * ) lt_newargv0=$SHELL ;;
+ esac
+ fi
+
+ cat <<EOF
+ newargz[0] = (char *) xstrdup("$lt_newargv0");
EOF
cat <<"EOF"
- newargz[1] = find_executable(argv[0]);
- if (newargz[1] == NULL)
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == 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");
+ LTWRAPPER_DEBUGPRINTF("(main) found exe (before symlink chase) at :
%s\n",tmp_pathspec);
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF("(main) found exe (after symlink chase) at :
%s\n",actual_cwrapper_path);
+ XFREE(tmp_pathspec);
+
+ shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
+ strendzap( actual_cwrapper_path, shwrapper_name );
+
+ /* shwrapper_name transforms */
+ strendzap(shwrapper_name,".exe");
+ tmp_pathspec = XMALLOC( char, strlen ( shwrapper_name ) +
+ strlen ( "_ltshwrapper" ) + 1 );
+ strcpy ( tmp_pathspec, shwrapper_name );
+ strcat ( tmp_pathspec, "_ltshwrapper" );
+ XFREE( shwrapper_name );
+ shwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+ LTWRAPPER_DEBUGPRINTF("(main) libtool shell wrapper name:
%s\n",shwrapper_name);
+EOF
+
+ cat <<EOF
+ newargz[1] = XMALLOC( char, strlen ( actual_cwrapper_path ) +
+ strlen ( "$objdir" ) + 1 +
+ strlen ( shwrapper_name ) + 1 );
+ strcpy ( newargz[1], actual_cwrapper_path );
+ strcat ( newargz[1], "$objdir" );
+ strcat ( newargz[1], "/" );
+ strcat ( newargz[1], shwrapper_name );
+EOF
+
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while( (p = strchr(newargz[1], '\\')) != NULL) {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE( shwrapper_name );
+ XFREE( actual_cwrapper_path );
+
+ /* note: do NOT use "wt" here! -- defer to underlying
+ * mount type on cygwin
+ */
+ if ( (shwrapper = fopen (newargz[1], "w")) == 0 )
+ {
+ lt_fatal("Could not open %s for writing", newargz[1]);
+ }
+ fprintf (shwrapper, "%s", script_text);
+ fclose (shwrapper);
+
+ make_executable( newargz[1] );
+
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]);
- ;
+ LTWRAPPER_DEBUGPRINTF("(main) newargz[%d] : %s\n",i,newargz[i]);
}
EOF
@@ -2539,14 +2656,14 @@
case $host_os in
mingw*)
cat <<EOF
- execv("$SHELL",(char const **)newargz);
+ execv ("$lt_newargv0", (const char * const *) newargz);
EOF
- ;;
+ ;;
*)
cat <<EOF
- execv("$SHELL",newargz);
+ execv ("$lt_newargv0", newargz);
EOF
- ;;
+ ;;
esac
cat <<"EOF"
@@ -2592,7 +2709,7 @@
{
struct stat st;
- DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") :
"NULL!");
+ LTWRAPPER_DEBUGPRINTF("(check_executable) : %s\n", path ? (*path ? path :
"EMPTY!") : "NULL!");
if ((!path) || (!*path))
return 0;
@@ -2612,8 +2729,37 @@
return 0;
}
+int
+make_executable(const char * path)
+{
+ int rval = 0;
+ struct stat st;
+
+ /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+ int S_XFLAGS =
+#if defined (S_IXOTH)
+ S_IXOTH ||
+#endif
+#if defined (S_IXGRP)
+ S_IXGRP ||
+#endif
+ S_IXUSR;
+
+ LTWRAPPER_DEBUGPRINTF("(make_executable) : %s\n", path ? (*path ? path :
"EMPTY!") : "NULL!");
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod ( path, st.st_mode | S_XFLAGS );
+ }
+ return rval;
+}
+
/* Searches for the full path of the wrapper. Returns
- newly allocated full path name if found, NULL otherwise */
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
char *
find_executable (const char* wrapper)
{
@@ -2625,7 +2771,7 @@
int tmp_len;
char* concat_name;
- DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!")
: "NULL!");
+ LTWRAPPER_DEBUGPRINTF("(find_executable) : %s\n", wrapper ? (*wrapper ?
wrapper : "EMPTY!") : "NULL!");
if ((wrapper == NULL) || (*wrapper == '\0'))
return NULL;
@@ -2715,6 +2861,62 @@
}
char *
+chase_symlinks(const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup ( pathspec );
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ int rv = 0;
+ char* tmp_pathspec = xstrdup (pathspec);
+ char* p;
+ int has_symlinks = 0;
+ while (strlen(tmp_pathspec) && !has_symlinks)
+ {
+ LTWRAPPER_DEBUGPRINTF("checking path component for symlinks: %s\n",
tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK(s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen(tmp_pathspec) - 1;
+ while ( (p > tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
+ p--;
+ if ( (p == tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char* errstr = strerror(errno);
+ lt_fatal("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
+ }
+ XFREE(tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup ( pathspec );
+ }
+
+ tmp_pathspec = realpath ( pathspec, buf );
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal("Could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup ( tmp_pathspec );
+#endif
+}
+
+char *
strendzap(char *str, const char *pat)
{
size_t len, patlen;
Index: libltdl/config/ltmain.m4sh
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/config/ltmain.m4sh,v
retrieving revision 1.74
diff -u -r1.74 ltmain.m4sh
--- libltdl/config/ltmain.m4sh 2007-04-27 03:52:20.109375000 -0400
+++ libltdl/config/ltmain.m4sh 2007-04-27 03:54:45.593750000 -0400
@@ -2506,26 +2506,27 @@
const char *program_name = NULL;
-void * xmalloc (size_t num);
-char * xstrdup (const char *string);
-const char * base_name (const char *name);
-char * find_executable(const char *wrapper);
-char * chase_symlinks(const char *pathspec);
-int make_executable(const char *path);
-int check_executable(const char *path);
-char * strendzap(char *str, const char *pat);
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
void lt_fatal (const char *message, ...);
-static const char* script_text =
+static const char *script_text =
EOF
func_emit_libtool_wrapper_script |
$SED -e 's/\([\\"]\)/\\\1/g' \
-e 's/\(WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\)=.*/\1=yes/' \
- -e 's/^/"/' -e 's/$/\\n"/'
+ -e 's/^/ "/' -e 's/$/\\n"/'
echo ";"
cat <<EOF
+
int
main (int argc, char *argv[])
{
@@ -2535,24 +2536,24 @@
char *shwrapper_name;
FILE *shwrapper;
- const char* dumpscript_opt = "--lt-dump-script";
+ const char *dumpscript_opt = "--lt-dump-script";
int i;
program_name = (char *) xstrdup (base_name (argv[0]));
- LTWRAPPER_DEBUGPRINTF("(main) argv[0] : %s\n",argv[0]);
- LTWRAPPER_DEBUGPRINTF("(main) program_name : %s\n",program_name);
+ LTWRAPPER_DEBUGPRINTF ("(main) argv[0] : %s\n", argv[0]);
+ LTWRAPPER_DEBUGPRINTF ("(main) program_name : %s\n", program_name);
/* very simple arg parsing; don't want to rely on getopt */
- for (i=1; i<argc; i++)
- {
- if (strcmp(argv[i], dumpscript_opt) == 0)
+ for (i = 1; i < argc; i++)
{
- printf("%s", script_text);
- return 0;
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+ printf ("%s", script_text);
+ return 0;
+ }
}
- }
- newargz = XMALLOC(char *, argc+2);
+ newargz = XMALLOC (char *, argc + 2);
EOF
if test -n "$TARGETSHELL" ; then
@@ -2560,56 +2561,59 @@
lt_newargv0=$TARGETSHELL
else
case "$host" in
- *mingw* )
+ *mingw* )
# awkward: cmd appends spaces to result
lt_sed_strip_trailing_spaces="s/[ ]*\$//"
lt_newargv0=`( cmd //c echo $SHELL | $SED -e
"$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo $SHELL`
- case $lt_newargv0 in
- *.exe | *.EXE) ;;
- *) lt_newargv0=$lt_newargv0.exe ;;
- esac
- ;;
- * ) lt_newargv0=$SHELL ;;
+ case $lt_newargv0 in
+ *.exe | *.EXE) ;;
+ *) lt_newargv0=$lt_newargv0.exe ;;
+ esac
+ ;;
+ * ) lt_newargv0=$SHELL ;;
esac
fi
cat <<EOF
- newargz[0] = (char *) xstrdup("$lt_newargv0");
+ newargz[0] = (char *) xstrdup ("$lt_newargv0");
EOF
cat <<"EOF"
tmp_pathspec = find_executable (argv[0]);
if (tmp_pathspec == NULL)
- lt_fatal("Couldn't find %s", argv[0]);
- LTWRAPPER_DEBUGPRINTF("(main) found exe (before symlink chase) at :
%s\n",tmp_pathspec);
+ lt_fatal ("Couldn't find %s", argv[0]);
+ LTWRAPPER_DEBUGPRINTF ("(main) found exe (before symlink chase) at : %s\n",
+ tmp_pathspec);
actual_cwrapper_path = chase_symlinks (tmp_pathspec);
- LTWRAPPER_DEBUGPRINTF("(main) found exe (after symlink chase) at :
%s\n",actual_cwrapper_path);
- XFREE(tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF ("(main) found exe (after symlink chase) at : %s\n",
+ actual_cwrapper_path);
+ XFREE (tmp_pathspec);
shwrapper_name = (char *) xstrdup (base_name (actual_cwrapper_path));
- strendzap( actual_cwrapper_path, shwrapper_name );
+ strendzap (actual_cwrapper_path, shwrapper_name);
/* shwrapper_name transforms */
- strendzap(shwrapper_name,".exe");
- tmp_pathspec = XMALLOC( char, strlen ( shwrapper_name ) +
- strlen ( "_ltshwrapper" ) + 1 );
- strcpy ( tmp_pathspec, shwrapper_name );
- strcat ( tmp_pathspec, "_ltshwrapper" );
- XFREE( shwrapper_name );
+ strendzap (shwrapper_name, ".exe");
+ tmp_pathspec = XMALLOC (char, (strlen (shwrapper_name) +
+ strlen ("_ltshwrapper") + 1));
+ strcpy (tmp_pathspec, shwrapper_name);
+ strcat (tmp_pathspec, "_ltshwrapper");
+ XFREE (shwrapper_name);
shwrapper_name = tmp_pathspec;
tmp_pathspec = 0;
- LTWRAPPER_DEBUGPRINTF("(main) libtool shell wrapper name:
%s\n",shwrapper_name);
+ LTWRAPPER_DEBUGPRINTF ("(main) libtool shell wrapper name: %s\n",
+ shwrapper_name);
EOF
cat <<EOF
- newargz[1] = XMALLOC( char, strlen ( actual_cwrapper_path ) +
- strlen ( "$objdir" ) + 1 +
- strlen ( shwrapper_name ) + 1 );
- strcpy ( newargz[1], actual_cwrapper_path );
- strcat ( newargz[1], "$objdir" );
- strcat ( newargz[1], "/" );
- strcat ( newargz[1], shwrapper_name );
+ newargz[1] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (shwrapper_name) + 1));
+ strcpy (newargz[1], actual_cwrapper_path);
+ strcat (newargz[1], "$objdir");
+ strcat (newargz[1], "/");
+ strcat (newargz[1], shwrapper_name);
EOF
@@ -2617,39 +2621,40 @@
mingw*)
cat <<"EOF"
{
- char* p;
- while( (p = strchr(newargz[1], '\\')) != NULL) {
- *p = '/';
- }
+ char* p;
+ while ((p = strchr (newargz[1], '\\')) != NULL)
+ {
+ *p = '/';
+ }
}
EOF
;;
esac
cat <<"EOF"
- XFREE( shwrapper_name );
- XFREE( actual_cwrapper_path );
+ XFREE (shwrapper_name);
+ XFREE (actual_cwrapper_path);
/* note: do NOT use "wt" here! -- defer to underlying
* mount type on cygwin
*/
- if ( (shwrapper = fopen (newargz[1], "w")) == 0 )
- {
- lt_fatal("Could not open %s for writing", newargz[1]);
- }
+ if ((shwrapper = fopen (newargz[1], "w")) == 0)
+ {
+ lt_fatal ("Could not open %s for writing", newargz[1]);
+ }
fprintf (shwrapper, "%s", script_text);
fclose (shwrapper);
- make_executable( newargz[1] );
+ make_executable (newargz[1]);
for (i = 1; i < argc; i++)
- newargz[i+1] = xstrdup(argv[i]);
- newargz[argc+1] = NULL;
+ newargz[i + 1] = xstrdup (argv[i]);
+ newargz[argc + 1] = NULL;
- for (i=0; i<argc+1; i++)
- {
- LTWRAPPER_DEBUGPRINTF("(main) newargz[%d] : %s\n",i,newargz[i]);
- }
+ for (i = 0; i < argc + 1; i++)
+ {
+ LTWRAPPER_DEBUGPRINTF ("(main) newargz[%d] : %s\n", i, newargz[i]);
+ }
EOF
@@ -2673,7 +2678,7 @@
void *
xmalloc (size_t num)
{
- void * p = (void *) malloc (num);
+ void *p = (void *) malloc (num);
if (!p)
lt_fatal ("Memory exhausted");
@@ -2683,8 +2688,8 @@
char *
xstrdup (const char *string)
{
- return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) :
NULL
-;
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
}
const char *
@@ -2694,7 +2699,7 @@
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Skip over the disk name in MSDOS pathnames. */
- if (isalpha ((unsigned char)name[0]) && name[1] == ':')
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
name += 2;
#endif
@@ -2705,32 +2710,31 @@
}
int
-check_executable(const char * path)
+check_executable (const char *path)
{
struct stat st;
- LTWRAPPER_DEBUGPRINTF("(check_executable) : %s\n", path ? (*path ? path :
"EMPTY!") : "NULL!");
+ LTWRAPPER_DEBUGPRINTF ("(check_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!");
if ((!path) || (!*path))
return 0;
- if ((stat (path, &st) >= 0) &&
- (
- /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+ if ((stat (path, &st) >= 0) && (
+ /* MinGW & native WIN32 do not support
S_IXOTH or S_IXGRP */
#if defined (S_IXOTH)
- ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+ ((st.st_mode & S_IXOTH) == S_IXOTH) ||
#endif
#if defined (S_IXGRP)
- ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+ ((st.st_mode & S_IXGRP) == S_IXGRP) ||
#endif
- ((st.st_mode & S_IXUSR) == S_IXUSR))
- )
+ ((st.st_mode & S_IXUSR) == S_IXUSR)))
return 1;
else
return 0;
}
int
-make_executable(const char * path)
+make_executable (const char *path)
{
int rval = 0;
struct stat st;
@@ -2738,22 +2742,23 @@
/* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
int S_XFLAGS =
#if defined (S_IXOTH)
- S_IXOTH ||
+ S_IXOTH ||
#endif
#if defined (S_IXGRP)
- S_IXGRP ||
+ S_IXGRP ||
#endif
- S_IXUSR;
+ S_IXUSR;
- LTWRAPPER_DEBUGPRINTF("(make_executable) : %s\n", path ? (*path ? path :
"EMPTY!") : "NULL!");
- if ((!path) || (!*path))
- return 0;
+ LTWRAPPER_DEBUGPRINTF ("(make_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!");
+ if ((!path) || (!*path))
+ return 0;
- if (stat (path, &st) >= 0)
+ if (stat (path, &st) >= 0)
{
- rval = chmod ( path, st.st_mode | S_XFLAGS );
+ rval = chmod (path, st.st_mode | S_XFLAGS);
}
- return rval;
+ return rval;
}
/* Searches for the full path of the wrapper. Returns
@@ -2761,184 +2766,188 @@
Does not chase symlinks, even on platforms that support them.
*/
char *
-find_executable (const char* wrapper)
+find_executable (const char *wrapper)
{
int has_slash = 0;
- const char* p;
- const char* p_next;
+ const char *p;
+ const char *p_next;
/* static buffer for getcwd */
char tmp[LT_PATHMAX + 1];
int tmp_len;
- char* concat_name;
+ char *concat_name;
- LTWRAPPER_DEBUGPRINTF("(find_executable) : %s\n", wrapper ? (*wrapper ?
wrapper : "EMPTY!") : "NULL!");
+ LTWRAPPER_DEBUGPRINTF ("(find_executable) : %s\n",
+ wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
if ((wrapper == NULL) || (*wrapper == '\0'))
return NULL;
/* Absolute path? */
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- if (isalpha ((unsigned char)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]))
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
{
concat_name = xstrdup (wrapper);
- if (check_executable(concat_name))
+ if (check_executable (concat_name))
return concat_name;
- XFREE(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)
- }
+ }
#endif
for (p = wrapper; *p; p++)
if (*p == '/')
- {
- has_slash = 1;
- break;
- }
+ {
+ 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
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
{
- 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);
+ 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);
+ }
}
- if (check_executable(concat_name))
- return concat_name;
- XFREE(concat_name);
- }
+ /* not found in PATH; assume curdir */
}
- /* not found in PATH; assume curdir */
- }
/* Relative path | not found in path: prepend cwd */
if (getcwd (tmp, LT_PATHMAX) == NULL)
lt_fatal ("getcwd failed");
- tmp_len = strlen(tmp);
- concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+ 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))
+ if (check_executable (concat_name))
return concat_name;
- XFREE(concat_name);
+ XFREE (concat_name);
return NULL;
}
char *
-chase_symlinks(const char *pathspec)
+chase_symlinks (const char *pathspec)
{
#ifndef S_ISLNK
- return xstrdup ( pathspec );
+ return xstrdup (pathspec);
#else
- char buf[LT_PATHMAX];
- struct stat s;
- int rv = 0;
- char* tmp_pathspec = xstrdup (pathspec);
- char* p;
- int has_symlinks = 0;
- while (strlen(tmp_pathspec) && !has_symlinks)
+ char buf[LT_PATHMAX];
+ struct stat s;
+ int rv = 0;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
{
- LTWRAPPER_DEBUGPRINTF("checking path component for symlinks: %s\n",
tmp_pathspec);
- if (lstat (tmp_pathspec, &s) == 0)
- {
- if (S_ISLNK(s.st_mode) != 0)
- {
- has_symlinks = 1;
- break;
- }
-
- /* search backwards for last DIR_SEPARATOR */
- p = tmp_pathspec + strlen(tmp_pathspec) - 1;
- while ( (p > tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
- p--;
- if ( (p == tmp_pathspec) && (! IS_DIR_SEPARATOR(*p)) )
- {
- /* no more DIR_SEPARATORS left */
- break;
- }
- *p = '\0';
- }
- else
- {
- char* errstr = strerror(errno);
- lt_fatal("Error accessing file %s (%s)", tmp_pathspec, errstr);
- }
+ LTWRAPPER_DEBUGPRINTF ("checking path component for symlinks: %s\n",
+ tmp_pathspec);
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char *errstr = strerror (errno);
+ lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
}
- XFREE(tmp_pathspec);
+ XFREE (tmp_pathspec);
- if (!has_symlinks)
+ if (!has_symlinks)
{
- return xstrdup ( pathspec );
+ return xstrdup (pathspec);
}
- tmp_pathspec = realpath ( pathspec, buf );
- if (tmp_pathspec == 0)
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
{
- lt_fatal("Could not follow symlinks for %s", pathspec);
+ lt_fatal ("Could not follow symlinks for %s", pathspec);
}
- return xstrdup ( tmp_pathspec );
+ return xstrdup (tmp_pathspec);
#endif
}
char *
-strendzap(char *str, const char *pat)
+strendzap (char *str, const char *pat)
{
size_t len, patlen;
- assert(str != NULL);
- assert(pat != NULL);
+ assert (str != NULL);
+ assert (pat != NULL);
- len = strlen(str);
- patlen = strlen(pat);
+ len = strlen (str);
+ patlen = strlen (pat);
if (patlen <= len)
- {
- str += len - patlen;
- if (strcmp(str, pat) == 0)
- *str = '\0';
- }
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
return str;
}
static void
-lt_error_core (int exit_status, const char * mode,
- const char * message, va_list ap)
+lt_error_core (int exit_status, const char *mode,
+ const char *message, va_list ap)
{
fprintf (stderr, "%s: %s: ", program_name, mode);
vfprintf (stderr, message, ap);
- [cygwin] cwrapper emits wrapper script, Charles Wilson, 2007/04/20
- Re: [cygwin] cwrapper emits wrapper script, Ralf Wildenhues, 2007/04/23
- Re: [cygwin] cwrapper emits wrapper script, Charles Wilson, 2007/04/23
- Re: [cygwin] cwrapper emits wrapper script, Charles Wilson, 2007/04/24
- Re: [cygwin] cwrapper emits wrapper script, Ralf Wildenhues, 2007/04/25
- Re: [cygwin] cwrapper emits wrapper script, libtool, 2007/04/25
- Re: [cygwin] cwrapper emits wrapper script, Ralf Wildenhues, 2007/04/26
Re: [cygwin] cwrapper emits wrapper script,
Charles Wilson <=