Subject: Re: bug#13472: [PATCH] libtool: speed up by pre-cutting sed's input by dd

From: Peter Rosin <[email-masked]>
Date: Tue, 06 May 2014 09:44:34 +0200

close 13472
close 16662
stop

On 2014-02-14 17:43, Nick Bowler wrote:
> On 2/13/14, Peter Rosin <[email-masked]> wrote:
>> On 2014-02-13 18:57, Peter Rosin wrote:
>>> Ok, everybody seems happy. But not me, not 100% anyway. This introduces
>>> an extra fork, and AFAICT, the "extra protection" is only needed when
>>> func_lalib_p is called from func_ltwrapper_script_p. Should we perhaps
>>> have a separate implementation in func_ltwrapper_script_p instead of
>>> simply calling func_lalib_p?
>>>
>>> Maybe we could also lose the "sed -e 4q" part when dd limits the size?
>>
>> *snip* outline, real patch attached instead...
>>
>> Now, which patch should I push?
> 
> The new looks a bit nicer to me although I have not tested it.
> 
> One comment I have that applies to both patches... you should probably
> be using AC_CHECK_PROGS instead of AC_PATH_PROG because the latter
> requires an absolute filename.
> 
> Specifically, AC_PATH_PROG will ignore any user-set value for DD if
> it's not absolute.

Ok, I'm reviving this old thing once again. There were two minor complaints
with the last patch, this patch addresses both. I.e.

1. DD=dd now works to override the dd check, you don't need to specify
a full path.
2. The code duplication between func_lalib_p and func_ltwrapper_script_p
has been factored out.

However, to address the first point, I made use of the
AC_PATH_PROGS_FEATURE_CHECK macro, which was added in Autoconf 2.62, which
Libtool didn't require before. But 2.62 is 6 years old by now. If anyone
has problems with that, we will have to fix it later as I'm now pushing
this thing. It's been brewing for far too long already...

Final version attached.

Cheers,
Peter

>From da30ce4dc9554c80f1931600af2b8bbab486476e Mon Sep 17 00:00:00 2001
From: Peter Rosin <[email-masked]>
Date: Tue, 6 May 2014 00:03:19 +0200
Subject: [PATCH] libtool: speed up ltwrapper_script detection in execute mode

Execute mode is slow and might even DOS the computer in extreme
cases when a parameter is a big binary file without newlines.
Work around this with different truncation if a suitable dd
utility is found.

Fixes bug#13472 and bug#16662.

Reported by Pavel Raiskup and Nick Bowler.

* m4/libtool.m4 (_LT_PATH_DD): New macro, for finding a dd utility
that works for the below purpose.
(_LT_CMD_TRUNCATE): New macro, for finding out how to truncate binary
pipes (fallback to the old sed truncation if no suitable dd is found
in _LT_PATH_DD).
(_LT_SETUP): Require _LT_CMD_TRUNCATE.
(LT_INIT): Require Autoconf 2.62, as needed by _LT_PATH_DD.
* build_aux/ltmain.in (func_lalib_p): Factor out the actual "generated
by libtool" test into...
(func_generated_by_libtool_p): ...this new function...
(func_ltwrapper_script_p): ...so that it can be reused here, when
truncating the pipe according to _LT_CMD_TRUNCATE.
* THANKS: Update.

Signed-off-by: Peter Rosin <[email-masked]>
---
 THANKS              |    2 ++
 build-aux/ltmain.in |   14 +++++++++++---
 m4/libtool.m4       |   40 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/THANKS b/THANKS
index e895aee..85c5150 100644
--- a/THANKS
+++ b/THANKS
@@ -150,6 +150,7 @@
   Mike Gorchak			[email-masked]
   Mike Frysinger		[email-masked]
   Mike Miller			[email-masked]
+  Nick Bowler			[email-masked]
   Nix				[email-masked]
   Olaf Lenz			[email-masked]
   Olly Betts			[email-masked]
@@ -161,6 +162,7 @@
   Paul Eggert			[email-masked]
   Paul Laight			[email-masked]
   Paul Seidler			[email-masked]
+  Pavel Raiskup			[email-masked]
   Paweł Daniluk			[email-masked]
   Peter Eisentraut		[email-masked]
   Peter Fritzsche		[email-masked]
diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
index 3a0fb0c..6af4087 100644
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
@@ -570,6 +570,14 @@ $1
 _LTECHO_EOF'
 }
 
+# func_generated_by_libtool
+# True iff stdin has been generated by Libtool. This function is only
+# a basic sanity check; it will hardly flush out determined imposters.
+func_generated_by_libtool_p ()
+{
+  $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
 # func_lalib_p file
 # True iff FILE is a libtool '.la' library or '.lo' object file.
 # This function is only a basic sanity check; it will hardly flush out
@@ -577,8 +585,7 @@ _LTECHO_EOF'
 func_lalib_p ()
 {
     test -f "$1" &&
-      $SED -e 4q "$1" 2>/dev/null \
-        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+      $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p
 }
 
 # func_lalib_unsafe_p file
@@ -610,7 +617,8 @@ func_lalib_unsafe_p ()
 # determined imposters.
 func_ltwrapper_script_p ()
 {
-    func_lalib_p "$1"
+    test -f "$1" &&
+      $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p
 }
 
 # func_ltwrapper_executable_p file
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index ce58f31..0454030 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -59,7 +59,7 @@ esac
 # LT_INIT([OPTIONS])
 # ------------------
 AC_DEFUN([LT_INIT],
-[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK
 AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
@@ -169,6 +169,7 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
 m4_require([_LT_WITH_SYSROOT])dnl
+m4_require([_LT_CMD_TRUNCATE])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
 # See if we are running on zsh, and set the options that allow our
@@ -3216,6 +3217,43 @@ _LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD

+# _LT_PATH_DD
+# -----------
+# find a working dd
+m4_defun([_LT_PATH_DD],
+[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+: ${lt_DD:=$DD}
+AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd],
+[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=:
+fi])
+rm -f conftest.i conftest2.i conftest.out])
+])# _LT_PATH_DD
+
+
+# _LT_CMD_TRUNCATE
+# ----------------
+# find command to truncate a binary pipe
+m4_defun([_LT_CMD_TRUNCATE],
+[m4_require([_LT_PATH_DD])
+AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin],
+[printf 0123456789abcdef0123456789abcdef >conftest.i
+cat conftest.i conftest.i >conftest2.i
+lt_cv_truncate_bin=
+if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then
+  cmp -s conftest.i conftest.out \
+  && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1"
+fi
+rm -f conftest.i conftest2.i conftest.out
+test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"])
+_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1],
+  [Command to truncate a binary pipe])
+])# _LT_CMD_TRUNCATE
+
+
 # _LT_CHECK_MAGIC_METHOD
 # ----------------------
 # how to check for library dependencies
-- 
1.7.9