emacs-devel
[Top][All Lists]
Advanced

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

Use gnulib's dup2 module instead of rolling our own


From: Paul Eggert
Subject: Use gnulib's dup2 module instead of rolling our own
Date: Sat, 25 Jun 2011 01:47:51 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110516 Thunderbird/3.1.10

Here's a patch to simplify Emacs proper, and work around some
platforms' dup2 bugs, by using gnulib's dup2 module in place of the
dup2 code in sysdep.c.  Most of this patch is automatically-generated;
the by-hand stuff is in Makefile.in (one line added), configure.in
(one word deleted), and src/sysdep.c (31 lines deleted).

I don't think this affects the Windows port but am giving a heads-up
before committing.

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
# target_branch: bzr+ssh://address@hidden/emacs/trunk
# testament_sha1: 05f410e91d17bd0e774aa185dd7c40db194f64e1
# timestamp: 2011-06-25 01:40:49 -0700
# base_revision_id: address@hidden
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog   2011-06-23 08:10:57 +0000
+++ ChangeLog   2011-06-25 08:40:38 +0000
@@ -1,3 +1,10 @@
+2011-06-25  Paul Eggert  <address@hidden>
+
+       Use gnulib's dup2 module instead of rolling our own.
+       * Makefile.in (GNULIB_MODULES): Add dup2.
+       * configure.in: Do not check for dup2; gnulib does that now.
+       * lib/dup2.c, m4/dup2.m4: New files, from gnulib.
+
 2011-06-23  Paul Eggert  <address@hidden>
 
        * lib/getopt.c, lib/stat.c, m4/gl-comp.m4: Merge from gnulib.

=== modified file 'Makefile.in'
--- Makefile.in 2011-06-21 16:15:07 +0000
+++ Makefile.in 2011-06-25 08:40:38 +0000
@@ -334,6 +334,7 @@
 GNULIB_MODULES = \
   alloca-opt \
   careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr \
+  dup2 \
   filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink \
   socklen stdarg stdio strftime strtoumax symlink sys_stat
 GNULIB_TOOL_FLAGS = \

=== modified file 'configure.in'
--- configure.in        2011-06-21 17:10:10 +0000
+++ configure.in        2011-06-25 08:40:38 +0000
@@ -2645,7 +2645,7 @@
 AC_SUBST(BLESSMAIL_TARGET)
 
 
-AC_CHECK_FUNCS(gethostname getdomainname dup2 \
+AC_CHECK_FUNCS(gethostname getdomainname \
 rename closedir mkdir rmdir sysinfo getrusage get_current_dir_name \
 random lrand48 logb frexp fmod rint cbrt ftime setsid \
 strerror fpathconf select euidaccess getpagesize tzset setlocale \

=== added file 'lib/dup2.c'
--- lib/dup2.c  1970-01-01 00:00:00 +0000
+++ lib/dup2.c  2011-06-25 08:40:38 +0000
@@ -0,0 +1,132 @@
+/* Duplicate an open file descriptor to a specified file descriptor.
+
+   Copyright (C) 1999, 2004-2007, 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* written by Paul Eggert */
+
+#include <config.h>
+
+/* Specification.  */
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+/* Get declarations of the Win32 API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
+#if HAVE_DUP2
+
+# undef dup2
+
+int
+rpl_dup2 (int fd, int desired_fd)
+{
+  int result;
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* If fd is closed, mingw hangs on dup2 (fd, fd).  If fd is open,
+     dup2 (fd, fd) returns 0, but all further attempts to use fd in
+     future dup2 calls will hang.  */
+  if (fd == desired_fd)
+    {
+      if ((HANDLE) _get_osfhandle (fd) == INVALID_HANDLE_VALUE)
+        {
+          errno = EBADF;
+          return -1;
+        }
+      return fd;
+    }
+  /* Wine 1.0.1 return 0 when desired_fd is negative but not -1:
+     http://bugs.winehq.org/show_bug.cgi?id=21289 */
+  if (desired_fd < 0)
+    {
+      errno = EBADF;
+      return -1;
+    }
+# elif !defined __linux__
+  /* On Haiku, dup2 (fd, fd) mistakenly clears FD_CLOEXEC.  */
+  if (fd == desired_fd)
+    return fcntl (fd, F_GETFL) == -1 ? -1 : fd;
+# endif
+  result = dup2 (fd, desired_fd);
+# ifdef __linux__
+  /* Correct a Linux return value.
+     
<http://git.kernel.org/?p=linux/kernel/git/stable/linux-2.6.30.y.git;a=commitdiff;h=2b79bc4f7ebbd5af3c8b867968f9f15602d5f802>
+   */
+  if (fd == desired_fd && result == (unsigned int) -EBADF)
+    {
+      errno = EBADF;
+      result = -1;
+    }
+# endif
+  if (result == 0)
+    result = desired_fd;
+  /* Correct a cygwin 1.5.x errno value.  */
+  else if (result == -1 && errno == EMFILE)
+    errno = EBADF;
+# if REPLACE_FCHDIR
+  if (fd != desired_fd && result != -1)
+    result = _gl_register_dup (fd, result);
+# endif
+  return result;
+}
+
+#else /* !HAVE_DUP2 */
+
+/* On older platforms, dup2 did not exist.  */
+
+# ifndef F_DUPFD
+static int
+dupfd (int fd, int desired_fd)
+{
+  int duplicated_fd = dup (fd);
+  if (duplicated_fd < 0 || duplicated_fd == desired_fd)
+    return duplicated_fd;
+  else
+    {
+      int r = dupfd (fd, desired_fd);
+      int e = errno;
+      close (duplicated_fd);
+      errno = e;
+      return r;
+    }
+}
+# endif
+
+int
+dup2 (int fd, int desired_fd)
+{
+  int result = fcntl (fd, F_GETFL) < 0 ? -1 : fd;
+  if (result == -1 || fd == desired_fd)
+    return result;
+  close (desired_fd);
+# ifdef F_DUPFD
+  result = fcntl (fd, F_DUPFD, desired_fd);
+#  if REPLACE_FCHDIR
+  if (0 <= result)
+    result = _gl_register_dup (fd, result);
+#  endif
+# else
+  result = dupfd (fd, desired_fd);
+# endif
+  if (result == -1 && (errno == EMFILE || errno == EINVAL))
+    errno = EBADF;
+  return result;
+}
+#endif /* !HAVE_DUP2 */

=== modified file 'lib/gnulib.mk'
--- lib/gnulib.mk       2011-06-21 16:15:07 +0000
+++ lib/gnulib.mk       2011-06-25 08:40:38 +0000
@@ -9,7 +9,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. 
--makefile-name=gnulib.mk --conditional-dependencies --no-libtool 
--macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 
crypto/sha256 crypto/sha512 dtoastr filemode getloadavg getopt-gnu ignore-value 
intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink 
sys_stat
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. 
--makefile-name=gnulib.mk --conditional-dependencies --no-libtool 
--macro-prefix=gl --no-vc-files alloca-opt careadlinkat crypto/md5 crypto/sha1 
crypto/sha256 crypto/sha512 dtoastr dup2 filemode getloadavg getopt-gnu 
ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime 
strtoumax symlink sys_stat
 
 
 MOSTLYCLEANFILES += core *.stackdump
@@ -159,6 +159,15 @@
 
 ## end   gnulib module dtoastr
 
+## begin gnulib module dup2
+
+
+EXTRA_DIST += dup2.c
+
+EXTRA_libgnu_a_SOURCES += dup2.c
+
+## end   gnulib module dup2
+
 ## begin gnulib module filemode
 
 libgnu_a_SOURCES += filemode.c

=== added file 'm4/dup2.m4'
--- m4/dup2.m4  1970-01-01 00:00:00 +0000
+++ m4/dup2.m4  2011-06-25 08:40:38 +0000
@@ -0,0 +1,76 @@
+#serial 13
+dnl Copyright (C) 2002, 2005, 2007, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_DUP2],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  m4_ifdef([gl_FUNC_DUP2_OBSOLETE], [
+    AC_CHECK_FUNCS_ONCE([dup2])
+    if test $ac_cv_func_dup2 = no; then
+      HAVE_DUP2=0
+      AC_LIBOBJ([dup2])
+    fi
+  ], [
+    AC_DEFINE([HAVE_DUP2], [1], [Define to 1 if you have the 'dup2' function.])
+  ])
+  if test $HAVE_DUP2 = 1; then
+    AC_CACHE_CHECK([whether dup2 works], [gl_cv_func_dup2_works],
+      [AC_RUN_IFELSE([
+         AC_LANG_PROGRAM([[#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>]],
+           [int result = 0;
+#ifdef FD_CLOEXEC
+            if (fcntl (1, F_SETFD, FD_CLOEXEC) == -1)
+              result |= 1;
+#endif
+            if (dup2 (1, 1) == 0)
+              result |= 2;
+#ifdef FD_CLOEXEC
+            if (fcntl (1, F_GETFD) != FD_CLOEXEC)
+              result |= 4;
+#endif
+            close (0);
+            if (dup2 (0, 0) != -1)
+              result |= 8;
+            /* Many gnulib modules require POSIX conformance of EBADF.  */
+            if (dup2 (2, 1000000) == -1 && errno != EBADF)
+              result |= 16;
+            return result;
+           ])
+        ],
+        [gl_cv_func_dup2_works=yes], [gl_cv_func_dup2_works=no],
+        [case "$host_os" in
+           mingw*) # on this platform, dup2 always returns 0 for success
+             gl_cv_func_dup2_works=no;;
+           cygwin*) # on cygwin 1.5.x, dup2(1,1) returns 0
+             gl_cv_func_dup2_works=no;;
+           linux*) # On linux between 2008-07-27 and 2009-05-11, dup2 of a
+                   # closed fd may yield -EBADF instead of -1 / errno=EBADF.
+             gl_cv_func_dup2_works=no;;
+           freebsd*) # on FreeBSD 6.1, dup2(1,1000000) gives EMFILE, not EBADF.
+             gl_cv_func_dup2_works=no;;
+           haiku*) # on Haiku alpha 2, dup2(1, 1) resets FD_CLOEXEC.
+             gl_cv_func_dup2_works=no;;
+           *) gl_cv_func_dup2_works=yes;;
+         esac])
+      ])
+    if test "$gl_cv_func_dup2_works" = no; then
+      gl_REPLACE_DUP2
+    fi
+  fi
+])
+
+AC_DEFUN([gl_REPLACE_DUP2],
+[
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_CHECK_FUNCS_ONCE([dup2])
+  if test $ac_cv_func_dup2 = yes; then
+    REPLACE_DUP2=1
+  fi
+  AC_LIBOBJ([dup2])
+])

=== modified file 'm4/gl-comp.m4'
--- m4/gl-comp.m4       2011-06-23 08:10:57 +0000
+++ m4/gl-comp.m4       2011-06-25 08:40:38 +0000
@@ -37,6 +37,7 @@
   # Code from module crypto/sha512:
   # Code from module dosname:
   # Code from module dtoastr:
+  # Code from module dup2:
   # Code from module extensions:
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   # Code from module filemode:
@@ -102,6 +103,8 @@
 gl_SHA256
 gl_SHA512
 AC_REQUIRE([gl_C99_STRTOLD])
+gl_FUNC_DUP2
+gl_UNISTD_MODULE_INDICATOR([dup2])
 gl_FILEMODE
 gl_GETLOADAVG
 if test $HAVE_GETLOADAVG = 0; then
@@ -404,6 +407,7 @@
   lib/careadlinkat.h
   lib/dosname.h
   lib/dtoastr.c
+  lib/dup2.c
   lib/filemode.c
   lib/filemode.h
   lib/ftoastr.c
@@ -453,6 +457,7 @@
   m4/00gnulib.m4
   m4/alloca.m4
   m4/c-strtod.m4
+  m4/dup2.m4
   m4/extensions.m4
   m4/filemode.m4
   m4/getloadavg.m4

=== modified file 'src/ChangeLog'
--- src/ChangeLog       2011-06-24 21:25:22 +0000
+++ src/ChangeLog       2011-06-25 08:40:38 +0000
@@ -1,3 +1,8 @@
+2011-06-25  Paul Eggert  <address@hidden>
+
+       Use gnulib's dup2 module instead of rolling our own.
+       * sysdep.c (dup2) [!HAVE_DUP2]: Remove; gnulib now does this.
+
 2011-06-24  Juanma Barranquero  <address@hidden>
 
        Move DEFSYM to lisp.h and use everywhere.

=== modified file 'src/sysdep.c'
--- src/sysdep.c        2011-05-03 05:47:50 +0000
+++ src/sysdep.c        2011-06-25 08:40:38 +0000
@@ -2012,37 +2012,6 @@
 }
 #endif /* HPUX and not HAVE_PERROR */
 
-#ifndef HAVE_DUP2
-
-/*
- *     Emulate BSD dup2.  First close newd if it already exists.
- *     Then, attempt to dup oldd.  If not successful, call dup2 recursively
- *     until we are, then close the unsuccessful ones.
- */
-
-int
-dup2 (int oldd, int newd)
-{
-  register int fd, ret;
-
-  emacs_close (newd);
-
-#ifdef F_DUPFD
-  return fcntl (oldd, F_DUPFD, newd);
-#else
-  fd = dup (old);
-  if (fd == -1)
-    return -1;
-  if (fd == new)
-    return new;
-  ret = dup2 (old,new);
-  emacs_close (fd);
-  return ret;
-#endif
-}
-
-#endif /* not HAVE_DUP2 */
-
 /*
  *     Gettimeofday.  Simulate as much as possible.  Only accurate
  *     to nearest second.  Emacs doesn't use tzp so ignore it for now.

# Begin bundle
IyBCYXphYXIgcmV2aXNpb24gYnVuZGxlIHY0CiMKQlpoOTFBWSZTWeo2+DIAEIffgHfw/f//////
/+6////+YBqHFmaafb05Hn166+82vm89Nt0MnewA9ABQPN099t33SjNz3vfG9E+3drnue65vbt97
OlrZGJ9fee6LTGzObr2zypJCSJNNCaCn6A0RiBNJsU9NTGI0JiaAaaaaYynogaaCSQAmQECNCNIp
+mk8qekN6SABkNAGgBiBmoNINTCj0iYh6mmmgGINAAAAGQMgANA0CREIImAmRT9SfqU/0IyaGqeK
ek09Q0Gg9R6nqPUHojTR6g9QIpEm0mTJo0mIyFT3lMVH6mp5Q9T2qHlNNPKNAGgHqAAAikmQJoAU
9J6ZTyjEZU2KeaptTbQJoR5T1AeSD0gAH5FYJaBkCKxMjODn0GmAzBsvL5x9UXnd2fQ7US36bjbU
SmTHxYh+Lg3bq7MyXV1nCdYxfOLi4V8iPYkaouSsXZdtr+53xdP2/wHtVzSPf6A3+e27fE3W+I6R
DZwdSpGR1ZRos9DfD8JOX4My5Ee/4cOOrLCjN8Tm+vMzZl+18o4rZ64n3TSIXJLsbVcRPJ9MWVbs
lHRsWf2vcYsmIwHGIKWuGVbGGC2td5AQUXrchq0EXd3w64nidoPSXqwCI5+2fwNrGgwZmkHOzhC2
rYjOGEmarKtHE5tJ0axS+tEZNs61L+Gy6dWsgElkISPsajYDYQi8aJJHpIhSMYfOyGIhohgP1Fse
14fjOFe/fZEpmhXFbD0nwHcbzCys15RvdcT8FKqKggO5cnDzVVxdmNDI9n78P9S2L2b4O87/5izL
P6yEY7Yevds2360fnQZsqOKGDYm20Ntpj9c5Iyt9dKT2CRnuFyCwaXDAzYEUrtH2THW+l8KP7Zxi
1HRfpOsucClv2oXWOrjK7E2Pg2eVIQzb2sfW8UKRy8HdmibeK+lW8kF00sZsxbX8huSgBmjaiFZ+
hzWCu9wYNtt1TuRhj5siOnD0nbTveIoPXm4wBxrEqKt0zV4KE01pmI3wY/m47KGKqhad5t4zo5ht
m/rlzkfbwsypWMwrJ5+eHNowzPEYIdYHiK7S3HuWjBRgMrOfTnMlwO5SnT7sGMm0UxzIFG182gLk
+i3Jp1FzDfYH3Gx3JMElyB0OOu33z7iEpHm6lubotayc5l2JkYDi+Kuf9uuTMwm+c27y/coOKyy0
MZqal7i46OtEG256Se2OCVjKVS9v19EnT1S+cz6Mkly0/Ev0avBbDe0oahnGFSle5lPqovJsWCtR
5SIGTzxonsNW4nAd8bMD19xfyTn7ILewnX6jL2SqSNY7Xcny+1tuacznaY+P6fRQDdBlN7IzrmM/
l749EzueZMgx3ke+lWwAdFXy+jM+HljjvHjOk4ZBcQOzGPdrELloBJ/RxOMH+YvDHC/Kd5GbelLb
w3ZabM+ncw3BTlfv2ciDzjR4eE7/NIbEQJt6Mm7kcdpq7XOTPy0Uu7MPYl4kFeqUY3pmewtSRQfP
jl8+itFPmLCOf65MoUmECHTEnwPqrJdUephDsMMj2aV8fD1wG+/daB8KAA8rIPkuWLrta9njXO7m
IlmfSkwVNDCPkzyFkSnC5bQmU6QR12POIIaicECCJTDMedL36nQ7swz9E3ju+X3WpKGQOhiu7gMX
A3Nyme/Ow2RYX7doyY1/hjTLd0lAZfMbv83G0jhC3cexy4lEBn8hBXyDA4TF3nunODmMgMVHCeAi
VX1gTphhbmBIYUNQQt5WSFPOfBdtRqICYbDaZio3Ml6aPQfzsXRpvu412MpbYzNLBTXkv2l3LNaH
34b9PBZnSLrPfTUux+ZaSUjhguim8005Plo8sMcz6auDiKqqqcn6z0UbVdfHt7viMuxiZnMmE0vo
ea5rU6+siIIIMveDi8BBO6OnjuxNm+6urhOO2JuxmRgNIbqpVL/XWqFFIEb5b3ELfR9I3SzjN506
CWHj0rQn42zNubbbbbb2ILa7G/Cs7dw1TZ2Vw2HDo1cd71Skl0MOLlnR+KAolashQdPl902yhUhL
HpebFLXCpQhbFixIRRhqwqN0LMJ0ySmLVrCOdm7k0rCQ0/1KM60b95ppLI0HJqqMfspkUcYKuIay
HBN8EkkSHVzKRSkUwYK3yxOCWCaUGdJkxGa2RmQKl9XiusxuFM4gRDarxc0mMk05E8i7Z2cgYDOG
H+Akapg7h3XmepORfc7sCLbjElJQZkJ65xelBQOT/GGgxFiIZnu3BOuRItLHB0raxL2rKq7VaO+A
mRuOQkqp/YarAjkLyp61tw2UCVhkwBqapAAyOYlgZhJyUBlTJK6UDOKmueVSWaT4yDJR3cS+9lwz
kfLwum4rR5IS8iXUZXtSjIJStqkaWyB1O0ciVjhJDt10HGSWq3OM8kuiUhxmY4lkPSrcboXSlAsP
EP0gA6DxRY8Wz4vrdMVY/BbS/AlFPUjjaYkyePQfi7SO3FjLwNCsJqRLc8fpIVPU7ZLwP/c8bwhC
vR3EHunJBA5eTUfAowQYTiVXKY9tttBzhxWssskLpo1QkC1lKLZUeJAoPQ0IQLDAzrS4WuTxq3eC
4mDc3ECWtQcnUBEPAlN2orpVkCIpZEZvolE8Wx6RudPuDPJXqi7WfkcHpFADkrpRaET8h4zGjuc1
vxteR6XoWl7vrz8mBXBmJ7eOxbLVWyhvLpJJK4gkJq6TRhsv2lpeqt0YceoI5xpFmeqjKQk3EnVA
kPFT5S867PtPK3WUJQSulRmNfo8UuQ+3EDFSJZLKFM54Wkshod612/EVWsRJk6Z5JRXWMOgkcoYG
yHLjrQ4uERWlhaalkvE615to6kzl2NJdZzJvw82eVpRjWST35iRJeZEKymSwr8GmSw2CBkNubU1J
8ZJbwH3oEypHsZVbPi9imZ2S5Eg9BIoonxD5Py54MEYxhWBBknJlCXQkJDx+oWekidZKTOEs12ll
UoDovOU8nm1FO5B9hvYrWnAi4SZOS57g5HUwSzqNrBLBEcn/eWyyrbob1PgItNMGvgcKLW5Z32yU
rrYwcyYlMAo+kySW5mV8MPQMloZDbs+0Suw5ihuQrPUosjwM0yX2Kx5lzfUxU1k1xtfOSw/uHLFs
KjQBtC9ptNiepQoaGfspix0qU3SqkMOwumNR4EI6uGiZ1uX5oa6ZKVEsEHZJMQyhUtfnUet9MEzp
TXWTzDicSc7sYwNqT1GKF7s5+rFiBVKTyRq81VigYLkYsbCWU7nxOh9glDgsdLOvvrKe0UmKc4Rn
yHFHpPMwJ87WaAeTlIuw5AHRhIswTc5ADiYjmc21GaJ5BSeTGR5JVM6ntlgnK5fUyuOYnoZOtSNt
qM/JxHLNMfMOF3S8HJgDkY93FUr4Wx5PrtoaRfM8SMnkeXY9VBL1Xmu5+BLNPSyOxklGWgp+Xj38
G4PCbpeFYIilRNKjSK1j58UJ1K1xEjytxMpZ3Oh1aeWuj8F8rGpAi48fFrlL7i7paJIyW85bsZuX
A8iTLtC0eZeUCXQulTKndZYmSEuqclsvKWx0EKHuGLa53NzJNdGe4aVUkcnDNz3VOe45WlAYwwO8
OlTr0jJ2qyHis6K4Si4fESNVjZctiV4zqbwJj4Z46j3YOMoDs576VuVlyfaxJ4yVwn2S52LsSzL4
1yliGV+NyhN6aEtXxeea+lKCX7CVvU35Z3LD5Q1aeIvTERKejl1gJRipRWhyLTSbm3Ax1KvY7G5o
tTMvKpSl+0ny6vUuLaydPZ0M66iW1ibkshilfmsiUeVJjjJnreuNtvTvy1D3h7VuqV8jwNh7jedn
Dzu+2iyRyGYEm5Y6VgxYRCF6ViizZMwosgCayVIWtdbNnWAWAK69JpQlxvO3m1HqM9fZL7GGNtGN
XLtChzMHJfXenMcCtR7V4/N3RLZyiDuoOp3SZdwXrZncb1jMphEqHBEIhf5GB9TwSzGZtttpjbXK
oZDbbhi0oHLbAb5zUR57xBp67vKzx8Y2ibPKXPV6kIHHUFUTXA656BBPK0C5+hrc7b8fenFs72Gm
JCR72VgHsEQuk3s5vwdcDUbokH/cbNANADQwYQWgbSaGDYxJtsxSP7fE/qUiCgftGs8t+svtSMCg
VVhIaNciYFTC94wSw+UNaUUrvEHK06AiKm0i2SpYrl6ewcm62I+5/wKORksfWKwLL/JEdmTwLYyM
2/VmxyF4HGPKrAwyYp4JsCM6RJuN5gOoubQrTUcFhQANNbzN6jVQKVw/8J+n183kUpXYmabBltJ8
uy9fVD372gUPYmsnyr4zRYwET25oxfqYZ7zo0HjiUaC0gQMkeg6b4qFBxf7BVuMEZCBRKeuKUULg
ipBMFxoMd61i9nKB0euefM9NVR11mJMy04RaF2DdJlBbFptvTBac09W+lrDLNlPIdBUz6OOXGk2e
6GAhgmVFXKK4eqIpo2PU6LQhSmScofcseCgWOoGyxFAacN0mWklSBdcZjKOsGECfGXyK17g5qaGt
3Pkwh3bqg5OfUTt6p8565Rrbj8FfpmOxJ/HIc6sgsWIoZbApjwkrnqQxNp99QfYv5qVf0sxtdlZT
rHO04Yllcnf7Js9JmPZjiMRMfP8d5cJ7SJA+cU/iDY+t60+1YJBEEfCAHbmJl5v+yoQlmEvnAY6x
BPu7xXsyBtpBEQUggFNt3nbCJQecsmVELEAkWqAMLDjH5SspPslBdjDramW1Bv8emiwZf1XL6H5T
toO7fjP7f7LhaclRBY8EctaUI1mUupawFfS9qXHobAEzHoTD+mTz6WfI2QeditrBos83xfi6lusW
twQlfPbz8Bu4KhqntzNGvzhx1YfHTOD5fa5lsG1ktd7VGqWV/wE+jQUhc5q8uS8FTuNhD4sEc4ef
UXrYfIYdeXcWPkfA+oqaXrlVoRzoeyO2KnsG1C5LemTr6HaZHhpF5aaGeRbao0FRd4w8S9F1PD8f
oL2b1Cye0c6bPaAEgedWPoGCNMEO/I5+e1useZ5ngyibWh8koeXj6DJXy/J3iaWWlBw5K1D0Ii9I
EiT4bQSmSc9cgXTlPl/sVNip3X4+4E49irGx7deN5DiFdvH4msiT7zTDMX4jfgtfHbEaSd4bK12Z
BBJ1/hH5oLQNa4B8t69HiI/fmzxek3vmioP/CCaXOZTpBhoe+WcWaIAsg3jKTCYX4hJIgyMFDOAR
5jA7ZJeflPz+r6j5KWs5DRw50Mz2zhkfr7JYLDYs5aICGPkxVPElXmNFVF66kuEe16BTEq5O2wNl
dvjqqNp2GTLmswA6DqMxjsKjp7mhzxES6yA+WkN9eZ3pzcZ9KhZkhmXT0HREeHzAOY6xykSOiWR5
+gZr4VoHQ4r+K7ewryCCZUJd8h1MHzjLNkJ/mGhAdva0222QvMiwiC60DeIl8nzNNrlenrRVq3nC
5DoFZ8fLf6evIYMbo0DyfOK+JWDdVwd+I7sax5aoTXdZxVpU3L90cdkwMI3do3FTS1NPdrbThN7G
Kp8sh/vxwSGIse7UdGETXF220oPjDbXnvWvs4hqc195O+Rpmakz6yD4HMgY5kCqB3xKHh6bDuEHm
g5xDQaJAHYMREg4G9CAHA0tYdlxhTXjYW+SOBww7xkKyd9LZTV2c+mzmlrijYwGxPVnnuECYi0mP
4ORrOgz+w6+tuSuM8R1C9i9ezmWZY1rNXJmSnE3oZK5LNu9s7Lg47g47pOO6TjuJx3BxxDIH7yC5
IoCQG9f1rcCY5tubf0ZJtSWvLF9+6+yU9Weum+PWlcJdWrrBnwev3HX2BfEa68Yz3xhDISPeze7t
TlALUSFSad9YyVYFRGOW2SG5eQW2YJrpg6D5+0eHIxuDFhmBJFSVy2bMcwO5NxP8thRe53E0Dq+w
vQELBUC8d7jSOqG+tXlgubTMV9xLBBxrmDTCDERxCTEo+LJqCAhWRpVqt+sVTfINAZdgtMZTRqnI
lJxoFJwUYTXSRFAKfGZyXVu0MqVMDqNy6iPwHgTUN0bIY0ohQQwaEmDXkMJE6EF+xKCFBchM06q/
JoJAHAPW93DqIo9AyNKEbx7EJCWwVCeNaxSyJh3pSAvWcj3whYKd3MbaLuBrfluu8Ic8ZxkMvTSp
7zuNgc4pQtclg1rcQAwHUCpkycIPgJaIJxDEc1T9R6bD2+jSu72H0wy/R8kqtgzmK7W/auJ4ds3G
dqONmeKLR6Xfx2B1LUXpmO9mu99RzO43pa1wD2QBPd2pAdeO72lgjImcqUJHZQvkPhDH7JEED6Vm
Nkcqq4I3719y5Ho9JwbdYd4LcuIDzF2DzmAgQw0gbSX7QqnwWT5ti+BB/5CWFejnyJXoKePmPpfs
TYwKzB8zbIGclEBg3MZO8aDVWiPQu8lACOcjQAaLamdI7G6JJYfODOs/tAaUxIS3XvqIcdoTiIDZ
5mOuoKq98J3V6FtXk1dohgCCFiACAyOw6VoeKtAxn1wxERCYecV088c5yl7aEmZjOiCmSa5aVnre
3jc4oaaOlcn6QZPEh+4Fy7DHk3kmEZLQ2iTD2v0WwREdq8vLvAbjoMgv9r1dDAmsUpqD0PBPYccd
mAkmXURETqqoFDSK8HMsINizFtgWYhqgziCZ2OV4UKFePJ73hlJsIQwAejKSQwwCWiK4LF9FQnoI
XK+GSz21YOceXYu359Fjs2Pw1xgvfVm96XVPNkvHPUMR6IaFYhGaSZrWBWG90XlRC74CWpe5ng2E
BsxsiPGG9mwUvklcAMFE1ZYMI0JOJWxtofPFkr4aSbkvgc0iGQsqWUAwKYmoNSkox3Mqmple+Ibo
opQvo2FKOpMkOYIBpeIbZUTS/MuitEthpWZWIdPXihvPeWA5wL84EzkzqagGoPPE4gTFSimi+U1z
lbvah7gpSRDFoEjGt5RmSR1MuAd9Waq5ShDoO1JRhNTaL73M4OdLbQSQB5lhEkQqabVXvYagWQpM
0uW7dCEH5Skpl8Mg2BkLCzE89VRnJ3e7k5yFoGtT9IVnlLQo2P3HFdhdMHtBXCmcmkKQRvSaWBK0
F3lAuIA00m40kHZtGystAtOrwIb1KxC04liJ4cyRlLh0x0n4Ts+8J5XbQzFoSm7PIvkcDrOdgSXO
l7UhJZLrKAAUd7i/d0elYQhUsAK+zlrnfBfZJdDurXzPofW+awoN+K8mXXVyrwh1rZpDgFpbXUGl
6oeAupe5ZyfhxZhC2r3NHc49ZovicYykGQfTnOIgghCuJBICa8S9KXNdnWEBffLaJMG7FUBHQHhI
jb0FioUqg7I9TCdgfUkgJ/CVCo9kqh4rWsgDXfnQ1jWwTcfE6TqsBayNYMjWrJpouh0OSF0wMMLi
5WQQkoQUthc88GSM5olwda799dfFiWMuk/Sw36ZHOzjMc1NsEoLY8PZqz2xNZKqid7caxCBF6naO
hb4jvJYFEYCSZ2u2QyJdkczMl6CKLLGyZE8LG6lB+6KkkEjahR5tUKGn78yNbAREQEEHeQqOW+XF
ujVRZQqXoFiGs+8wbGxtDY2DZZdQkYrK+4SgPyE4AY+JkEs2WVS49fgmWmcJFugB10mxcaJSBae5
mcxFY0ZvUSLXXQ05hyHmsnJREn9vaNv74E+MkShCoSMgLEXilk1orqpZK3p8RI8IeAMQKYLjEEuQ
uu6RCXKtUhbIlZkK1mEqTTeRCzNaei6QhgtZYVCGGKqpPK1VFF0RFa5+G4XNsh6IsglGS243hQOG
PdXUVgNETDJ2rOpIjBbhlZZKytU0YAb3UG3OrschlZgRXsJRI3DqQQgCYaly4NENIU+90V0OYQTS
8gGlYdTuI4yNomzK1cAGa6FSTCVeBULIOQ+wyIy8twoHqhLrE1dtIVvwbjIVkBPvhQMsPE3BwB5b
z8QsuFp7dsZCeuqeCJcUO5bQVhfJ+80FOD9tdBQ2kjludDOQ39uTOfw3LumWvZ5uLUFzxF9Ak95F
WJ2CxkePZdHVEoPqMXn1l3TNjccnQSXsda71og+ku59h04uZe6cJ6prqhcbnNpa39ZrOXxGxfpDm
Z0hwDKZZjmPAUcxMU4LracysmhBE1qZ714ajyD4+t/qmoSU6iURH/xdyRThQkOo2+DI=



reply via email to

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