[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[commits] r8714 - in /fsf/trunk/libc: ./ elf/ nptl/ resolv/ sysdeps/x86_64/ sysdeps/x86_64/multiarch/
- To: commits@xxxxxxxxxx
- Subject: [commits] r8714 - in /fsf/trunk/libc: ./ elf/ nptl/ resolv/ sysdeps/x86_64/ sysdeps/x86_64/multiarch/
- From: eglibc@xxxxxxxxxx
- Date: Tue, 28 Jul 2009 07:10:56 -0000
Author: eglibc
Date: Tue Jul 28 00:10:55 2009
New Revision: 8714
Log:
Import glibc-mainline for 2009-07-28
Added:
fsf/trunk/libc/elf/dl-scope.c
Removed:
fsf/trunk/libc/sysdeps/x86_64/multiarch/rtld-rawmemchr.c
fsf/trunk/libc/sysdeps/x86_64/rtld-memchr.c
fsf/trunk/libc/sysdeps/x86_64/rtld-rawmemchr.c
fsf/trunk/libc/sysdeps/x86_64/rtld-strcmp.S
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/elf/Makefile
fsf/trunk/libc/elf/dl-lookup.c
fsf/trunk/libc/elf/dl-open.c
fsf/trunk/libc/nptl/ChangeLog
fsf/trunk/libc/nptl/pthread_mutex_lock.c
fsf/trunk/libc/nptl/pthread_mutex_timedlock.c
fsf/trunk/libc/nptl/pthread_mutex_unlock.c
fsf/trunk/libc/resolv/res_debug.c
fsf/trunk/libc/resolv/res_mkquery.c
fsf/trunk/libc/resolv/res_query.c
fsf/trunk/libc/resolv/resolv.h
fsf/trunk/libc/sysdeps/x86_64/Makefile
fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Tue Jul 28 00:10:55 2009
@@ -1,3 +1,33 @@
+2009-07-27 Ulrich Drepper <drepper@xxxxxxxxxx>
+
+ * sysdeps/x86_64/tst-xmmymm.sh: Refine testing. The script now
+ determines which files are used in runtime lookups and only checks
+ those for SSE use.
+ * sysdeps/x86_64/rtld-memchr.c: Removed. Not needed with refined
+ testing.
+ * sysdeps/x86_64/rtld-rawmemchr.c: Removed.
+ * sysdeps/x86_64/multiarch/rtld-rawmemchr.c: Removed
+ * sysdeps/x86_64/Makefile: Emit warning that tst-xmmymm.sh might
+ take a while.
+
+ * elf/dl-open.c: Move _dl_scope_free to...
+ * elf/dl-scope.c: ...here. New file.
+ * elf/Makefile (dl-routines): Add scope.
+
+ * resolv/resolv.h (RES_USE_DNSSEC): Define.
+ * resolv/res_debug.c (p_option): Handle RES_USE_EDNS0 and
+ RES_USE_DNSSEC.
+ * resolv/res_mkquery.c (__res_nopt): Set flags for RES_USE_DNSSEC.
+ * resolv/res_query.c (__libc_res_nquery): Handle RES_USE_DNSSEC in
+ all the places we handled RES_USE_EDNS0 only before.
+ Patch by Adam Tkac <atkac@xxxxxxxxxx>.
+
+2009-07-27 Jakub Jelinek <jakub@xxxxxxxxxx>
+
+ * elf/dl-lookup.c (do_lookup_x): Fix check for table more than
+ 3/4 full. Pass size + 1 rather than size to _dl_higher_prime_number.
+ Update size when reallocating.
+
2009-07-26 Ulrich Drepper <drepper@xxxxxxxxxx>
* sysdeps/x86_64/tst-xmmymm.sh: New file. Check whether any of the
@@ -7,7 +37,6 @@
* sysdeps/x86_64/rtld-memcmp.c: New file.
* sysdeps/x86_64/rtld-rawmemchr.c: New file.
* sysdeps/x86_64/rtld-strchr.S: New file.
- * sysdeps/x86_64/rtld-strcmp.S: New file.
* sysdeps/x86_64/rtld-strlen.S: New file.
* sysdeps/x86_64/multiarch/rtld-rawmemchr.c: New file.
* sysdeps/x86_64/multiarch/rtld-strlen.S: New file.
Modified: fsf/trunk/libc/elf/Makefile
==============================================================================
--- fsf/trunk/libc/elf/Makefile (original)
+++ fsf/trunk/libc/elf/Makefile Tue Jul 28 00:10:55 2009
@@ -29,7 +29,7 @@
# profiled libraries.
dl-routines = $(addprefix dl-,load cache lookup object reloc deps \
runtime error init fini debug misc \
- version profile conflict tls origin \
+ version profile conflict tls origin scope \
execstack caller open close trampoline)
all-dl-routines = $(dl-routines) $(sysdep-dl-routines)
# But they are absent from the shared libc, because that code is in ld.so.
Modified: fsf/trunk/libc/elf/dl-lookup.c
==============================================================================
--- fsf/trunk/libc/elf/dl-lookup.c (original)
+++ fsf/trunk/libc/elf/dl-lookup.c Tue Jul 28 00:10:55 2009
@@ -377,10 +377,10 @@
idx -= size;
}
- if (size * 3 <= tab->n_elements)
+ if (size * 3 <= tab->n_elements * 4)
{
/* Expand the table. */
- size_t newsize = _dl_higher_prime_number (size);
+ size_t newsize = _dl_higher_prime_number (size + 1);
struct unique_sym *newentries
= calloc (sizeof (struct unique_sym), newsize);
if (newentries == NULL)
@@ -398,6 +398,7 @@
tab->free (entries);
tab->size = newsize;
+ size = newsize;
entries = tab->entries = newentries;
tab->free = free;
}
Modified: fsf/trunk/libc/elf/dl-open.c
==============================================================================
--- fsf/trunk/libc/elf/dl-open.c (original)
+++ fsf/trunk/libc/elf/dl-open.c Tue Jul 28 00:10:55 2009
@@ -165,41 +165,6 @@
return 0;
}
-int
-_dl_scope_free (void *old)
-{
- struct dl_scope_free_list *fsl;
-#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
-
- if (RTLD_SINGLE_THREAD_P)
- free (old);
- else if ((fsl = GL(dl_scope_free_list)) == NULL)
- {
- GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
- if (fsl == NULL)
- {
- THREAD_GSCOPE_WAIT ();
- free (old);
- return 1;
- }
- else
- {
- fsl->list[0] = old;
- fsl->count = 1;
- }
- }
- else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
- fsl->list[fsl->count++] = old;
- else
- {
- THREAD_GSCOPE_WAIT ();
- while (fsl->count > 0)
- free (fsl->list[--fsl->count]);
- return 1;
- }
- return 0;
-}
-
static void
dl_open_worker (void *a)
{
Added: fsf/trunk/libc/elf/dl-scope.c
==============================================================================
--- fsf/trunk/libc/elf/dl-scope.c (added)
+++ fsf/trunk/libc/elf/dl-scope.c Tue Jul 28 00:10:55 2009
@@ -1,0 +1,58 @@
+/* Memory handling for the scope data structures.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <stdlib.h>
+#include <ldsodefs.h>
+#include <sysdep-cancel.h>
+
+
+int
+_dl_scope_free (void *old)
+{
+ struct dl_scope_free_list *fsl;
+#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
+
+ if (RTLD_SINGLE_THREAD_P)
+ free (old);
+ else if ((fsl = GL(dl_scope_free_list)) == NULL)
+ {
+ GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
+ if (fsl == NULL)
+ {
+ THREAD_GSCOPE_WAIT ();
+ free (old);
+ return 1;
+ }
+ else
+ {
+ fsl->list[0] = old;
+ fsl->count = 1;
+ }
+ }
+ else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
+ fsl->list[fsl->count++] = old;
+ else
+ {
+ THREAD_GSCOPE_WAIT ();
+ while (fsl->count > 0)
+ free (fsl->list[--fsl->count]);
+ return 1;
+ }
+ return 0;
+}
Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Tue Jul 28 00:10:55 2009
@@ -1,9 +1,8 @@
-2009-07-26 Ulrich Drepper <drepper@xxxxxxxxxx>
+2009-07-27 Ulrich Drepper <drepper@xxxxxxxxxx>
[BZ #10418]
- * pthread_mutex_lock.c (pthread_mutex_lock): Use _rel instead of of
- _acq variants of cmpxchg.
- * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Likewise.
+ * pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Use _rel
+ instead of of _acq variants of cmpxchg.
2009-07-23 Ulrich Drepper <drepper@xxxxxxxxxx>
Modified: fsf/trunk/libc/nptl/pthread_mutex_lock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_lock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_lock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -160,7 +160,7 @@
#endif
newval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
newval, oldval);
if (newval != oldval)
@@ -285,7 +285,7 @@
#ifdef NO_INCR
newval |= FUTEX_WAITERS;
#endif
- oldval = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
newval, 0);
if (oldval != 0)
@@ -420,7 +420,7 @@
oldprio = ceiling;
oldval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
#ifdef NO_INCR
ceilval | 2,
#else
@@ -434,7 +434,7 @@
do
{
oldval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2,
ceilval | 1);
@@ -445,7 +445,7 @@
lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
PTHREAD_MUTEX_PSHARED (mutex));
}
- while (atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
!= ceilval);
}
Modified: fsf/trunk/libc/nptl/pthread_mutex_timedlock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_timedlock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_timedlock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2007, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -126,7 +126,7 @@
int newval = id | (oldval & FUTEX_WAITERS);
newval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
newval, oldval);
if (newval != oldval)
{
@@ -246,7 +246,7 @@
}
}
- oldval = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
id, 0);
if (oldval != 0)
@@ -404,7 +404,7 @@
oldprio = ceiling;
oldval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 1, ceilval);
if (oldval == ceilval)
@@ -413,7 +413,7 @@
do
{
oldval
- = atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2,
ceilval | 1);
@@ -456,7 +456,7 @@
PTHREAD_MUTEX_PSHARED (mutex));
}
}
- while (atomic_compare_and_exchange_val_rel (&mutex->__data.__lock,
+ while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
ceilval | 2, ceilval)
!= ceilval);
}
Modified: fsf/trunk/libc/nptl/pthread_mutex_unlock.c
==============================================================================
--- fsf/trunk/libc/nptl/pthread_mutex_unlock.c (original)
+++ fsf/trunk/libc/nptl/pthread_mutex_unlock.c Tue Jul 28 00:10:55 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005-2007, 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005-2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
@@ -213,7 +213,7 @@
/* Unlock. */
if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
- || atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock, 0,
+ || atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock, 0,
THREAD_GETMEM (THREAD_SELF,
tid)))
{
@@ -263,7 +263,7 @@
oldval = mutex->__data.__lock;
newval = oldval & PTHREAD_MUTEX_PRIO_CEILING_MASK;
}
- while (atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock,
+ while (atomic_compare_and_exchange_bool_rel (&mutex->__data.__lock,
newval, oldval));
if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
Modified: fsf/trunk/libc/resolv/res_debug.c
==============================================================================
--- fsf/trunk/libc/resolv/res_debug.c (original)
+++ fsf/trunk/libc/resolv/res_debug.c Tue Jul 28 00:10:55 2009
@@ -586,6 +586,8 @@
case RES_ROTATE: return "rotate";
case RES_NOCHECKNAME: return "no-check-names";
case RES_USEBSTRING: return "ip6-bytstring";
+ case RES_USE_EDNS0: return "edns0";
+ case RES_USE_DNSSEC: return "dnssec";
/* XXX nonreentrant */
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
return (nbuf);
Modified: fsf/trunk/libc/resolv/res_mkquery.c
==============================================================================
--- fsf/trunk/libc/resolv/res_mkquery.c (original)
+++ fsf/trunk/libc/resolv/res_mkquery.c Tue Jul 28 00:10:55 2009
@@ -247,7 +247,15 @@
NS_PUT16(MIN(anslen, 0xffff), cp); /* CLASS = UDP payload size */
*cp++ = NOERROR; /* extended RCODE */
*cp++ = 0; /* EDNS version */
- /* XXX Once we support DNSSEC we change the flag value here. */
+
+ if (statp->options & RES_USE_DNSSEC) {
+#ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+ printf(";; res_opt()... ENDS0 DNSSEC\n");
+#endif
+ flags |= NS_OPT_DNSSEC_OK;
+ }
+
NS_PUT16(flags, cp);
NS_PUT16(0, cp); /* RDLEN */
hp->arcount = htons(ntohs(hp->arcount) + 1);
Modified: fsf/trunk/libc/resolv/res_query.c
==============================================================================
--- fsf/trunk/libc/resolv/res_query.c (original)
+++ fsf/trunk/libc/resolv/res_query.c Tue Jul 28 00:10:55 2009
@@ -147,7 +147,7 @@
if (n > 0)
{
if ((oflags & RES_F_EDNS0ERR) == 0
- && (statp->options & RES_USE_EDNS0) != 0)
+ && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
{
n = __res_nopt(statp, n, query1, bufsize, anslen / 2);
if (n < 0)
@@ -169,7 +169,7 @@
NULL, query2, bufsize - nused);
if (n > 0
&& (oflags & RES_F_EDNS0ERR) == 0
- && (statp->options & RES_USE_EDNS0) != 0)
+ && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
n = __res_nopt(statp, n, query2, bufsize - nused - n,
anslen / 2);
nquery2 = n;
@@ -184,7 +184,7 @@
if (n > 0
&& (oflags & RES_F_EDNS0ERR) == 0
- && (statp->options & RES_USE_EDNS0) != 0)
+ && (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
n = __res_nopt(statp, n, query1, bufsize, anslen);
nquery1 = n;
@@ -203,7 +203,7 @@
}
if (__builtin_expect (n <= 0, 0)) {
/* If the query choked with EDNS0, retry without EDNS0. */
- if ((statp->options & RES_USE_EDNS0) != 0
+ if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0
&& ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
statp->_flags |= RES_F_EDNS0ERR;
#ifdef DEBUG
Modified: fsf/trunk/libc/resolv/resolv.h
==============================================================================
--- fsf/trunk/libc/resolv/resolv.h (original)
+++ fsf/trunk/libc/resolv/resolv.h Tue Jul 28 00:10:55 2009
@@ -218,6 +218,7 @@
#define RES_SNGLKUP 0x00200000 /* one outstanding request at a time */
#define RES_SNGLKUPREOP 0x00400000 /* -"-, but open new socket for each
request */
+#define RES_USE_DNSSEC 0x00800000 /* use DNSSEC using OK bit in OPT */
#define RES_DEFAULT (RES_RECURSE|RES_DEFNAMES|RES_DNSRCH|RES_NOIP6DOTINT)
Modified: fsf/trunk/libc/sysdeps/x86_64/Makefile
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/Makefile (original)
+++ fsf/trunk/libc/sysdeps/x86_64/Makefile Tue Jul 28 00:10:55 2009
@@ -22,6 +22,7 @@
tests: $(objpfx)tst-xmmymm.out
$(objpfx)tst-xmmymm.out: ../sysdeps/x86_64/tst-xmmymm.sh $(objpfx)ld.so
+ @echo "Checking ld.so for SSE register use. This will take a few seconds..."
$(SHELL) -e $< $(objpfx) > $@
endif
Modified: fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh (original)
+++ fsf/trunk/libc/sysdeps/x86_64/tst-xmmymm.sh Tue Jul 28 00:10:55 2009
@@ -1,17 +1,79 @@
-#! /bin/sh
+#! /bin/bash
objpfx="$1"
tmp=$(mktemp ${objpfx}tst-xmmymm.XXXXXX)
trap 'rm -f "$tmp"' 1 2 3 15
-objdump -d "${objpfx}ld.so" |
-awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
-tee "$tmp"
+# List of object files we have to test
+rtldobjs=$(readelf -W -wi ${objpfx}dl-allobjs.os |
+ awk '/^ </ { if ($5 == "(DW_TAG_compile_unit)") c=1; else c=0 } $2 == "DW_AT_name" { if (c == 1) print $NF }' |
+ sed 's,\(.*/\|\)\([_[:alnum:]-]*[.]\).$,\2os,')
+rtldobjs="$rtldobjs $(ar t ${objpfx}rtld-libc.a)"
-echo "Functions which incorrectly modify xmm/ymm registers:"
-err=1
-egrep -vs '^_dl_runtime_profile$' "$tmp" || err=0
-if test $err -eq 0; then echo "None"; fi
+# OBJECT symbols can be ignored.
+readelf -sW ${objpfx}dl-allobjs.os ${objpfx}rtld-libc.a |
+egrep " OBJECT *GLOBAL " |
+awk '{if ($7 != "ABS") print $8 }' |
+sort -u > "$tmp"
+declare -a objects
+objects=($(cat "$tmp"))
+
+objs="dl-runtime.os"
+tocheck="dl-runtime.os"
+
+while test -n "$objs"; do
+ this="$objs"
+ objs=""
+
+ for f in $this; do
+ undef=$(nm -u "$objpfx"../*/"$f" | awk '{print $2}')
+ if test -n "$undef"; then
+ for s in $undef; do
+ for obj in ${objects[*]} "_GLOBAL_OFFSET_TABLE_"; do
+ if test "$obj" = "$s"; then
+ continue 2
+ fi
+ done
+ for o in $rtldobjs; do
+ ro=$(echo "$objpfx"../*/"$o")
+ if nm -g --defined-only "$ro" | egrep -qs " $s\$"; then
+ if ! (echo "$tocheck $objs" | fgrep -qs "$o"); then
+ echo "$o needed for $s"
+ objs="$objs $o"
+ fi
+ break;
+ fi
+ done
+ done
+ fi
+ done
+ tocheck="$tocheck$objs"
+done
+
+echo
+echo
+echo "object files needed: $tocheck"
+
+cp /dev/null "$tmp"
+for f in $tocheck; do
+ objdump -d "$objpfx"../*/"$f" |
+ awk 'BEGIN { last="" } /^[[:xdigit:]]* <[_[:alnum:]]*>:$/ { fct=substr($2, 2, length($2)-3) } /,%[xy]mm[[:digit:]]*$/ { if (last != fct) { print fct; last=fct} }' |
+ while read fct; do
+ if test "$fct" != "_dl_runtime_profile"; then
+ echo "function $fct in $f modifies xmm/ymm" >> "$tmp"
+ result=1
+ fi
+ done
+done
+
+if test -s "$tmp"; then
+ echo
+ echo
+ cat "$tmp"
+ result=1
+else
+ result=0
+fi
rm "$tmp"
-exit $err
+exit $result