Updated to fedora-glibc-20080111T0737
authorjakub <jakub>
Fri, 11 Jan 2008 07:45:12 +0000 (07:45 +0000)
committerjakub <jakub>
Fri, 11 Jan 2008 07:45:12 +0000 (07:45 +0000)
37 files changed:
ChangeLog
fedora/branch.mk
fedora/glibc.spec.in
iconv/loop.c
iconvdata/Makefile
iconvdata/ibm1364.c
iconvdata/ibm930.c
iconvdata/ibm933.c
iconvdata/ibm935.c
iconvdata/ibm937.c
iconvdata/ibm939.c
iconvdata/iso-2022-cn-ext.c
iconvdata/iso-2022-cn.c
iconvdata/iso-2022-jp-3.c
iconvdata/iso-2022-jp.c
iconvdata/iso-2022-kr.c
iconvdata/tst-iconv7.c [new file with mode: 0644]
libio/stdio.h
localedata/ChangeLog
localedata/locales/ga_IE
malloc/malloc.c
nptl/ChangeLog
nptl/pthread-errnos.sym
nptl/sysdeps/unix/sysv/linux/i386/i486/sem_post.S
nptl/sysdeps/unix/sysv/linux/sem_post.c
nptl/sysdeps/unix/sysv/linux/structsem.sym
nptl/sysdeps/unix/sysv/linux/x86_64/sem_post.S
nscd/connections.c
posix/tst-rfc3484-2.c
posix/tst-rfc3484-3.c
posix/tst-rfc3484.c
stdlib/Makefile
stdlib/tst-makecontext2.c [new file with mode: 0644]
sunrpc/clnt_perr.c
sunrpc/rpc_thread.c
sysdeps/posix/getaddrinfo.c
sysdeps/unix/sysv/linux/i386/makecontext.S

index 3a98c7a..9b70229 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,82 @@
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/posix/getaddrinfo.c (rfc3484_sort): Store result of
+       native interface lookup in all the relevant places.
+
+2008-01-10  Jakub Jelinek  <jakub@redhat.com>
+           Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/posix/getaddrinfo.c (sort_results): Remove service_order
+       field.  Use sockaddr_in6 for source_addr.
+       (get_scope): Change type of parameter to sockaddr_in6.  Adjust.
+       (match_prefix): Likewise.
+       (get_label): Likewise.
+       (get_precedence): Likewise.
+       (rfc3484_sort): Change to use indirect access to results array.
+       Adjust to use of sockaddr_in6.  Replace service_order test with
+       simple index comparison.
+       (getaddrinfo): Define order array.  Initialize it.  Don't initialize
+       service_order field.  Adjust qsort_t calls.  Access sorted result
+       array indirectly through order array.
+       * posix/tst-rfc3484.c: Adjust for change of rfc3484_sort.
+       * posix/tst-rfc3484-2.c: Likewise.
+       * posix/tst-rfc3484-3.c: Likewise.
+
+2008-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+       [BZ #5541]
+       * sunrpc/rpc_thread.c (__rpc_thread_destroy): Also free xports and
+       pollfd structures.
+       Patch by AndrĂ© Cruz.
+
+       [BZ #5545]
+       * sunrpc/clnt_perr.c (clnt_sperror): Don't use fixed size buffer.
+       (clnt_spcreateerror): Likewise.
+
+       [BZ #5553]
+       * malloc/malloc.c (public_mALLOc): Set ar_ptr when trying main_arena.
+       (public_mEMALIGn): Likewise.
+       Patch mostly by Daniel Jacobowitz.
+
+2008-01-09  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/makecontext.S (__makecontext): Avoid
+       clobbering memory at or above uc_stack.ss_sp + uc_stack.ss_size.
+       * stdlib/Makefile: Add rules to build and run tst-makecontext2.
+       * stdlib/tst-makecontext2.c: New test.
+
+008-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       * iconv/loop.c (UPDATE_PARAMS): Define to empty statement if not
+       defined.
+       (REINIT_PARAMS): Likewise.  Undefine before end of file.
+       (STANDARD_TO_LOOP_ERR_HANDLER): Use UPDATE_PARAMS before calling
+       transliteration hooks and REINIT_PARAMS afterwards.
+       * iconvdata/iso-2022-jp.c (BODY): Use a separate variable for
+       status.
+       (REINIT_PARAMS): Define.
+       * iconvdata/ibm1364.c (REINIT_PARAMS): Likewise.
+       * iconvdata/ibm930.c (REINIT_PARAMS): Likewise.
+       * iconvdata/ibm933.c (REINIT_PARAMS): Likewise.
+       * iconvdata/ibm935.c (REINIT_PARAMS): Likewise.
+       * iconvdata/ibm937.c (REINIT_PARAMS): Likewise.
+       * iconvdata/ibm939.c (REINIT_PARAMS): Likewise.
+       * iconvdata/iso-2022-cn.c (REINIT_PARAMS): Likewise.
+       * iconvdata/iso-2022-cn-ext.c (REINIT_PARAMS): Likewise.
+       * iconvdata/iso-2022-jp-3.c (REINIT_PARAMS): Likewise.
+       * iconvdata/iso-2022-kr.c (REINIT_PARAMS): Likewise.
+       * iconvdata/Makefile: Add rules to build and run tst-iconv7.c.
+       * iconvdata/tst-iconv7.c: New test.
+
+2008-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+       * libio/stdio.h (vscanf): Fix definition for loser compilers.
+
+2008-01-05  Jakub Jelinek  <jakub@redhat.com>
+
+       [BZ #5112]
+       * nscd/connections.c (restart): Fix condition.
+
 2008-01-03  Jakub Jelinek  <jakub@redhat.com>
 
        * ctype/ctype.h (__ctype_b_loc, __ctype_tolower_loc,
index 4351f00..06c6d25 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2008-01-03 19:58 UTC
-fedora-sync-tag := fedora-glibc-20080103T1958
+fedora-sync-date := 2008-01-11 07:37 UTC
+fedora-sync-tag := fedora-glibc-20080111T0737
index 3567731..836e6ed 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 3
+%define glibcrelease 4
 %define run_glibc_tests 1
 %define auxarches i586 i686 athlon sparcv9v sparc64v alphaev6
 %define xenarches i686 athlon
@@ -1011,6 +1011,15 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Fri Jan 11 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-4
+- update to trunk
+  - misc fixes (BZ#5541, BZ#5545, BZ#5553, BZ#5112, BZ#5520)
+  - getaddrinfo fixes
+  - signalize EOVERFLOW from sem_post instead of overflowing
+    the counter
+  - fix i?86 makecontext
+  - fix iconv for iso-2022-jp//translit (#397021)
+
 * Thu Jan  3 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-3
 - update to trunk
   - fix recognition of interface family (#425768)
index df8c8dc..da11bc2 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion loop frame work.
-   Copyright (C) 1998-2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2003, 2005, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
 # define EXTRA_LOOP_DECLS
 #endif
 
+/* Allow using UPDATE_PARAMS in macros where #ifdef UPDATE_PARAMS test
+   isn't possible.  */
+#ifndef UPDATE_PARAMS
+# define UPDATE_PARAMS do { } while (0)
+#endif
+#ifndef REINIT_PARAMS
+# define REINIT_PARAMS do { } while (0)
+#endif
+
 
 /* To make it easier for the writers of the modules, we define a macro
    to test whether we have to ignore errors.  */
         case we are not doing any error recovery outself.  */                \
       break;                                                                 \
                                                                              \
+    /* If needed, flush any conversion state, so that __gconv_transliterate   \
+       starts with current shift state.  */                                  \
+    UPDATE_PARAMS;                                                           \
+                                                                             \
     /* First try the transliteration methods.  */                            \
     for (trans = step_data->__trans; trans != NULL; trans = trans->__next)    \
       {                                                                              \
        if (result != __GCONV_ILLEGAL_INPUT)                                  \
          break;                                                              \
       }                                                                              \
+                                                                             \
+    REINIT_PARAMS;                                                           \
+                                                                             \
     /* If any of them recognized the input continue with the loop.  */       \
     if (result != __GCONV_ILLEGAL_INPUT)                                     \
       {                                                                              \
@@ -319,9 +335,7 @@ FCTNAME (LOOPFCT) (struct __gconv_step *step,
   /* Update the pointers pointed to by the parameters.  */
   *inptrp = inptr;
   *outptrp = outptr;
-#ifdef UPDATE_PARAMS
   UPDATE_PARAMS;
-#endif
 
   return result;
 }
@@ -492,6 +506,7 @@ gconv_btowc (struct __gconv_step *step, unsigned char c)
 #undef EXTRA_LOOP_DECLS
 #undef INIT_PARAMS
 #undef UPDATE_PARAMS
+#undef REINIT_PARAMS
 #undef ONEBYTE_BODY
 #undef UNPACK_BYTES
 #undef CLEAR_STATE
index 4ac5de3..1a46a64 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1997-2004,2005,2006,2007 Free Software Foundation, Inc.
+# Copyright (C) 1997-2004,2005,2006,2007,2008 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
@@ -67,7 +67,7 @@ include ../Makeconfig
 
 ifeq (yes,$(build-shared))
 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
-       tst-iconv6 bug-iconv5 bug-iconv6
+       tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7
 ifeq ($(have-thread-library),yes)
 tests += bug-iconv3
 endif
@@ -365,6 +365,8 @@ $(objpfx)tst-loading.out: $(objpfx)gconv-modules \
                          $(addprefix $(objpfx),$(modules.so))
 $(objpfx)tst-iconv4.out: $(objpfx)gconv-modules \
                         $(addprefix $(objpfx),$(modules.so))
+$(objpfx)tst-iconv7.out: $(objpfx)gconv-modules \
+                        $(addprefix $(objpfx),$(modules.so))
 
 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
                         $(addprefix $(objpfx),$(modules.so)) \
index 1d46cf6..6881341 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM1364.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@jp.ibm.com>, 2005.
 
@@ -387,6 +387,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index f5e2cb1..67d0791 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM930.
-   Copyright (C) 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -277,6 +277,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index 389028e..db822ea 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM933.
-   Copyright (C) 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -272,6 +272,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index 6475739..5b9af9a 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM935
-   Copyright (C) 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -272,6 +272,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index 2d46115..52f7aea 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion from and to IBM937.
-   Copyright (C) 2000-2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -272,6 +272,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index 50b083f..9f3a363 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion to and from IBM939.
-   Copyright (C) 2000-2002, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2005, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Masahide Washizawa <washi@yamato.ibm.co.jp>, 2000.
 
@@ -277,6 +277,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *curcsp
 #define INIT_PARAMS            int curcs = *curcsp & ~7
+#define REINIT_PARAMS          curcs = *curcsp & ~7
 #define UPDATE_PARAMS          *curcsp = curcs
 #include <iconv/loop.c>
 
index fd02d63..3ffaf19 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion module for ISO-2022-CN-EXT.
-   Copyright (C) 2000-2002, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2000-2002, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
@@ -648,6 +648,12 @@ enum
 #define EXTRA_LOOP_DECLS       , int *setp
 #define INIT_PARAMS            int set = (*setp >> 3) & CURRENT_MASK; \
                                int ann = (*setp >> 3) & ~CURRENT_MASK
+#define REINIT_PARAMS          do                                            \
+                                 {                                           \
+                                   set = (*setp >> 3) & CURRENT_MASK;        \
+                                   ann = (*setp >> 3) & ~CURRENT_MASK;       \
+                                 }                                           \
+                               while (0)
 #define UPDATE_PARAMS          *setp = (set | ann) << 3
 #define LOOP_NEED_FLAGS
 #include <iconv/loop.c>
index 1613cf2..7247dd2 100644 (file)
@@ -1,5 +1,5 @@
 /* Conversion module for ISO-2022-CN.
-   Copyright (C) 1999, 2000-2002, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000-2002, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
 
@@ -393,6 +393,12 @@ enum
 #define EXTRA_LOOP_DECLS       , int *setp
 #define INIT_PARAMS            int set = *setp & CURRENT_SEL_MASK; \
                                int ann = *setp & CURRENT_ANN_MASK
+#define REINIT_PARAMS          do                                            \
+                                 {                                           \
+                                   set = *setp & CURRENT_SEL_MASK;           \
+                                   ann = *setp & CURRENT_ANN_MASK;           \
+                                 }                                           \
+                               while (0)
 #define UPDATE_PARAMS          *setp = set | ann
 #include <iconv/loop.c>
 
index bbccc2e..7df8ea1 100644 (file)
@@ -1,5 +1,6 @@
 /* Conversion module for ISO-2022-JP-3.
-   Copyright (C) 1998-1999, 2000-2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998-1999, 2000-2002, 2004, 2008
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998,
    and Bruno Haible <bruno@clisp.org>, 2002.
@@ -759,6 +760,12 @@ static const struct
 #define EXTRA_LOOP_DECLS       , int *statep
 #define INIT_PARAMS            int set = *statep & CURRENT_SEL_MASK;         \
                                uint32_t lasttwo = *statep >> 6
+#define REINIT_PARAMS          do                                            \
+                                 {                                           \
+                                   set = *statep & CURRENT_SEL_MASK;         \
+                                   lasttwo = *statep >> 6;                   \
+                                 }                                           \
+                               while (0)
 #define UPDATE_PARAMS          *statep = set | (lasttwo << 6)
 #include <iconv/loop.c>
 
index a9612e9..e14b796 100644 (file)
@@ -715,8 +715,7 @@ static const cvlist_t conversion_lists[4] =
               list that depends on the current language tag.  */             \
            cvlist_t conversion_list;                                         \
            unsigned char buf[2];                                             \
-                                                                             \
-           result = __GCONV_ILLEGAL_INPUT;                                   \
+           int res = __GCONV_ILLEGAL_INPUT;                                  \
                                                                              \
            if (var == iso2022jp2)                                            \
              conversion_list = conversion_lists[tag >> 8];                   \
@@ -735,7 +734,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 3 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -746,13 +745,13 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 3 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = ESC;                                        \
                      *outptr++ = 'N';                                        \
                      *outptr++ = ch - 0x80;                                  \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -774,7 +773,7 @@ static const cvlist_t conversion_lists[4] =
                                  if (__builtin_expect (outptr + 3 > outend,  \
                                                        0))                   \
                                    {                                         \
-                                     result = __GCONV_FULL_OUTPUT;           \
+                                     res = __GCONV_FULL_OUTPUT;              \
                                      break;                                  \
                                    }                                         \
                                  *outptr++ = ESC;                            \
@@ -785,13 +784,13 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                              if (__builtin_expect (outptr + 3 > outend, 0))  \
                                {                                             \
-                                 result = __GCONV_FULL_OUTPUT;               \
+                                 res = __GCONV_FULL_OUTPUT;                  \
                                  break;                                      \
                                }                                             \
                              *outptr++ = ESC;                                \
                              *outptr++ = 'N';                                \
                              *outptr++ = res;                                \
-                             result = __GCONV_OK;                            \
+                             res = __GCONV_OK;                               \
                              break;                                          \
                            }                                                 \
                        }                                                     \
@@ -810,7 +809,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 3 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -821,11 +820,11 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 1 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0];                                     \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -837,7 +836,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 3 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -848,12 +847,12 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 2 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0];                                     \
                      *outptr++ = buf[1];                                     \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -869,7 +868,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 4 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -881,12 +880,12 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 2 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0];                                     \
                      *outptr++ = buf[1];                                     \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -903,7 +902,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 3 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -914,12 +913,12 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 2 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0];                                     \
                      *outptr++ = buf[1];                                     \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -936,7 +935,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 4 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -948,12 +947,12 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 2 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0];                                     \
                      *outptr++ = buf[1];                                     \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -972,7 +971,7 @@ static const cvlist_t conversion_lists[4] =
                        {                                                     \
                          if (__builtin_expect (outptr + 3 > outend, 0))      \
                            {                                                 \
-                             result = __GCONV_FULL_OUTPUT;                   \
+                             res = __GCONV_FULL_OUTPUT;                      \
                              break;                                          \
                            }                                                 \
                          *outptr++ = ESC;                                    \
@@ -983,11 +982,11 @@ static const cvlist_t conversion_lists[4] =
                                                                              \
                      if (__builtin_expect (outptr + 1 > outend, 0))          \
                        {                                                     \
-                         result = __GCONV_FULL_OUTPUT;                       \
+                         res = __GCONV_FULL_OUTPUT;                          \
                          break;                                              \
                        }                                                     \
                      *outptr++ = buf[0] - 0x80;                              \
-                     result = __GCONV_OK;                                    \
+                     res = __GCONV_OK;                                       \
                      break;                                                  \
                    }                                                         \
                                                                              \
@@ -996,13 +995,16 @@ static const cvlist_t conversion_lists[4] =
                default:                                                      \
                  abort ();                                                   \
                }                                                             \
-           while (result == __GCONV_ILLEGAL_INPUT                            \
+           while (res == __GCONV_ILLEGAL_INPUT                               \
                   && (conversion_list = CVLIST_REST (conversion_list)) != 0);\
                                                                              \
-           if (result == __GCONV_FULL_OUTPUT)                                \
-             break;                                                          \
+           if (res == __GCONV_FULL_OUTPUT)                                   \
+             {                                                               \
+               result = res;                                                 \
+               break;                                                        \
+             }                                                               \
                                                                              \
-           if (result == __GCONV_ILLEGAL_INPUT)                              \
+           if (res == __GCONV_ILLEGAL_INPUT)                                 \
              {                                                               \
                STANDARD_TO_LOOP_ERR_HANDLER (4);                             \
              }                                                               \
@@ -1017,6 +1019,13 @@ static const cvlist_t conversion_lists[4] =
 #define INIT_PARAMS            int set = *setp & CURRENT_SEL_MASK;           \
                                int set2 = *setp & CURRENT_ASSIGN_MASK;       \
                                int tag = *setp & CURRENT_TAG_MASK;
+#define REINIT_PARAMS          do                                            \
+                                 {                                           \
+                                   set = *setp & CURRENT_SEL_MASK;           \
+                                   set2 = *setp & CURRENT_ASSIGN_MASK;       \
+                                   tag = *setp & CURRENT_TAG_MASK;           \
+                                 }                                           \
+                               while (0)
 #define UPDATE_PARAMS          *setp = set | set2 | tag
 #include <iconv/loop.c>
 
index 6439b0a..556a33d 100644 (file)
@@ -1,5 +1,6 @@
 /* Conversion module for ISO-2022-KR.
-   Copyright (C) 1998, 1999, 2000-2002, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000-2002, 2007, 2008
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -261,6 +262,7 @@ enum
 #define LOOP_NEED_FLAGS
 #define EXTRA_LOOP_DECLS       , int *setp
 #define INIT_PARAMS            int set = *setp
+#define REINIT_PARAMS          set = *setp
 #define UPDATE_PARAMS          *setp = set
 #include <iconv/loop.c>
 
diff --git a/iconvdata/tst-iconv7.c b/iconvdata/tst-iconv7.c
new file mode 100644 (file)
index 0000000..a01e3d8
--- /dev/null
@@ -0,0 +1,61 @@
+#include <iconv.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+do_test (void)
+{
+  setlocale (LC_ALL, "de_DE.UTF-8");
+
+  iconv_t cd = iconv_open ("ISO-2022-JP//TRANSLIT", "");
+  if (cd == (iconv_t) -1)
+    {
+      puts ("iconv_open failed");
+      return 1;
+    }
+
+  char instr1[] = "\xc2\xa3\xe2\x82\xac\n";
+  const char expstr1[] = "\033$B!r\033(BEUR\n";
+  char outstr[32];
+  size_t inlen = sizeof (instr1);
+  size_t outlen = sizeof (outstr);
+  char *inptr = instr1;
+  char *outptr = outstr;
+  size_t r = iconv (cd, &inptr, &inlen, &outptr, &outlen);
+  if (r != 1
+      || inlen != 0
+      || outlen != sizeof (outstr) - sizeof (expstr1)
+      || memcmp (outstr, expstr1, sizeof (expstr1)) != 0)
+    {
+      puts ("wrong first conversion");
+      return 1;
+    }
+
+  char instr2[] = "\xe3\x88\xb1\n";
+  const char expstr2[] = "(\033$B3t\033(B)\n";
+  inlen = sizeof (instr2);
+  outlen = sizeof (outstr);
+  inptr = instr2;
+  outptr = outstr;
+  r = iconv (cd, &inptr, &inlen, &outptr, &outlen);
+  if (r != 1
+      || inlen != 0
+      || outlen != sizeof (outstr) - sizeof (expstr2)
+      || memcmp (outstr, expstr2, sizeof (expstr2)) != 0)
+    {
+      puts ("wrong second conversion");
+      return 1;
+    }
+
+  if (iconv_close (cd) != 0)
+    {
+      puts ("iconv_close failed");
+      return 1;
+    }
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index c14df27..c14351a 100644 (file)
@@ -1,5 +1,5 @@
 /* Define ISO C stdio on top of C++ iostreams.
-   Copyright (C) 1991,1994-2004,2005,2006,2007 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1994-2007, 2008 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
@@ -494,7 +494,7 @@ extern int __isoc99_vsscanf (__const char *__restrict __s,
                             __const char *__restrict __format,
                             _G_va_list __arg) __THROW;
 #   define vfscanf __isoc99_vfscanf
-#   define vscanf __isoc99_vsscanf
+#   define vscanf __isoc99_vscanf
 #   define vsscanf __isoc99_vsscanf
 #  endif
 # endif
index 5a3e8c8..2a35fc6 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       [BZ #5520]
+       * locales/ga_IE: Fix May, June, November and December entries in mon.
+
 2007-12-11  Ulrich Drepper  <drepper@redhat.com>
 
        * charmsp/HP-THAI8: New file.
index 8522fd3..6e95260 100644 (file)
@@ -101,14 +101,14 @@ mon         "<U0045><U0061><U006E><U00E1><U0069><U0072>";/
             "<U0046><U0065><U0061><U0062><U0068><U0072><U0061>";/
             "<U004D><U00E1><U0072><U0074><U0061>";/
             "<U0041><U0069><U0062><U0072><U0065><U00E1><U006E>";/
-            "<U004D><U00ED><U0020><U006E><U0061><U0020><U0042><U0065><U0061><U006C><U0074><U0061><U0069><U006E><U0065>";/
-            "<U004D><U0065><U0069><U0074><U0068>";/
+            "<U0042><U0065><U0061><U006C><U0074><U0061><U0069><U006E><U0065>";/
+            "<U004D><U0065><U0069><U0074><U0068><U0065><U0061><U006d><U0068>";/
             "<U0049><U00FA><U0069><U006C>";/
             "<U004C><U00FA><U006E><U0061><U0073><U0061>";/
             "<U004D><U0065><U00E1><U006E><U0020><U0046><U00F3><U006D><U0068><U0061><U0069><U0072>";/
             "<U0044><U0065><U0069><U0072><U0065><U0061><U0064><U0068><U0020><U0046><U00F3><U006D><U0068><U0061><U0069><U0072>";/
-            "<U004D><U00ED><U0020><U006E><U0061><U0020><U0053><U0061><U006D><U0068><U006E><U0061>";/
-            "<U004D><U00ED><U0020><U006E><U0061><U0020><U004E><U006F><U006C><U006C><U0061><U0067>"
+            "<U0053><U0061><U006D><U0068><U0061><U0069><U006E>";/
+            "<U004E><U006F><U006C><U006C><U0061><U0069><U0067>"
 d_t_fmt     "<U0025><U0061><U0020><U0025><U0064><U0020><U0025><U0062><U0020><U0025><U0059><U0020><U0025><U0054><U0020><U0025><U005A>"
 d_fmt       "<U0025><U0064><U002E><U0025><U006D><U002E><U0025><U0079>"
 t_fmt       "<U0025><U0054>"
index fc8a83c..e00eb0f 100644 (file)
@@ -1,5 +1,5 @@
 /* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 1996-2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1996-2006, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>
    and Doug Lea <dl@cs.oswego.edu>, 2001.
@@ -3553,9 +3553,10 @@ public_mALLOc(size_t bytes)
     /* Maybe the failure is due to running out of mmapped areas. */
     if(ar_ptr != &main_arena) {
       (void)mutex_unlock(&ar_ptr->mutex);
-      (void)mutex_lock(&main_arena.mutex);
-      victim = _int_malloc(&main_arena, bytes);
-      (void)mutex_unlock(&main_arena.mutex);
+      ar_ptr = &main_arena;
+      (void)mutex_lock(&ar_ptr->mutex);
+      victim = _int_malloc(ar_ptr, bytes);
+      (void)mutex_unlock(&ar_ptr->mutex);
     } else {
 #if USE_ARENAS
       /* ... or sbrk() has failed and there is still a chance to mmap() */
@@ -3760,24 +3761,28 @@ public_mEMALIGn(size_t alignment, size_t bytes)
   if(!ar_ptr)
     return 0;
   p = _int_memalign(ar_ptr, alignment, bytes);
-  (void)mutex_unlock(&ar_ptr->mutex);
   if(!p) {
     /* Maybe the failure is due to running out of mmapped areas. */
     if(ar_ptr != &main_arena) {
-      (void)mutex_lock(&main_arena.mutex);
-      p = _int_memalign(&main_arena, alignment, bytes);
-      (void)mutex_unlock(&main_arena.mutex);
+      (void)mutex_unlock(&ar_ptr->mutex);
+      ar_ptr = &main_arena;
+      (void)mutex_lock(&ar_ptr->mutex);
+      p = _int_memalign(ar_ptr, alignment, bytes);
+      (void)mutex_unlock(&ar_ptr->mutex);
     } else {
 #if USE_ARENAS
       /* ... or sbrk() has failed and there is still a chance to mmap() */
-      ar_ptr = arena_get2(ar_ptr->next ? ar_ptr : 0, bytes);
+      mstate prev = ar_ptr->next ? ar_ptr : 0;
+      (void)mutex_unlock(&ar_ptr->mutex);
+      ar_ptr = arena_get2(prev, bytes);
       if(ar_ptr) {
         p = _int_memalign(ar_ptr, alignment, bytes);
         (void)mutex_unlock(&ar_ptr->mutex);
       }
 #endif
     }
-  }
+  } else
+    (void)mutex_unlock(&ar_ptr->mutex);
   assert(!p || chunk_is_mmapped(mem2chunk(p)) ||
         ar_ptr == arena_for_chunk(mem2chunk(p)));
   return p;
index e3fb8df..ddb451f 100644 (file)
@@ -1,3 +1,11 @@
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthread-errnos.sym: Add EOVERFLOW.
+       * sysdeps/unix/sysv/linux/structsem.sym: Add SEM_VALUE_MAX.
+       * sysdeps/unix/sysv/linux/sem_post.c: Don't overflow value field.
+       * sysdeps/unix/sysv/linux/i386/i486/sem_post.S: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/sem_post.S: Likewise.
+
 2007-12-14  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/x86_64/pthreaddef.h (ARCH_RETRY_MMAP): Take additional
index 2bb4d0d..0975b7a 100644 (file)
@@ -8,5 +8,6 @@ EDEADLK         EDEADLK
 EINTR          EINTR
 EINVAL         EINVAL
 ENOSYS         ENOSYS
+EOVERFLOW      EOVERFLOW
 ETIMEDOUT      ETIMEDOUT
 EWOULDBLOCK    EWOULDBLOCK
index ac045b6..2edcdde 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -34,12 +34,21 @@ __new_sem_post:
 
        movl    8(%esp), %ebx
 
+#if VALUE == 0
+       movl    (%ebx), %eax
+#else
+       movl    VALUE(%ebx), %eax
+#endif
+0:     cmpl    $SEM_VALUE_MAX, %eax
+       je      3f
+       leal    1(%eax), %edx
        LOCK
 #if VALUE == 0
-       addl    $1, (%ebx)
+       cmpxchgl %edx, (%ebx)
 #else
-       addl    $1, VALUE(%ebx)
+       cmpxchgl %edx, VALUE(%ebx)
 #endif
+       jnz     0b
 
        cmpl    $0, NWAITERS(%ebx)
        je      2f
@@ -82,6 +91,32 @@ __new_sem_post:
        orl     $-1, %eax
        popl    %ebx
        ret
+
+3:
+#ifdef PIC
+       call    __i686.get_pc_thunk.bx
+#else
+       movl    $5f, %ebx
+5:
+#endif
+       addl    $_GLOBAL_OFFSET_TABLE_, %ebx
+#if USE___THREAD
+# ifdef NO_TLS_DIRECT_SEG_REFS
+       movl    errno@gotntpoff(%ebx), %edx
+       addl    %gs:0, %edx
+       movl    $EOVERFLOW, (%edx)
+# else
+       movl    errno@gotntpoff(%ebx), %edx
+       movl    $EOVERFLOW, %gs:(%edx)
+# endif
+#else
+       call    __errno_location@plt
+       movl    $EOVERFLOW, (%eax)
+#endif
+
+       orl     $-1, %eax
+       popl    %ebx
+       ret
        .size   __new_sem_post,.-__new_sem_post
        versioned_symbol(libpthread, __new_sem_post, sem_post, GLIBC_2_1)
 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
index 25b676f..58b226f 100644 (file)
@@ -1,5 +1,5 @@
 /* sem_post -- post to a POSIX semaphore.  Generic futex-using version.
-   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -31,7 +31,18 @@ __new_sem_post (sem_t *sem)
 {
   struct new_sem *isem = (struct new_sem *) sem;
 
-  int nr = atomic_increment_val (&isem->value);
+  __typeof (isem->value) cur;
+  do
+    {
+      cur = isem->value;
+      if (isem->value == SEM_VALUE_MAX)
+       {
+         __set_errno (EOVERFLOW);
+         return -1;
+       }
+    }
+  while (atomic_compare_and_exchange_bool_acq (&isem->value, cur + 1, cur));
+
   atomic_full_barrier ();
   if (isem->nwaiters > 0)
     {
index 4f32c68..0e2a15f 100644 (file)
@@ -1,3 +1,4 @@
+#include <limits.h>
 #include <stddef.h>
 #include <sched.h>
 #include <bits/pthreadtypes.h>
@@ -8,3 +9,4 @@
 VALUE          offsetof (struct new_sem, value)
 PRIVATE                offsetof (struct new_sem, private)
 NWAITERS       offsetof (struct new_sem, nwaiters)
+SEM_VALUE_MAX  SEM_VALUE_MAX
index adbbcdf..b4014c6 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
        .type   sem_post,@function
        .align  16
 sem_post:
+#if VALUE == 0
+       movl    (%rdi), %eax
+#else
+       movl    VALUE(%rdi), %eax
+#endif
+0:     cmpl    $SEM_VALUE_MAX, %eax
+       je      3f
+       leal    1(%eax), %esi
        LOCK
 #if VALUE == 0
-       addl    $1, (%rdi)
+       cmpxchgl %esi, (%rdi)
 #else
-       addl    $1, VALUE(%rdi)
+       cmpxchgl %esi, VALUE(%rdi)
 #endif
+       jnz     0b
 
        cmpq    $0, NWAITERS(%rdi)
        je      2f
@@ -54,13 +63,28 @@ sem_post:
 
 1:
 #if USE___THREAD
-       movq    errno@gottpoff(%rip), %rdx
-       movl    $EINVAL, %fs:(%rdx)
+       movl    $EINVAL, %eax
 #else
        callq   __errno_location@plt
-       movl    $EINVAL, (%rax)
+       movl    $EINVAL, %edx
 #endif
+       jmp     4f
 
+3:
+#if USE___THREAD
+       movl    $EOVERFLOW, %eax
+#else
+       callq   __errno_location@plt
+       movl    $EOVERFLOW, %edx
+#endif
+
+4:
+#if USE___THREAD
+       movq    errno@gottpoff(%rip), %rdx
+       movl    %eax, %fs:(%rdx)
+#else
+       movl    %edx, (%rax)
+#endif
        orl     $-1, %eax
        retq
        .size   sem_post,.-sem_post
index abd84b9..8140e96 100644 (file)
@@ -1,5 +1,6 @@
 /* Inner loops of cache daemon.
-   Copyright (C) 1998-2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1998-2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -1297,7 +1298,7 @@ cannot change to old working directory: %s; disabling paranoia mode"),
 
   /* Synchronize memory.  */
   for (int cnt = 0; cnt < lastdb; ++cnt)
-    if (!dbs[cnt].enabled)
+    if (dbs[cnt].enabled)
       {
        /* Make sure nobody keeps using the database.  */
        dbs[cnt].head->timestamp = 0;
index d29f072..56c0277 100644 (file)
@@ -100,31 +100,32 @@ do_test (void)
 
 
   struct sort_result results[2];
+  size_t order[2];
 
   results[0].dest_addr = &ai1;
   results[0].got_source_addr = true;
   results[0].source_addr_len = sizeof (so1);
   results[0].source_addr_flags = 0;
-  results[0].service_order = 0;
   results[0].prefixlen = 16;
   results[0].index = 0;
   memcpy (&results[0].source_addr, &so1, sizeof (so1));
+  order[0] = 0;
 
   results[1].dest_addr = &ai2;
   results[1].got_source_addr = true;
   results[1].source_addr_len = sizeof (so2);
   results[1].source_addr_flags = 0;
-  results[1].service_order = 1;
   results[1].prefixlen = 16;
   results[1].index = 0;
   memcpy (&results[1].source_addr, &so2, sizeof (so2));
+  order[1] = 1;
 
 
   struct sort_result_combo combo = { .results = results, .nresults = 2 };
-  qsort_r (results, 2, sizeof (results[0]), rfc3484_sort, &combo);
+  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
 
   int result = 0;
-  if (results[0].dest_addr->ai_family == AF_INET6)
+  if (results[order[0]].dest_addr->ai_family == AF_INET6)
     {
       puts ("wrong order in first test");
       result |= 1;
@@ -136,24 +137,24 @@ do_test (void)
   results[1].got_source_addr = true;
   results[1].source_addr_len = sizeof (so1);
   results[1].source_addr_flags = 0;
-  results[1].service_order = 1;
   results[1].prefixlen = 16;
   results[1].index = 0;
   memcpy (&results[1].source_addr, &so1, sizeof (so1));
+  order[1] = 1;
 
   results[0].dest_addr = &ai2;
   results[0].got_source_addr = true;
   results[0].source_addr_len = sizeof (so2);
   results[0].source_addr_flags = 0;
-  results[0].service_order = 0;
   results[0].prefixlen = 16;
   results[0].index = 0;
   memcpy (&results[0].source_addr, &so2, sizeof (so2));
+  order[0] = 0;
 
 
-  qsort_r (results, 2, sizeof (results[0]), rfc3484_sort, &combo);
+  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
 
-  if (results[0].dest_addr->ai_family == AF_INET6)
+  if (results[order[0]].dest_addr->ai_family == AF_INET6)
     {
       puts ("wrong order in second test");
       result |= 1;
index 4aede81..616722e 100644 (file)
@@ -66,6 +66,7 @@ struct sockaddr_in addrs[] =
 #define naddrs (sizeof (addrs) / sizeof (addrs[0]))
 static struct addrinfo ais[naddrs];
 static struct sort_result results[naddrs];
+static size_t order[naddrs];
 
 static const int expected[naddrs] =
   {
@@ -111,18 +112,19 @@ do_test (void)
       memcpy(&results[i].source_addr, &so, sizeof (so));
       results[i].source_addr_len = sizeof (so);
       results[i].source_addr_flags = 0;
-      results[i].service_order = i;
       results[i].prefixlen = 8;
       results[i].index = 0;
+
+      order[i] = i;
     }
 
   struct sort_result_combo combo = { .results = results, .nresults = naddrs };
-  qsort_r (results, naddrs, sizeof (results[0]), rfc3484_sort, &combo);
+  qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
 
   int result = 0;
   for (int i = 0; i < naddrs; ++i)
     {
-      struct in_addr addr = ((struct sockaddr_in *) (results[i].dest_addr->ai_addr))->sin_addr;
+      struct in_addr addr = ((struct sockaddr_in *) (results[order[i]].dest_addr->ai_addr))->sin_addr;
 
       int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
                         sizeof (struct in_addr));
index fe06255..4df5b29 100644 (file)
@@ -64,6 +64,7 @@ struct sockaddr_in addrs[] =
 #define naddrs (sizeof (addrs) / sizeof (addrs[0]))
 static struct addrinfo ais[naddrs];
 static struct sort_result results[naddrs];
+static size_t order[naddrs];
 
 static int expected[naddrs] =
   {
@@ -100,18 +101,19 @@ do_test (void)
       memcpy(&results[i].source_addr, &so, sizeof (so));
       results[i].source_addr_len = sizeof (so);
       results[i].source_addr_flags = 0;
-      results[i].service_order = i;
       results[i].prefixlen = 8;
       results[i].index = 0;
+
+      order[i] = i;
     }
 
   struct sort_result_combo combo = { .results = results, .nresults = naddrs };
-  qsort_r (results, naddrs, sizeof (results[0]), rfc3484_sort, &combo);
+  qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
 
   int result = 0;
   for (int i = 0; i < naddrs; ++i)
     {
-      struct in_addr addr = ((struct sockaddr_in *) (results[i].dest_addr->ai_addr))->sin_addr;
+      struct in_addr addr = ((struct sockaddr_in *) (results[order[i]].dest_addr->ai_addr))->sin_addr;
 
       int here = memcmp (&addr, &addrs[expected[i]].sin_addr,
                         sizeof (struct in_addr));
index e72ab5b..736c562 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007, 2008 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
@@ -68,7 +68,8 @@ tests         := tst-strtol tst-strtod testmb testrand testsort testdiv   \
                   tst-limits tst-rand48 bug-strtod tst-setcontext          \
                   test-a64l tst-qsort tst-system testmb2 bug-strtod2       \
                   tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
-                  tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2
+                  tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2       \
+                  tst-makecontext2
 
 include ../Makeconfig
 
@@ -106,6 +107,7 @@ endif
 
 CFLAGS-tst-bsearch.c = $(stack-align-test-flags)
 CFLAGS-tst-qsort.c = $(stack-align-test-flags)
+CFLAGS-tst-makecontext2.c = $(stack-align-test-flags)
 
 include ../Rules
 
diff --git a/stdlib/tst-makecontext2.c b/stdlib/tst-makecontext2.c
new file mode 100644 (file)
index 0000000..903ccf6
--- /dev/null
@@ -0,0 +1,80 @@
+/* Copyright (C) 2008 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 <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ucontext.h>
+#include <tst-stack-align.h>
+
+ucontext_t ucp, ucp2;
+char st1[262144] __attribute__((aligned (16)));
+
+void
+cf (int i, int j)
+{
+  if (i != 78 || j != 274)
+    {
+      printf ("i %d j %d\n", i, j);
+      exit (1);
+    }
+  else if (TEST_STACK_ALIGN ())
+    {
+      puts ("insufficiently aligned stack");
+      exit (2);
+    }
+}
+
+int
+do_test (void)
+{
+  for (size_t j = 32; j < 64; j += sizeof (long))
+    {
+      if (getcontext (&ucp) != 0)
+       {
+         if (errno == ENOSYS)
+           {
+             puts ("context handling not supported");
+             return 0;
+           }
+
+         puts ("getcontext failed");
+         return 1;
+       }
+      ucp.uc_link = &ucp2;
+      ucp.uc_stack.ss_sp = st1;
+      ucp.uc_stack.ss_size = sizeof (st1) - j;
+      memset (&st1[sizeof (st1) - j], 0x55, j);
+      makecontext (&ucp, (void (*) (void)) cf, 2, 78, 274);
+      if (swapcontext (&ucp2, &ucp) != 0)
+       {
+         puts ("setcontext failed");
+         return 1;
+       }
+
+      for (size_t i = j; i > 0; i--)
+       if (st1[sizeof (st1) - j + i - 1] != 0x55)
+         { printf ("fail %zd %zd\n", i, j); break; }
+    }
+
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 6446b32..c15796f 100644 (file)
@@ -60,36 +60,21 @@ static char *auth_errmsg (enum auth_stat stat) internal_function;
 static char *buf;
 #endif
 
-static char *
-_buf (void)
-{
-  if (buf == NULL)
-    buf = (char *) malloc (256);
-  return buf;
-}
-
 /*
  * Print reply error info
  */
 char *
 clnt_sperror (CLIENT * rpch, const char *msg)
 {
-  char chrbuf[1024];
   struct rpc_err e;
-  char *err;
-  char *str = _buf ();
-  char *strstart = str;
-  int len;
-
-  if (str == NULL)
-    return NULL;
   CLNT_GETERR (rpch, &e);
 
-  len = sprintf (str, "%s: ", msg);
-  str += len;
-
-  str = stpcpy (str, clnt_sperrno (e.re_status));
+  const char *errstr = clnt_sperrno (e.re_status);
 
+  char chrbuf[1024];
+  char *str;
+  char *tmpstr;
+  int res;
   switch (e.re_status)
     {
     case RPC_SUCCESS:
@@ -105,50 +90,52 @@ clnt_sperror (CLIENT * rpch, const char *msg)
     case RPC_PMAPFAILURE:
     case RPC_PROGNOTREGISTERED:
     case RPC_FAILED:
+      res = __asprintf (&str, "%s: %s\n", msg, errstr);
       break;
 
     case RPC_CANTSEND:
     case RPC_CANTRECV:
-      len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno,
-                                                       chrbuf, sizeof chrbuf));
-      str += len;
+      res = __asprintf (&str, "%s: %s; errno = %s\n",
+                       msg, errstr, __strerror_r (e.re_errno,
+                                                  chrbuf, sizeof chrbuf));
       break;
 
     case RPC_VERSMISMATCH:
-      len= sprintf (str, _("; low version = %lu, high version = %lu"),
-                   e.re_vers.low, e.re_vers.high);
-      str += len;
+      res = __asprintf (&str,
+                       _("%s: %s; low version = %lu, high version = %lu"),
+                       msg, errstr, e.re_vers.low, e.re_vers.high);
       break;
 
     case RPC_AUTHERROR:
-      err = auth_errmsg (e.re_why);
-      str = stpcpy (str, _ ("; why = "));
-      if (err != NULL)
-       {
-         str = stpcpy (str, err);
-       }
+      tmpstr = auth_errmsg (e.re_why);
+      if (tmpstr != NULL)
+       res = __asprintf (&str, _("%s: %s; why = %s\n"), msg, errstr, tmpstr);
       else
-       {
-         len = sprintf (str, _("(unknown authentication error - %d)"),
-                        (int) e.re_why);
-         str += len;
-       }
+       res = __asprintf (&str, _("\
+%s: %s; why = (unknown authentication error - %d)\n"),
+                         msg, errstr, (int) e.re_why);
       break;
 
     case RPC_PROGVERSMISMATCH:
-      len = sprintf (str, _("; low version = %lu, high version = %lu"),
-                    e.re_vers.low, e.re_vers.high);
-      str += len;
+      res = __asprintf (&str,
+                       _("%s: %s; low version = %lu, high version = %lu"),
+                       msg, errstr, e.re_vers.low, e.re_vers.high);
       break;
 
     default:                   /* unknown */
-      len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
-      str += len;
+      res = __asprintf (&str, "%s: %s; s1 = %lu, s2 = %lu",
+                       msg, errstr, e.re_lb.s1, e.re_lb.s2);
       break;
     }
-  *str = '\n';
-  *++str = '\0';
-  return (strstart);
+
+  if (res < 0)
+    return NULL;
+
+  char *oldbuf = buf;
+  buf = str;
+  free (oldbuf);
+
+  return str;
 }
 libc_hidden_def (clnt_sperror)
 
@@ -291,35 +278,36 @@ clnt_perrno (enum clnt_stat num)
 char *
 clnt_spcreateerror (const char *msg)
 {
-  char chrbuf[1024];
-  char *str = _buf ();
-  char *cp;
-  int len;
-  struct rpc_createerr *ce;
+  struct rpc_createerr *ce = &get_rpc_createerr ();
 
-  if (str == NULL)
-    return NULL;
-  ce = &get_rpc_createerr ();
-  len = sprintf (str, "%s: ", msg);
-  cp = str + len;
-  cp = stpcpy (cp, clnt_sperrno (ce->cf_stat));
+  char chrbuf[1024];
+  const char *connector = "";
+  const char *errstr = "";
   switch (ce->cf_stat)
     {
     case RPC_PMAPFAILURE:
-      cp = stpcpy (stpcpy (cp, " - "),
-                  clnt_sperrno (ce->cf_error.re_status));
+      connector = " - ";
+      errstr = clnt_sperrno (ce->cf_error.re_status);
       break;
 
     case RPC_SYSTEMERROR:
-      cp = stpcpy (stpcpy (cp, " - "),
-                  __strerror_r (ce->cf_error.re_errno,
-                                chrbuf, sizeof chrbuf));
+      connector = " - ";
+      errstr = __strerror_r (ce->cf_error.re_errno, chrbuf, sizeof chrbuf);
       break;
+
     default:
       break;
     }
-  *cp = '\n';
-  *++cp = '\0';
+
+  char *str;
+  if (__asprintf (&str, "%s: %s%s%s\n",
+                 msg, clnt_sperrno (ce->cf_stat), connector, errstr) < 0)
+    return NULL;
+
+  char *oldbuf = buf;
+  buf = str;
+  free (oldbuf);
+
   return str;
 }
 libc_hidden_def (clnt_spcreateerror)
index 91e94c2..7a9cc9d 100644 (file)
@@ -29,6 +29,8 @@ __rpc_thread_destroy (void)
                free (tvp->svcraw_private_s);
                free (tvp->authdes_cache_s);
                free (tvp->authdes_lru_s);
+               free (tvp->svc_xports_s);
+               free (tvp->svc_pollfd_s);
                if (tvp != &__libc_tsd_RPC_VARS_mem)
                        free (tvp);
                __libc_tsd_set (RPC_VARS, NULL);
index e8f4099..8746725 100644 (file)
@@ -997,8 +997,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
 struct sort_result
 {
   struct addrinfo *dest_addr;
-  struct sockaddr_storage source_addr;
-  size_t service_order;
+  /* Using sockaddr_storage is for now overkill.  We only support IPv4
+     and IPv6 so far.  If this changes at some point we can adjust the
+     type here.  */
+  struct sockaddr_in6 source_addr;
   uint8_t source_addr_len;
   bool got_source_addr;
   uint8_t source_addr_flags;
@@ -1047,13 +1049,11 @@ static const struct scopeentry *scopes;
 
 
 static int
-get_scope (const struct sockaddr_storage *ss)
+get_scope (const struct sockaddr_in6 *in6)
 {
   int scope;
-  if (ss->ss_family == PF_INET6)
+  if (in6->sin6_family == PF_INET6)
     {
-      const struct sockaddr_in6 *in6 = (const struct sockaddr_in6 *) ss;
-
       if (! IN6_IS_ADDR_MULTICAST (&in6->sin6_addr))
        {
          if (IN6_IS_ADDR_LINKLOCAL (&in6->sin6_addr))
@@ -1067,9 +1067,9 @@ get_scope (const struct sockaddr_storage *ss)
       else
        scope = in6->sin6_addr.s6_addr[1] & 0xf;
     }
-  else if (ss->ss_family == PF_INET)
+  else if (in6->sin6_family == PF_INET)
     {
-      const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+      const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
 
       size_t cnt = 0;
       while (1)
@@ -1179,18 +1179,15 @@ static const struct prefixentry default_precedence[] =
 
 
 static int
-match_prefix (const struct sockaddr_storage *ss,
+match_prefix (const struct sockaddr_in6 *in6,
              const struct prefixentry *list, int default_val)
 {
   int idx;
   struct sockaddr_in6 in6_mem;
-  const struct sockaddr_in6 *in6;
 
-  if (ss->ss_family == PF_INET6)
-    in6 = (const struct sockaddr_in6 *) ss;
-  else if (ss->ss_family == PF_INET)
+  if (in6->sin6_family == PF_INET)
     {
-      const struct sockaddr_in *in = (const struct sockaddr_in *) ss;
+      const struct sockaddr_in *in = (const struct sockaddr_in *) in6;
 
       /* Convert to IPv6 address.  */
       in6_mem.sin6_family = PF_INET6;
@@ -1209,7 +1206,7 @@ match_prefix (const struct sockaddr_storage *ss,
 
       in6 = &in6_mem;
     }
-  else
+  else if (in6->sin6_family != PF_INET6)
     return default_val;
 
   for (idx = 0; ; ++idx)
@@ -1241,18 +1238,18 @@ match_prefix (const struct sockaddr_storage *ss,
 
 
 static int
-get_label (const struct sockaddr_storage *ss)
+get_label (const struct sockaddr_in6 *in6)
 {
   /* XXX What is a good default value?  */
-  return match_prefix (ss, labels, INT_MAX);
+  return match_prefix (in6, labels, INT_MAX);
 }
 
 
 static int
-get_precedence (const struct sockaddr_storage *ss)
+get_precedence (const struct sockaddr_in6 *in6)
 {
   /* XXX What is a good default value?  */
-  return match_prefix (ss, precedence, 0);
+  return match_prefix (in6, precedence, 0);
 }
 
 
@@ -1272,9 +1269,11 @@ fls (uint32_t a)
 static int
 rfc3484_sort (const void *p1, const void *p2, void *arg)
 {
-  const struct sort_result *a1 = (const struct sort_result *) p1;
-  const struct sort_result *a2 = (const struct sort_result *) p2;
+  const size_t idx1 = *(const size_t *) p1;
+  const size_t idx2 = *(const size_t *) p2;
   struct sort_result_combo *src = (struct sort_result_combo *) arg;
+  struct sort_result *a1 = &src->results[idx1];
+  struct sort_result *a2 = &src->results[idx2];
 
   /* Rule 1: Avoid unusable destinations.
      We have the got_source_addr flag set if the destination is reachable.  */
@@ -1287,10 +1286,10 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
   /* Rule 2: Prefer matching scope.  Only interesting if both
      destination addresses are IPv6.  */
   int a1_dst_scope
-    = get_scope ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+    = get_scope ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
 
   int a2_dst_scope
-    = get_scope ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+    = get_scope ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
 
   if (a1->got_source_addr)
     {
@@ -1330,11 +1329,11 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
   if (a1->got_source_addr)
     {
       int a1_dst_label
-       = get_label ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+       = get_label ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
       int a1_src_label = get_label (&a1->source_addr);
 
       int a2_dst_label
-       = get_label ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+       = get_label ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
       int a2_src_label = get_label (&a2->source_addr);
 
       if (a1_dst_label == a1_src_label && a2_dst_label != a2_src_label)
@@ -1346,9 +1345,9 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
 
   /* Rule 6: Prefer higher precedence.  */
   int a1_prec
-    = get_precedence ((struct sockaddr_storage *) a1->dest_addr->ai_addr);
+    = get_precedence ((struct sockaddr_in6 *) a1->dest_addr->ai_addr);
   int a2_prec
-    = get_precedence ((struct sockaddr_storage *) a2->dest_addr->ai_addr);
+    = get_precedence ((struct sockaddr_in6 *) a2->dest_addr->ai_addr);
 
   if (a1_prec > a2_prec)
     return -1;
@@ -1364,27 +1363,54 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
         (most?) cases.  */
       if (a1->index != a2->index)
        {
-         if (a1->native == -1 || a2->native == -1)
+         int a1_native = a1->native;
+         int a2_native = a2->native;
+
+         if (a1_native == -1 || a2_native == -1)
            {
-             /* If we do not have the information use 'native' as the
-                default.  */
-             int a1_native = 0;
-             int a2_native = 0;
-             __check_native (a1->index, &a1_native, a2->index, &a2_native);
+             uint32_t a1_index;
+             if (a1_native == -1)
+               {
+                 /* If we do not have the information use 'native' as
+                    the default.  */
+                 a1_native = 0;
+                 a1_index = a1->index;
+               }
+             else
+               a1_index = 0xffffffffu;
+
+             uint32_t a2_index;
+             if (a2_native == -1)
+               {
+                 /* If we do not have the information use 'native' as
+                    the default.  */
+                 a2_native = 0;
+                 a2_index = a2->index;
+               }
+             else
+               a2_index = 0xffffffffu;
+
+             __check_native (a1_index, &a1_native, a2_index, &a2_native);
 
              /* Fill in the results in all the records.  */
              for (int i = 0; i < src->nresults; ++i)
-               {
-                 if (a1->native == -1 && src->results[i].index == a1->index)
+               if (src->results[i].index == a1_index)
+                 {
+                   assert (src->results[i].native == -1
+                           || src->results[i].native == a1_native);
                    src->results[i].native = a1_native;
-                 if (a2->native == -1 && src->results[i].index == a2->index)
+                 }
+               else if (src->results[i].index == a2_index)
+                 {
+                   assert (src->results[i].native == -1
+                           || src->results[i].native == a2_native);
                    src->results[i].native = a2_native;
-               }
+                 }
            }
 
-         if (a1->native && !a2->native)
+         if (a1_native && !a2_native)
            return -1;
-         if (!a1->native && a2->native)
+         if (!a1_native && a2_native)
            return 1;
        }
     }
@@ -1406,8 +1432,8 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
 
       if (a1->dest_addr->ai_family == PF_INET)
        {
-         assert (a1->source_addr.ss_family == PF_INET);
-         assert (a2->source_addr.ss_family == PF_INET);
+         assert (a1->source_addr.sin6_family == PF_INET);
+         assert (a2->source_addr.sin6_family == PF_INET);
 
          /* Outside of subnets, as defined by the network masks,
             common address prefixes for IPv4 addresses make no sense.
@@ -1437,8 +1463,8 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
        }
       else if (a1->dest_addr->ai_family == PF_INET6)
        {
-         assert (a1->source_addr.ss_family == PF_INET6);
-         assert (a2->source_addr.ss_family == PF_INET6);
+         assert (a1->source_addr.sin6_family == PF_INET6);
+         assert (a2->source_addr.sin6_family == PF_INET6);
 
          struct sockaddr_in6 *in1_dst;
          struct sockaddr_in6 *in1_src;
@@ -1478,7 +1504,7 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
      compare with the value indicating the order in which the entries
      have been received from the services.  NB: no two entries can have
      the same order so the test will never return zero.  */
-  return a1->service_order < a2->service_order ? -1 : 1;
+  return idx1 < idx2 ? -1 : 1;
 }
 
 
@@ -2100,6 +2126,7 @@ getaddrinfo (const char *name, const char *service,
       __libc_once (once, gaiconf_init);
       /* Sort results according to RFC 3484.  */
       struct sort_result results[nresults];
+      size_t order[nresults];
       struct addrinfo *q;
       struct addrinfo *last = NULL;
       char *canonname = NULL;
@@ -2115,8 +2142,8 @@ getaddrinfo (const char *name, const char *service,
       for (i = 0, q = p; q != NULL; ++i, last = q, q = q->ai_next)
        {
          results[i].dest_addr = q;
-         results[i].service_order = i;
          results[i].native = -1;
+         order[i] = i;
 
          /* If we just looked up the address for a different
             protocol, reuse the result.  */
@@ -2255,16 +2282,16 @@ getaddrinfo (const char *name, const char *service,
          __libc_lock_lock (lock);
          if (old_once && gaiconf_reload_flag)
            gaiconf_reload ();
-         qsort_r (results, nresults, sizeof (results[0]), rfc3484_sort, &src);
+         qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
          __libc_lock_unlock (lock);
        }
       else
-       qsort_r (results, nresults, sizeof (results[0]), rfc3484_sort, &src);
+       qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
 
       /* Queue the results up as they come out of sorting.  */
-      q = p = results[0].dest_addr;
+      q = p = results[order[0]].dest_addr;
       for (i = 1; i < nresults; ++i)
-       q = q->ai_next = results[i].dest_addr;
+       q = q->ai_next = results[order[i]].dest_addr;
       q->ai_next = NULL;
 
       /* Fill in the canonical name into the new first entry.  */
index 89be117..ad23405 100644 (file)
@@ -1,5 +1,5 @@
 /* Create new context.
-   Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2005, 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
 
@@ -41,13 +41,15 @@ ENTRY(__makecontext)
        movl    12(%esp), %ecx
        movl    %ecx, oEBX(%eax)
 
-       /* Make room on the new stack for the parameters.  */
+       /* Make room on the new stack for the parameters.
+          Room for the arguments, return address (== L(exitcode)) and
+          oLINK pointer is needed.  One of the pointer sizes is subtracted
+          after aligning the stack.  */
        negl    %ecx
-       leal    -8(%edx,%ecx,4), %edx
+       leal    -4(%edx,%ecx,4), %edx
        negl    %ecx
 
        /* Align the stack.  */
-       addl    $16, %edx
        andl    $0xfffffff0, %edx
        subl    $4, %edx