summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog78
-rw-r--r--Makeconfig39
-rw-r--r--Makerules43
-rw-r--r--Rules2
-rw-r--r--hurd/Makefile2
-rw-r--r--locale/C-ctype.c146
-rw-r--r--locale/C-monetary.c18
-rw-r--r--locale/C-numeric.c2
-rw-r--r--locale/loadlocale.c11
-rw-r--r--locale/setlocale.c4
-rw-r--r--mach/Machrules28
-rw-r--r--mach/Makefile2
-rw-r--r--stdio/internals.c2
-rw-r--r--stdio/printf_fp.c9
-rw-r--r--stdio/vfscanf.c81
-rw-r--r--stdlib/Makefile2
-rw-r--r--stdlib/grouping.h123
-rw-r--r--stdlib/stdlib.h52
-rw-r--r--stdlib/strtod.c149
-rw-r--r--stdlib/strtol.c87
-rw-r--r--stdlib/wcstombs.c11
-rw-r--r--stdlib/wctomb.c2
-rw-r--r--sysdeps/generic/memchr.c4
-rw-r--r--sysdeps/mach/hurd/dirfd.c4
-rw-r--r--sysdeps/mach/hurd/euidaccess.c8
-rw-r--r--sysdeps/mach/hurd/i386/trampoline.c17
-rw-r--r--sysdeps/mach/hurd/opendir.c11
-rw-r--r--sysdeps/mach/hurd/readdir.c3
-rw-r--r--time/tzfile.c2
29 files changed, 658 insertions, 284 deletions
diff --git a/ChangeLog b/ChangeLog
index d73e47f0fd..cd8096b2f9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,83 @@
+Thu Mar 16 00:04:41 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* locale/C-ctype.c: New correct data generated by drepper.
+
+	* Rules: Don't use $(libc.a).
+
+	Parsing of grouped numbers contributed by Ulrich Drepper.
+	* stdlib/strtol.c (__strtol_internal): Renamed from strtol.  Take
+ 	new flag arg; if nonzero, parse locale-dependent thousands
+ 	grouping and interpret only the prefix that is correctly grouped.
+	(strtol): Define this to call _strtol_internal with zero for the flag.
+	Use a weak symbol for the definition.
+	* stdlib/strtod.c (strtod, __strtod_internal): Likewise.
+  	Check for the exponent of the number overflowing the float format.
+	* stdlib/stdlib.h (__strtof, __strtold): Declarations removed.
+	(__strto{f,d,ld,l,ul,q,uq}_internal): Declare these functions.
+	[__OPTIMIZE__]: Define inline functions calling those.
+	* stdlib/grouping.h: New file, written by drepper.
+	* stdlib/Makefile (distribute): Add grouping.h.
+	* stdio/vfscanf.c: Grok %' modifier to numeric conversions.  Call
+ 	__strtoX_internal with the grouping flag set iff the modifier is
+ 	present.
+
+Wed Mar 15 00:40:54 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* sysdeps/generic/memchr.c: Fix typos: limit.h -> limits.h.
+
+	* mach/Machrules: Produce static deps for all object flavors.
+	[interface-library]: Remove all these variables and rules.
+	($(interface-library)-routines): Define this variable.
+	(extra-libs): Append $(interface-library) to this.
+	* mach/Makefile (interface-library): Omit .a suffix.
+	* hurd/Makefile: Likewise.
+
+Tue Mar 14 23:40:31 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
+
+	* stdio/internals.c (flushbuf): If !FLUSH_ONLY, don't skip out
+ 	early if no new data in buffer after priming.
+
 Mon Mar 13 01:48:16 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
+	* Makerules (object-suffixes, libtypes): Move all these variables
+ 	to Makeconfig.
+	* Makeconfig (object-suffixes, libtypes): Moved here from Makerules.
+
+	* Makerules (build-extra-lib): New canned sequence.
+
+	* sysdeps/mach/hurd/euidaccess.c: Include fcntl.h.  Declare ERR;
+ 	fix uses of FILE and PORT.  Remove bogus weak alias for `access'.
+
+	* sysdeps/mach/hurd/dirfd.c: Include hurd/fd.h and errno.h.
+	Add missing semicolon.
+	* sysdeps/mach/hurd/opendir.c: Include hurd/fd.h.  Use a `struct
+ 	hurd_fd *' temp var, since DIRP->__fd is a `void *'.
+	* sysdeps/mach/hurd/readdir.c: Include hurd/fd.h.
+
+	* stdlib/wcstombs.c: #if 0 out code for non-ASCII chars until the
+ 	locale data format is implemented.
+
+	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
+ 	Pass &__sigreturn on the stack to the trampoline code, so it is
+ 	not position-dependent.
+
+	* stdio/printf_fp.c (NDEBUG): Define this to disable assert.
+  	Don't include <stdarg.h>.
+	(__printf_fp): Last arg ARGS is now `const void **const'; 
+	dereference ARGS[0] instead of using va_arg.
+
+	* locale/setlocale.c: In LC_ALL case, initialize CATEGORY before
+ 	loop to install data.
+
+	* locale/loadlocale.c (_nl_category_num_items): Use _NL_ITEM_INDEX
+ 	to extract number from item code.
+	(_nl_load_locale): Close the descriptor when finished.
+
+	* malloc/realloc.c (_realloc_internal): Call _malloc_internal in
+ 	place of malloc.
+
+	* time/tzfile.c (__tzfile_default): Initialize RULE_STDOFF to zero.
+
 	* stdio/printf_fp.c (group_number): Cast *GROUPING to unsigned int
  	to avoid warning.
 	* sysdeps/generic/sigset.h (__SIGSETFN): Cast result of sizeof to
diff --git a/Makeconfig b/Makeconfig
index b10ec81fb9..8cee8c066d 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -340,8 +340,8 @@ endif	# gcc
 
 # These are the variables that the implicit compilation rules use.
 CPPFLAGS = $(+includes) $(defines) -include $(..)libc-symbols.h \
-	   $(sysdep-CPPFLAGS)
-override CFLAGS	= $(+cflags) $(sysdep-CFLAGS)
+	   $(sysdep-CPPFLAGS) $(CFLAGS-$(suffix $@))
+override CFLAGS	= $(+cflags) $(sysdep-CFLAGS) $(CPPFLAGS-$(suffix $@))
 
 
 # This is the macro that the implicit linking rules use.
@@ -349,6 +349,41 @@ ifneq "$(filter -g,$(+cflags))" "" # -g is in $(+cflags)
 LDFLAGS	:= -g
 endif
 
+
+# Enable object files for different versions of the library.
+# Various things use $(object-suffixes) to know what all to make.
+# The compilation rules use $(CPPFLAGS-${SUFFIX}) and $(CFLAGS-${SUFFIX})
+# to pass different flags for each flavor.
+libtypes = $(foreach o,$(object-suffixes),$(libtype$o))
+object-suffixes := .o
+libtype.o := lib%.a
+ifeq (yes,$(build-shared))
+# Under --enable-shared, we will build a shared library of PIC objects.
+# The PIC object files are named foo.so.
+object-suffixes += .so
+CPPFLAGS-.so = -DPIC
+CFLAGS-.so = -fPIC
+libtype.so := lib%_pic.a
+endif
+ifeq (yes,$(build-profile))
+# Under --enable-profile, we will build a static library of profiled objects.
+# The profiled object files are named foo.po.
+object-suffixes += .po
+CFLAGS-.po = -p
+libtype.po = lib%_p.a
+endif
+ifeq (yes,$(build-omitfp))
+# Under --enable-omitfp, we build an the library optimized without
+# debugging information using -fomit-frame-pointer, and build an extra
+# library with debugging information.  The debuggable objects are named foo.go.
+object-suffixes += .go
+CFLAGS-.go = -g
+CFLAGS-.o = -g0 -O99 -fomit-frame-pointer
+CFLAGS-.so += $(CFLAGS.o)
+libtype.go = lib%_g.a
+endif
+
+
 +gnu-stabs = $(shell echo>&2 '*** BARF ON ME')
 
 ifneq ($(BUILD_CC),$(CC))
diff --git a/Makerules b/Makerules
index 780ed43700..6a8073006c 100644
--- a/Makerules
+++ b/Makerules
@@ -65,41 +65,6 @@ endif
 # Add -I switches to get the right sysdep directories.
 # `+includes' in Makeconfig references $(+sysdep-includes).
 +sysdep-includes := $(addprefix -I,$(+sysdep_dirs))
-
-# Enable object files for different versions of the library.
-# Various things use $(object-suffixes) to know what all to make.
-# The compilation rules use $(CPPFLAGS-${SUFFIX}) and $(CFLAGS-${SUFFIX})
-# to pass different flags for each flavor.
-libtypes = $(foreach o,$(object-suffixes),$(libtype$o))
-object-suffixes := .o
-libtype.o := lib%.a
-override CFLAGS += $(CFLAGS-$(suffix $@))
-override CPPFLAGS += $(CPPFLAGS-$(suffix $@))
-ifeq (yes,$(build-shared))
-# Under --enable-shared, we will build a shared library of PIC objects.
-# The PIC object files are named foo.so.
-object-suffixes += .so
-CPPFLAGS-.so = -DPIC
-CFLAGS-.so = -fPIC
-libtype.so := lib%_pic.a
-endif
-ifeq (yes,$(build-profile))
-# Under --enable-profile, we will build a static library of profiled objects.
-# The profiled object files are named foo.po.
-object-suffixes += .po
-CFLAGS-.po = -p
-libtype.po = lib%_p.a
-endif
-ifeq (yes,$(build-omitfp))
-# Under --enable-omitfp, we build an the library optimized without
-# debugging information using -fomit-frame-pointer, and build an extra
-# library with debugging information.  The debuggable objects are named foo.go.
-object-suffixes += .go
-CFLAGS-.go = -g
-CFLAGS-.o = -g0 -O99 -fomit-frame-pointer
-CFLAGS-.so += $(CFLAGS.o)
-libtype.go = lib%_g.a
-endif
 
 # Include any system-specific makefiles.
 
@@ -416,6 +381,14 @@ symdef.%: $(foreach o,$(object-suffixes),\
 .PHONY: objects objs
 objects objs: $(foreach o,$(object-suffixes),$(objects:.o=$o)) \
 	      $(addprefix $(objpfx),$(extra-objs))
+
+# Canned sequence for building an extra library archive.
+define build-extra-lib
+$(patsubst %,cd %;,$(objdir)) \
+$(AR) cru$(verbose) $(@:$(objpfx)%=%) \
+      $(patsubst $(objpfx)%,%,$^)
+$(RANLIB) $@
+endef
 
 # Installation.
 
diff --git a/Rules b/Rules
index c40e9b2f30..df944e4c90 100644
--- a/Rules
+++ b/Rules
@@ -79,7 +79,7 @@ tests: $(tests:%=$(objpfx)%.out)
 endif
 
 ifneq "$(strip $(others) $(tests))" ""
-$(addprefix $(objpfx),$(others) $(tests)): %: %.o $(libc.a)
+$(addprefix $(objpfx),$(others) $(tests)): %: %.o $(common-objpfx)libc.a
 	$(+link)
 endif
 
diff --git a/hurd/Makefile b/hurd/Makefile
index 7a5a1ba995..386267c649 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -31,7 +31,7 @@ headers = hurd.h $(interface-headers) \
 distribute := hurdfault.h intr-rpc.awk intr-rpc.defs STATUS
 
 # The RPC interfaces go in a separate library.
-interface-library := libhurduser.a
+interface-library := libhurduser
 user-interfaces		:= $(addprefix hurd/,\
 				       auth process startup \
 				       msg msg_reply msg_request \
diff --git a/locale/C-ctype.c b/locale/C-ctype.c
index 6a987209ed..7a5c0c7b7f 100644
--- a/locale/C-ctype.c
+++ b/locale/C-ctype.c
@@ -3,74 +3,74 @@
 #include "localeinfo.h"
 #include <endian.h>
 
-static const char _nl_C_LC_CTYPE_class[] = 
-  /* 0x80 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x86 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x8c */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x92 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x98 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x9e */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xa4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xaa */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xb0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xb6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xbc */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xc2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xc8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xce */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xd4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xda */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xe0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xe6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xec */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xf2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xf8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xfe */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x04 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\001\024"
-  /* 0x0a */ "\000\024" "\000\024" "\000\024" "\000\024" "\000\004" "\000\004"
-  /* 0x10 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x16 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x1c */ "\000\004" "\000\004" "\000\004" "\000\004" "\001\220" "\000\100"
-  /* 0x22 */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
-  /* 0x28 */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
-  /* 0x2e */ "\000\100" "\000\100" "\000\050" "\000\050" "\000\050" "\000\050"
-  /* 0x34 */ "\000\050" "\000\050" "\000\050" "\000\050" "\000\050" "\000\050"
-  /* 0x3a */ "\000\100" "\000\100" "\000\100" "\000\100" "\000\100" "\000\100"
-  /* 0x40 */ "\000\100" "\000\041" "\000\041" "\000\041" "\000\041" "\000\041"
-  /* 0x46 */ "\000\041" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
-  /* 0x4c */ "\000\001" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
-  /* 0x52 */ "\000\001" "\000\001" "\000\001" "\000\001" "\000\001" "\000\001"
-  /* 0x58 */ "\000\001" "\000\001" "\000\001" "\000\100" "\000\100" "\000\100"
-  /* 0x5e */ "\000\100" "\000\100" "\000\100" "\000\042" "\000\042" "\000\042"
-  /* 0x64 */ "\000\042" "\000\042" "\000\042" "\000\002" "\000\002" "\000\002"
-  /* 0x6a */ "\000\002" "\000\002" "\000\002" "\000\002" "\000\002" "\000\002"
-  /* 0x70 */ "\000\002" "\000\002" "\000\002" "\000\002" "\000\002" "\000\002"
-  /* 0x76 */ "\000\002" "\000\002" "\000\002" "\000\002" "\000\002" "\000\100"
-  /* 0x7c */ "\000\100" "\000\100" "\000\100" "\000\004" "\000\004" "\000\004"
-  /* 0x82 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x88 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x8e */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x94 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0x9a */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xa0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xa6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xac */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xb2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xb8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xbe */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xc4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xca */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xd0 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xd6 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xdc */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xe2 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xe8 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xee */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xf4 */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
-  /* 0xfa */ "\000\004" "\000\004" "\000\004" "\000\004" "\000\004" "\000\004"
+const char _nl_C_LC_CTYPE_class[] = 
+  /* 0x80 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x86 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x8c */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x92 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x98 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x9e */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xa4 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xaa */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xb0 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xb6 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xbc */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xc2 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xc8 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xce */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xd4 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xda */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xe0 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xe6 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xec */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xf2 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xf8 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xfe */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x04 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\003\040"
+  /* 0x0a */ "\002\040" "\002\040" "\002\040" "\002\040" "\002\000" "\002\000"
+  /* 0x10 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x16 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x1c */ "\002\000" "\002\000" "\002\000" "\002\000" "\001\140" "\004\300"
+  /* 0x22 */ "\004\300" "\004\300" "\004\300" "\004\300" "\004\300" "\004\300"
+  /* 0x28 */ "\004\300" "\004\300" "\004\300" "\004\300" "\004\300" "\004\300"
+  /* 0x2e */ "\004\300" "\004\300" "\000\330" "\000\330" "\000\330" "\000\330"
+  /* 0x34 */ "\000\330" "\000\330" "\000\330" "\000\330" "\000\330" "\000\330"
+  /* 0x3a */ "\004\300" "\004\300" "\004\300" "\004\300" "\004\300" "\004\300"
+  /* 0x40 */ "\004\300" "\000\325" "\000\325" "\000\325" "\000\325" "\000\325"
+  /* 0x46 */ "\000\325" "\000\305" "\000\305" "\000\305" "\000\305" "\000\305"
+  /* 0x4c */ "\000\305" "\000\305" "\000\305" "\000\305" "\000\305" "\000\305"
+  /* 0x52 */ "\000\305" "\000\305" "\000\305" "\000\305" "\000\305" "\000\305"
+  /* 0x58 */ "\000\305" "\000\305" "\000\305" "\004\300" "\004\300" "\004\300"
+  /* 0x5e */ "\004\300" "\004\300" "\004\300" "\000\326" "\000\326" "\000\326"
+  /* 0x64 */ "\000\326" "\000\326" "\000\326" "\000\306" "\000\306" "\000\306"
+  /* 0x6a */ "\000\306" "\000\306" "\000\306" "\000\306" "\000\306" "\000\306"
+  /* 0x70 */ "\000\306" "\000\306" "\000\306" "\000\306" "\000\306" "\000\306"
+  /* 0x76 */ "\000\306" "\000\306" "\000\306" "\000\306" "\000\306" "\004\300"
+  /* 0x7c */ "\004\300" "\004\300" "\004\300" "\002\000" "\002\000" "\002\000"
+  /* 0x82 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x88 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x8e */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x94 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0x9a */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xa0 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xa6 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xac */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xb2 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xb8 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xbe */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xc4 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xca */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xd0 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xd6 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xdc */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xe2 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xe8 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xee */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xf4 */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
+  /* 0xfa */ "\002\000" "\002\000" "\002\000" "\002\000" "\002\000" "\002\000"
 ;
 #if BYTE_ORDER == LITTLE_ENDIAN
-static const char _nl_C_LC_CTYPE_toupper[] = 
+const char _nl_C_LC_CTYPE_toupper[] = 
   /* 0x80 */ "\200\000\000\000" "\201\000\000\000" "\202\000\000\000"
   /* 0x83 */ "\203\000\000\000" "\204\000\000\000" "\205\000\000\000"
   /* 0x86 */ "\206\000\000\000" "\207\000\000\000" "\210\000\000\000"
@@ -200,7 +200,7 @@ static const char _nl_C_LC_CTYPE_toupper[] =
   /* 0xfa */ "\372\000\000\000" "\373\000\000\000" "\374\000\000\000"
   /* 0xfd */ "\375\000\000\000" "\376\000\000\000" "\377\000\000\000"
 ;
-static const char _nl_C_LC_CTYPE_tolower[] = 
+const char _nl_C_LC_CTYPE_tolower[] = 
   /* 0x80 */ "\200\000\000\000" "\201\000\000\000" "\202\000\000\000"
   /* 0x83 */ "\203\000\000\000" "\204\000\000\000" "\205\000\000\000"
   /* 0x86 */ "\206\000\000\000" "\207\000\000\000" "\210\000\000\000"
@@ -331,7 +331,7 @@ static const char _nl_C_LC_CTYPE_tolower[] =
   /* 0xfd */ "\375\000\000\000" "\376\000\000\000" "\377\000\000\000"
 ;
 #elif BYTE_ORDER == BIG_ENDIAN
-static const char _nl_C_LC_CTYPE_toupper[] = 
+const char _nl_C_LC_CTYPE_toupper[] = 
   /* 0x80 */ "\000\000\000\200" "\000\000\000\201" "\000\000\000\202"
   /* 0x83 */ "\000\000\000\203" "\000\000\000\204" "\000\000\000\205"
   /* 0x86 */ "\000\000\000\206" "\000\000\000\207" "\000\000\000\210"
@@ -461,7 +461,7 @@ static const char _nl_C_LC_CTYPE_toupper[] =
   /* 0xfa */ "\000\000\000\372" "\000\000\000\373" "\000\000\000\374"
   /* 0xfd */ "\000\000\000\375" "\000\000\000\376" "\000\000\000\377"
 ;
-static const char _nl_C_LC_CTYPE_tolower[] = 
+const char _nl_C_LC_CTYPE_tolower[] = 
   /* 0x80 */ "\000\000\000\200" "\000\000\000\201" "\000\000\000\202"
   /* 0x83 */ "\000\000\000\203" "\000\000\000\204" "\000\000\000\205"
   /* 0x86 */ "\000\000\000\206" "\000\000\000\207" "\000\000\000\210"
@@ -601,12 +601,8 @@ const struct locale_data _nl_C_LC_CTYPE =
   5,
   {
     _nl_C_LC_CTYPE_class,
-#if BYTE_ORDER == BIG_ENDIAN
-    _nl_C_LC_CTYPE_toupper, _nl_C_LC_CTYPE_tolower,
-#endif
     NULL, NULL,
-#if BYTE_ORDER == LITTLE_ENDIAN
-    _nl_C_LC_CTYPE_toupper, _nl_C_LC_CTYPE_tolower,
-#endif
+    _nl_C_LC_CTYPE_toupper,
+    _nl_C_LC_CTYPE_tolower
   }
 };
diff --git a/locale/C-monetary.c b/locale/C-monetary.c
index 7e2b1bc3a7..bf2cede799 100644
--- a/locale/C-monetary.c
+++ b/locale/C-monetary.c
@@ -15,16 +15,16 @@ const struct locale_data _nl_C_LC_MONETARY =
     "",
     "",
     "",
-    "\377",
+    "\177",
     "",
     "",
-    "\377",
-    "\377",
-    "\377",
-    "\377",
-    "\377",
-    "\377",
-    "\377",
-    "\377"
+    "\177",
+    "\177",
+    "\177",
+    "\177",
+    "\177",
+    "\177",
+    "\177",
+    "\177"
   }
 };
diff --git a/locale/C-numeric.c b/locale/C-numeric.c
index 05cdad1265..248e2eb7bd 100644
--- a/locale/C-numeric.c
+++ b/locale/C-numeric.c
@@ -13,6 +13,6 @@ const struct locale_data _nl_C_LC_NUMERIC =
   {
     ".",
     "",
-    "\377"
+    "\177"
   }
 };
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
index 5c367ae4be..7ad7a21b53 100644
--- a/locale/loadlocale.c
+++ b/locale/loadlocale.c
@@ -30,7 +30,7 @@ Cambridge, MA 02139, USA.  */
 const size_t _nl_category_num_items[] =
   {
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
-    [category] = _NL_NUM_##category,
+    [category] = _NL_ITEM_INDEX (_NL_NUM_##category),
 #include "categories.def"
 #undef	DEFINE_CATEGORY
   };
@@ -60,10 +60,12 @@ _nl_load_locale (int category, char **name)
 
   if ((*name)[0] == '\0')
     {
-      *name = getenv (_nl_category_names[category]);
-      if (! *name || (*name) == '\0')
+      *name = getenv ("LC_ALL");
+      if (! *name || (*name)[0] == '\0')
+	*name = getenv (_nl_category_names[category]);
+      if (! *name || (*name)[0] == '\0')
 	*name = getenv ("LANG");
-      if (! *name || (*name) == '\0')
+      if (! *name || (*name)[0] == '\0')
 	*name = (char *) "local";
     }
 
@@ -172,6 +174,7 @@ _nl_load_locale (int category, char **name)
       newdata->strings[i] = newdata->filedata + idx;
     }
 
+  __close (fd);
   return newdata;
 }
 
diff --git a/locale/setlocale.c b/locale/setlocale.c
index 79d22ab98d..500d8627eb 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -255,7 +255,7 @@ setlocale (int category, const char *name)
 	  char *n = alloca (len);
 	  memcpy (n, name, len);
 
-	  while (p = strchr (n, '='))
+	  while ((p = strchr (n, '=')) != NULL)
 	    {
 	      for (i = 0; i < LC_ALL; ++i)
 		if (_nl_category_name_sizes[i] == p - n &&
@@ -353,7 +353,7 @@ setlocale (int category, const char *name)
 	}
 
       /* Now we have loaded all the new data.  Put it in place.  */
-      for (; category < LC_ALL; ++category)
+      for (category = 0; category < LC_ALL; ++category)
 	{
 	  setdata (category, newdata[category]);
 	  setname (category, newnames[category]);
diff --git a/mach/Machrules b/mach/Machrules
index 4f91d9bab7..93916a0a27 100644
--- a/mach/Machrules
+++ b/mach/Machrules
@@ -175,38 +175,24 @@ interface-headers: $(interface-headers)
 omit-deps += $(interface-routines)
 
 # Specify the static dependencies of the generated files.
-$(foreach if,$(user-interfaces),$($(if)-calls:%=$(objpfx)RPC_%.o))): \
+$(foreach o,$(object-suffixes),\
+$(foreach if,$(user-interfaces),$($(if)-calls:%=$(objpfx)RPC_%$o))): \
     mach/boolean.h mach/kern_return.h mach/message.h mach/notify.h \
     mach/mach_types.h mach/mig_errors.h mach/mig_support.h mach/msg_type.h \
     $(..)libc-symbols.h $(objpfx)config.h
-$(server-interfaces:%=$(objpfx)%.o): \
+$(foreach o,$(object-suffixes),\
+$(server-interfaces:%=$(objpfx)%$o)): \
     mach/boolean.h mach/kern_return.h mach/message.h mach/mig_errors.h \
     mach/mig_support.h mach/std_types.h
 # The MiG-generated sources also depend on the imports in their .defs files.
 # These dependencies are generated into the .ir files above.
 
-# If defined, $(interface-library) is `libNAME.a'.  It is to be a library
+# If defined, $(interface-library) is `libNAME'.  It is to be a library
 # containing all the MiG-generated functions for the specified interfaces.
 
 ifdef interface-library
 
-$(interface-library)-objs := $(interface-routines:%=%.o)
-
-install-lib += $(interface-library)
-extra-objs += $($(interface-library)-objs)
-
-$(objpfx)$(interface-library): $(addprefix $(objpfx),\
-					   $($(interface-library)-objs))
-ifdef objdir
-	cd $(objdir); $(AR) cru$(verbose) $(@:$(objpfx)%=%) $(^:$(objpfx)%=%)
-else
-	$(AR) cru$(verbose) $@ $^
-endif
-	$(RANLIB) $@
-
-lib-noranlib: $(objpfx)$(interface-library)
-
-mostlyclean:
-	-rm -f $(objpfx)$(interface-library)
+$(interface-library)-routines = $(interface-routines)
+extra-libs += $(interface-library)
 
 endif
diff --git a/mach/Makefile b/mach/Makefile
index 5f1ecae342..f9a3815f39 100644
--- a/mach/Makefile
+++ b/mach/Makefile
@@ -37,7 +37,7 @@ routines = $(mach-syscalls) $(mach-shortcuts) \
 	   mach_error errstring error_compat errsystems \
 	   devstream bootprivport setup-thread $(lock)
 # The RPC interfaces go in a separate library.
-interface-library := libmachuser.a
+interface-library := libmachuser
 user-interfaces := $(addprefix mach/,mach_interface mach_port mach_host	\
 				     memory_object_user			\
 				     memory_object_default		\
diff --git a/stdio/internals.c b/stdio/internals.c
index b01c5bd531..c238bf39f9 100644
--- a/stdio/internals.c
+++ b/stdio/internals.c
@@ -265,7 +265,7 @@ DEFUN(flushbuf, (fp, c),
 	    }
 	}
 
-      if (fp->__bufp - fp->__buffer <= buffer_offset)
+      if (fp->__bufp - fp->__buffer <= buffer_offset && flush_only)
 	{
 	  /* There is nothing new in the buffer, only data that
 	     was read back aligned from the file.  */
diff --git a/stdio/printf_fp.c b/stdio/printf_fp.c
index 42443fa003..33fe427999 100644
--- a/stdio/printf_fp.c
+++ b/stdio/printf_fp.c
@@ -36,12 +36,11 @@ Cambridge, MA 02139, USA.  */
 #include <limits.h>
 #include <math.h>
 #include <printf.h>
-#include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 
-/* #define NDEBUG 1 */
+#define NDEBUG			/* Undefine this for debugging assertions.  */
 #include <assert.h>
 
 /* This defines make it possible to use the same code for GNU C library and
@@ -133,7 +132,7 @@ int
 __printf_fp (fp, info, args)
      FILE *fp;
      const struct printf_info *info;
-     va_list *args;
+     const **const args;
 {
   /* The floating-point value to output.  */
   union
@@ -254,7 +253,7 @@ __printf_fp (fp, info, args)
   /* Fetch the argument value.	*/
   if (info->is_long_double && sizeof (long double) > sizeof (double))
     {
-      fpnum.ldbl = va_arg (*args, LONG_DOUBLE);
+      fpnum.ldbl = *(const long double *) args[0];
 
       /* Check for special values: not a number or infinity.  */
       if (__isnanl (fpnum.ldbl))
@@ -279,7 +278,7 @@ __printf_fp (fp, info, args)
     }
   else
     {
-      fpnum.dbl = va_arg (*args, double);
+      fpnum.dbl = *(const double *) args[0];
 
       /* Check for special values: not a number or infinity.  */
       if (__isnan (fpnum.dbl))
diff --git a/stdio/vfscanf.c b/stdio/vfscanf.c
index 47781ed566..9a9e3bb79c 100644
--- a/stdio/vfscanf.c
+++ b/stdio/vfscanf.c
@@ -57,6 +57,7 @@ DEFUN(__vfscanf, (s, format, arg),
   register int c;		/* Last char read.  */
   register int do_assign;	/* Whether to do an assignment.  */
   register int width;		/* Maximum field width.  */
+  int group_flag;		/* %' modifier flag.  */
 
   /* Type modifiers.  */
   char is_short, is_long, is_long_double;
@@ -76,8 +77,13 @@ DEFUN(__vfscanf, (s, format, arg),
   /* Signedness for integral numbers.  */
   int number_signed;
   /* Integral holding variables.  */
-  long int num;
-  unsigned long int unum;
+  union
+    {
+      long long int q;
+      unsigned long long int uq;
+      long int l;
+      unsigned long int ul;
+    } num;
   /* Character-buffer pointer.  */
   register char *str, **strptr;
   size_t strsize;
@@ -93,8 +99,8 @@ DEFUN(__vfscanf, (s, format, arg),
     }
 
   /* Figure out the decimal point character.  */
-  if (mbtowc(&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
-	     strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
+  if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
+	      strlen (_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT))) <= 0)
     decimal = (wchar_t) *_NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
 
   c = inchar();
@@ -102,10 +108,10 @@ DEFUN(__vfscanf, (s, format, arg),
   /* Run through the format string.  */
   while (*f != '\0')
     {
-      if (!isascii(*f))
+      if (!isascii (*f))
 	{
 	  /* Non-ASCII, may be a multibyte.  */
-	  int len = mblen(f, strlen(f));
+	  int len = mblen (f, strlen(f));
 	  if (len > 0)
 	    {
 	      while (len-- > 0)
@@ -139,15 +145,20 @@ DEFUN(__vfscanf, (s, format, arg),
 	  continue;
 	}
 
-      /* Check for the assignment-suppressant.  */
-      if (*f == '*')
-	{
-	  do_assign = 0;
-	  ++f;
-	}
-      else
-	do_assign = 1;
-		
+      /* Check for the assignment-suppressant and the number grouping flag.  */
+      do_assign = 1;
+      group_flag = 0;
+      while (*f == '*' || *f == '\'')
+	switch (*f++)
+	  {
+	  case '*':
+	    do_assign = 0;
+	    break;
+	  case '\'':
+	    group_flag = 1;
+	    break;
+	  }
+
       /* Find the maximum field width.  */
       width = 0;
       while (isdigit(*f))
@@ -396,9 +407,19 @@ DEFUN(__vfscanf, (s, format, arg),
 	  /* Convert the number.  */
 	  *w = '\0';
 	  if (number_signed)
-	    num = strtol (work, &w, base);
+	    {
+	      if (is_longlong)
+		num.q = __strtoq_internal (work, &w, base, group_flag);
+	      else
+		num.uq = __strtouq_internal (work, &w, base, group_flag);
+	    }
 	  else
-	    unum = strtoul (work, &w, base);
+	    {
+	      if (is_long_double)
+		num.l = __strtol_internal (work, &w, base, group_flag);
+	      else
+		num.ul = __strtoul_internal (work, &w, base, group_flag);
+	    }
 	  if (w == work)
 	    conv_error ();
 
@@ -407,25 +428,25 @@ DEFUN(__vfscanf, (s, format, arg),
 	      if (! number_signed)
 		{
 		  if (is_longlong)
-		    *va_arg (arg, unsigned LONGLONG int *) = unum;
+		    *va_arg (arg, unsigned LONGLONG int *) = num.uq;
 		  else if (is_long)
-		    *va_arg (arg, unsigned long int *) = unum;
+		    *va_arg (arg, unsigned long int *) = num.ul;
 		  else if (is_short)
 		    *va_arg (arg, unsigned short int *)
-		      = (unsigned short int) unum;
+		      = (unsigned short int) num.ul;
 		  else
-		    *va_arg(arg, unsigned int *) = (unsigned int) unum;
+		    *va_arg (arg, unsigned int *) = (unsigned int) num.ul;
 		}
 	      else
 		{
 		  if (is_longlong)
-		    *va_arg(arg, LONGLONG int *) = num;
+		    *va_arg (arg, LONGLONG int *) = num.q;
 		  else if (is_long)
-		    *va_arg(arg, long int *) = num;
+		    *va_arg (arg, long int *) = num.l;
 		  else if (is_short)
-		    *va_arg(arg, short int *) = (short int) num;
+		    *va_arg (arg, short int *) = (short int) num.l;
 		  else
-		    *va_arg(arg, int *) = (int) num;
+		    *va_arg (arg, int *) = (int) num.l;
 		}
 	      ++done;
 	    }
@@ -482,19 +503,19 @@ DEFUN(__vfscanf, (s, format, arg),
 	  *w = '\0';
 	  if (is_long_double)
 	    {
-	      long double d = __strtold (work, &w);
+	      long double d = __strtold_internal (work, &w, group_flag);
 	      if (do_assign && w != work)
 		*va_arg (arg, long double *) = d;
 	    }
 	  else if (is_long)
 	    {
-	      double d = strtod (work, &w);
+	      double d = __strtod_internal (work, &w, group_flag);
 	      if (do_assign && w != work)
 		*va_arg (arg, double *) = d;
 	    }
 	  else
 	    {
-	      float d = __strtof (work, &w);
+	      float d = __strtof_internal (work, &w, group_flag);
 	      if (do_assign && w != work)
 		*va_arg (arg, float *) = d;
 	    }
@@ -536,7 +557,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	    conv_error();
 
 	  *w = '\0';
-	  unum = read_in;
+	  num.ul = read_in;
 	  do
 	    {
 	      if ((strchr (work, c) == NULL) != not_in)
@@ -545,7 +566,7 @@ DEFUN(__vfscanf, (s, format, arg),
 	      if (width > 0)
 		--width;
 	    } while (inchar () != EOF && width != 0);
-	  if (read_in == unum)
+	  if (read_in == num.ul)
 	    conv_error ();
 
 	  if (do_assign)
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 1a1498c662..ea1ffd33e8 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -37,7 +37,7 @@ routines	:=							      \
 	strtof strtod strtold						      \
 	system
 
-distribute	:= exit.h
+distribute	:= exit.h grouping.h
 tests		:= tst-strtol tst-strtod testmb testrand testsort testdiv
 
 include ../Rules
diff --git a/stdlib/grouping.h b/stdlib/grouping.h
new file mode 100644
index 0000000000..566f6a6109
--- /dev/null
+++ b/stdlib/grouping.h
@@ -0,0 +1,123 @@
+/* Internal header for proving correct grouping in strings of numbers.
+Copyright (C) 1995 Free Software Foundation, Inc.
+Contributed by Ulrich Drepper.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <limits.h>
+
+#ifndef MAX
+#define MAX(a,b)	({ typeof(a) _a = (a); typeof(b) _b = (b); \
+			   _a > _b ? _a : _b; })
+#endif
+
+/* Find the maximum prefix of the string between BEGIN and END which
+   satisfies the grouping rules.  It is assumed that at least one digit
+   follows BEGIN directly.  */
+
+static inline const char *
+correctly_grouped_prefix (const char *begin, const char *end,
+			  wchar_t thousands, const char *grouping)
+{
+  if (! grouping)
+    return end;
+
+  while (end > begin)
+    {
+      const char *cp = end - 1;
+      const char *gp = grouping;
+
+      /* Check first group.  */
+      while (cp >= begin && (wchar_t) *cp != thousands)
+	--cp;
+
+      if (end - cp == (int) *gp + 1)
+	{
+	  /* This group matches the specification.  */
+
+	  const char *new_end;
+
+	  if (cp < begin)
+	    /* There is just one complete group.  We are done.  */
+	    return end;
+
+	  /* CP points to a thousands separator character.  The preceding
+	     remainder of the string from BEGIN to NEW_END is the part we
+	     will consider if there is a grouping error in this trailing
+	     portion from CP to END.  */
+	  new_end = cp - 1;
+
+	  /* Loop while the grouping is correct.  */
+	  while (1)
+	    {
+	      /* Get the next grouping rule.  */
+	      ++gp;
+	      if (*gp == 0)
+		/* If end is reached use last rule.  */ 
+	        --gp;
+
+	      /* Skip the thousands separator.  */
+	      --cp;
+
+	      if (*gp == CHAR_MAX || *gp < 0)
+	        {
+	          /* No more thousands separators are allowed to follow.  */
+	          while (cp >= begin && (wchar_t) *cp != thousands)
+		    --cp;
+
+	          if (cp < begin)
+		    /* OK, only digits followed.  */
+		    return end;
+	        }
+	      else
+	        {
+		  /* Check the next group.  */
+	          const char *group_end = cp;
+
+		  while (cp >= begin && (wchar_t) *cp != thousands)
+		    --cp;
+
+		  if (cp < begin && group_end - cp <= (int) *gp)
+		    /* Final group is correct.  */
+		    return end;
+
+		  if (cp < begin || group_end - cp != (int) *gp)
+		    /* Incorrect group.  Punt.  */
+		    break;
+		}
+	    }
+
+	  /* The trailing portion of the string starting at NEW_END
+	     contains a grouping error.  So we will look for a correctly
+	     gouped number in the preceding portion instead.  */
+	  end = new_end;
+	}
+      else
+	{
+	  /* Even the first group was wrong; determine maximum shift.  */
+	  if (end - cp > (int) *gp + 1)
+	    end = cp + (int) *gp + 1;
+	  else if (cp < begin)
+	    /* This number does not fill the first group, but is correct.  */
+	    return end;
+	  else
+	    /* CP points to a thousands seperator character.  */
+	    end = cp;
+	}
+    }
+
+  return MAX (begin, end);
+} 
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index d64a2ffb7c..2a3cf8ec5f 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -78,9 +78,7 @@ extern double strtod __P ((__const char *__nptr, char **__endptr));
 
 #ifdef	__USE_GNU
 /* Likewise for `float' and `long double' sizes of floating-point numbers.  */
-extern float __strtof __P ((__const char *__nptr, char **__endptr));
 extern float strtof __P ((__const char *__nptr, char **__endptr));
-extern __long_double_t __strtold __P ((__const char *__nptr, char **__endptr));
 extern __long_double_t strtold __P ((__const char *__nptr, char **__endptr));
 #endif
 
@@ -100,9 +98,57 @@ extern unsigned long long int strtouq __P ((__const char *__nptr,
 					    char **__endptr, int __base));
 #endif /* GCC and use BSD.  */
 
+
+/* The internal entry points for `strtoX' take an extra flag argument
+   saying whether or not to parse locale-dependent number grouping.  */
+
+extern double __strtod_internal (__const char *__nptr,
+				 char **__endptr, int __group);
+extern float __strtof_internal (__const char *__nptr, char **__endptr,
+				int __group);
+extern __long_double_t __strtold_internal (__const char *__nptr,
+					   char **__endptr, int __group);
+extern long int __strtol_internal (__const char *__nptr, char **__endptr,
+				   int __base, int __group);
+extern unsigned long int __strtoul_internal (__const char *__nptr,
+					     char **__endptr, int __base,
+					     int __group);
+extern long long int __strtoq_internal (__const char *__nptr, char **__endptr,
+					int __base, int __group);
+extern unsigned long long int __strtouq_internal (__const char *__nptr,
+						  char **__endptr, int __base,
+						  int __group);
+
 #if defined (__OPTIMIZE__) && __GNUC__ >= 2
+/* Define inline functions which call the internal entry points.  */
+
+extern __inline double strtod (__const char *__nptr, char **__endptr)
+{ return __strtod_internal (__nptr, __endptr, 0); }
+extern __inline long int strtol (__const char *__nptr,
+				 char **__endptr, int __base)
+{ return __strtol_internal (__nptr, __endptr, __base, 0); }
+extern __inline unsigned long int strtoul (__const char *__nptr,
+					   char **__endptr, int __base)
+{ return __strtoul_internal (__nptr, __endptr, __base, 0); }
+
+#ifdef __USE_GNU
+extern __inline float strtof (__const char *__nptr, char **__endptr)
+{ return __strtof_internal (__nptr, __endptr, 0); }
+extern __inline __long_double_t strtold (__const char *__nptr, char **__endptr)
+{ return __strtold_internal (__nptr, __endptr, 0); }
+#endif
+
+#ifdef __USE_BSD
+extern __inline long long int strtoq (__const char *__nptr, char **__endptr,
+				      int __base)
+{ return __strtoq_internal (__nptr, __endptr, __base, 0); }
+extern __inline unsigned long long int strtouq (__const char *__nptr,
+					    char **__endptr, int __base)
+{ return __strtouq_internal (__nptr, __endptr, __base, 0); }
+#endif
+
 extern __inline double atof (__const char *__nptr)
-{ return strtod(__nptr, (char **) NULL); }
+{ return strtod (__nptr, (char **) NULL); }
 extern __inline int atoi (__const char *__nptr)
 { return (int) strtol (__nptr, (char **) NULL, 10); }
 extern __inline long int atol (__const char *__nptr)
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index 2f0e972893..8f71d136de 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -102,10 +102,11 @@ static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
 #define	RETURN_LIMB_SIZE		howmany (MANT_DIG, BITS_PER_MP_LIMB)
 
 #define RETURN(val,end) \
-	do { if (endptr != 0) *endptr = (char *) end; return val; } while (0)
+  do { if (endptr != 0) *endptr = (char *) (end); return (val); } while (0)
 
 /* Maximum size necessary for mpn integers to hold floating point numbers.  */ 
-#define	MPNSIZE		(howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) + 2)
+#define	MPNSIZE		(howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) \
+			 + 2)
 /* Declare an mpn integer variable that big.  */
 #define	MPN_VAR(name)	mp_limb name[MPNSIZE]; mp_size_t name##size
 /* Copy an mpn integer value.  */
@@ -276,15 +277,23 @@ __mpn_lshift_1 (mp_limb *ptr, mp_size_t size, unsigned int count, mp_limb limb)
 }
 
 
+#define INTERNAL(x) INTERNAL1(x)
+#define INTERNAL1(x) __##x##_internal
+
+/* This file defines a function to check for correct grouping.  */
+#include "grouping.h"
+
+
 /* Return a floating point number with the value of the given string NPTR.
    Set *ENDPTR to the character after the last used one.  If the number is
    smaller than the smallest representable number, set `errno' to ERANGE and
    return 0.0.  If the number is too big to be represented, set `errno' to
    ERANGE and return HUGE_VAL with the approriate sign.  */
 FLOAT
-STRTOF (nptr, endptr)
-    const char *nptr;
-    char **endptr;
+INTERNAL (STRTOF) (nptr, endptr, group)
+     const char *nptr;
+     char **endptr;
+     int group;
 {
   int negative;			/* The sign of the number.  */
   MPN_VAR (num);		/* MP representation of the number.  */
@@ -301,9 +310,9 @@ STRTOF (nptr, endptr)
   int bits;
 
   /* Running pointer after the last character processed in the string.  */
-  const char *cp;
+  const char *cp, *tp;
   /* Start of significant part of the number.  */
-  const char *startp;
+  const char *startp, *start_of_digits;
   /* Points at the character following the integer and fractional digits.  */
   const char *expp;
   /* Total number of digit and number of digits in integer part.  */
@@ -313,60 +322,29 @@ STRTOF (nptr, endptr)
 
   /* The radix character of the current locale.  */
   wchar_t decimal;
-#ifdef	USE_GROUPING
   /* The thousands character of the current locale.  */
   wchar_t thousands;
   /* The numeric grouping specification of the current locale,
      in the format described in <locale.h>.  */
   const char *grouping;
 
-  /* Check the grouping of the integer part at [BEGIN,END).
-     Return zero iff a separator is found out of place.  */
-  int grouping_ok (const char *begin, const char *end)
+  if (group)
     {
-      if (grouping)
-	while (end > begin)
-	  {
-	    const char *p = end;
-	    do
-	      --p;
-	    while (*p != thousands && p > begin);
-	    if (end - 1 - p != *grouping++)
-	      return 0;		/* Wrong number of digits in this group.  */
-	    end = p;		/* Correct group; trim it off the end.  */
-
-	    if (*grouping == 0)
-	      --grouping;	/* Same grouping repeats in next iteration.  */
-	    else if (*grouping == CHAR_MAX || *grouping < 0)
-	      {
-		/* No further grouping allowed.  */
-		while (end > begin)
-		  if (*--end == thousands)
-		    return 0;
-	      }
-	  }
-      return 1;
-    }
-  /* Return with no conversion if the grouping of [STARTP,CP) is bad.  */
-#define	CHECK_GROUPING if (! grouping_ok (startp, cp)) RETURN (0.0, nptr); else
-
-  grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
-  if (*grouping <= 0 || *grouping == CHAR_MAX)
-    grouping = NULL;
-  else
-    {
-      /* Figure out the thousands seperator character.  */
-      if (mbtowc (&thousands_sep, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
-		  strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
-	thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
-      if (thousands == L'\0')
+      grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+      if (*grouping <= 0 || *grouping == CHAR_MAX)
 	grouping = NULL;
+      else
+	{
+	  /* Figure out the thousands separator character.  */
+	  if (mbtowc (&thousands, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+		      strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+	    thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+	  if (thousands == L'\0')
+	    grouping = NULL;
+	}
     }
-#else
-#define	grouping	NULL
-#define	thousands	L'\0'
-#define	CHECK_GROUPING	((void) 0)
-#endif
+  else
+    grouping = NULL;
 
   /* Find the locale's decimal point character.  */
   if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
@@ -402,18 +380,21 @@ STRTOF (nptr, endptr)
     RETURN (0.0, nptr);
 
   /* Record the start of the digits, in case we will check their grouping.  */
-  startp = cp;
+  start_of_digits = startp = cp;
 
   /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
   while (c == '0' || (thousands != L'\0' && c == thousands))
     c = *++cp;
 
-  CHECK_GROUPING;
-
   /* If no other digit but a '0' is found the result is 0.0.
      Return current read pointer.  */
   if (!isdigit (c) && c != decimal)
-    RETURN (0.0, cp);
+    {
+      tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
+      /* If TP is at the start of the digits, there was no correctly
+	 grouped prefix of the string; so no number found.  */
+      RETURN (0.0, tp == start_of_digits ? nptr : tp);
+    }
 
   /* Remember first significant digit and read following characters until the
      decimal point, exponent character or any non-FP number character.  */
@@ -432,7 +413,37 @@ STRTOF (nptr, endptr)
       c = *++cp;
     }
 
-  CHECK_GROUPING;
+  if (grouping && dig_no > 0)
+    {
+      /* Check the grouping of the digits.  */
+      tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
+      if (cp != tp)
+       {
+	  /* Less than the entire string was correctly grouped.  */
+
+	  if (tp == start_of_digits)
+	    /* No valid group of numbers at all: no valid number.  */
+	    RETURN (0.0, nptr);
+
+	  if (tp < startp)
+	    /* The number is validly grouped, but consists
+	       only of zeroes.  The whole value is zero.  */
+	    RETURN (0.0, tp);
+
+	  /* Recompute DIG_NO so we won't read more digits than
+	     are properly grouped.  */
+	  cp = tp;
+	  dig_no = 0;
+	  for (tp = startp; tp < cp; ++tp)
+	    if (isdigit (*tp))
+	      ++dig_no;
+
+	  int_no = dig_no;
+	  lead_zero = 0;
+
+	  goto number_parsed;
+	}
+    }
 
   if (dig_no >= NDIG)
     /* Too many digits to be representable.  Assigning this to EXPONENT
@@ -528,6 +539,8 @@ STRTOF (nptr, endptr)
       assert (dig_no >= int_no);
     }
 
+ number_parsed:
+
   /* The whole string is parsed.  Store the address of the next character.  */
   if (endptr)
     *endptr = (char *) cp;
@@ -546,7 +559,7 @@ STRTOF (nptr, endptr)
     exponent -= incr;
   }
 
-  if (int_no + exponent > MAX_10_EXP)
+  if (int_no + exponent > MAX_10_EXP + 1)
     {
       errno = ERANGE;
       return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
@@ -607,6 +620,14 @@ STRTOF (nptr, endptr)
       count_leading_zeros (bits, num[numsize - 1]);
       bits = numsize * BITS_PER_MP_LIMB - bits;
 
+      /* Now we know the exponent of the number in base two.
+	 Check it against the maximum possible exponent.  */
+      if (bits > MAX_EXP)
+	{
+	  errno = ERANGE;
+	  return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+	}
+
       /* We have already the first BITS bits of the result.  Together with
 	 the information whether more non-zero bits follow this is enough
 	 to determine the result.  */
@@ -1059,3 +1080,15 @@ STRTOF (nptr, endptr)
 
   /* NOTREACHED */
 }
+
+/* External user entry point.  */
+
+weak_symbol (STRTOF)
+
+FLOAT
+STRTOF (nptr, endptr)
+     const char *nptr;
+     char **endptr;
+{
+  return INTERNAL (STRTOF) (nptr, endptr, 0);
+}
diff --git a/stdlib/strtol.c b/stdlib/strtol.c
index 888a94e4d7..1c63afb6fe 100644
--- a/stdlib/strtol.c
+++ b/stdlib/strtol.c
@@ -22,11 +22,17 @@ Cambridge, MA 02139, USA.  */
 #include <stddef.h>
 #include <stdlib.h>
 #include <errno.h>
+#include "../locale/localeinfo.h"
 
-/* Nonzero if we are defining `strtoul' or `strtouq', operating on unsigned
-   integers.  */
-#ifndef	UNSIGNED
+
+/* Nonzero if we are defining `strtoul' or `strtouq', operating on
+   unsigned integers.  */
+#ifndef UNSIGNED
 #define	UNSIGNED	0
+#define INT		LONG int
+#else
+#define	strtol		strtoul
+#define INT		unsigned LONG int
 #endif
 
 /* If QUAD is defined, we are defining `strtoq' or `strtouq',
@@ -54,22 +60,27 @@ static const unsigned long long int maxquad = ULONG_LONG_MAX;
 #define	LONG	long
 #endif
 
+
+#define INTERNAL(x) INTERNAL1(x)
+#define INTERNAL1(x) __##x##_internal
+
+/* This file defines a function to check for correct grouping.  */
+#include "grouping.h"
+
+
 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
    If BASE is 0 the base is determined by the presence of a leading
    zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
    If BASE is < 2 or > 36, it is reset to 10.
    If ENDPTR is not NULL, a pointer to the character after the last
    one converted is stored in *ENDPTR.  */
-#if	UNSIGNED
-unsigned LONG int
-#define	strtol	strtoul
-#else
-LONG int
-#endif
-strtol (nptr, endptr, base)
+
+INT
+INTERNAL (strtol) (nptr, endptr, base, group)
      const char *nptr;
      char **endptr;
      int base;
+     int group;
 {
   int negative;
   register unsigned LONG int cutoff;
@@ -77,9 +88,34 @@ strtol (nptr, endptr, base)
   register unsigned LONG int i;
   register const char *s;
   register unsigned char c;
-  const char *save;
+  const char *save, *end;
   int overflow;
 
+  /* The thousands character of the current locale.  */
+  wchar_t thousands;
+  /* The numeric grouping specification of the current locale,
+     in the format described in <locale.h>.  */
+  const char *grouping;
+
+  if (group)
+    {
+      grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
+      if (*grouping <= 0 || *grouping == CHAR_MAX)
+	grouping = NULL;
+      else
+	{
+	  /* Figure out the thousands separator character.  */
+	  if (mbtowc (&thousands, _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP),
+		      strlen (_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP))) <= 0)
+	    thousands = (wchar_t) *_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
+	  if (thousands == L'\0')
+	    grouping = NULL;
+	}
+    }
+  else
+    grouping = NULL;
+
+
   if (base < 0 || base == 1 || base > 36)
     base = 10;
 
@@ -126,6 +162,20 @@ strtol (nptr, endptr, base)
   /* Save the pointer so we can check later if anything happened.  */
   save = s;
 
+  if (group)
+    {
+      /* Find the end of the digit string and check its grouping.  */
+      end = s;
+      for (c = *end; c != '\0'; c = *++end)
+	if (c != thousands && !isdigit (c) &&
+	    (!isalpha (c) || toupper (c) - 'A' + 10 >= base))
+	  break;
+      if (*s == thousands)
+	end = s;
+      else
+	end = correctly_grouped_prefix (s, end, thousands, grouping);
+    }
+
   cutoff = ULONG_MAX / (unsigned LONG int) base;
   cutlim = ULONG_MAX % (unsigned LONG int) base;
 
@@ -133,6 +183,8 @@ strtol (nptr, endptr, base)
   i = 0;
   for (c = *s; c != '\0'; c = *++s)
     {
+      if (group && s == end)
+	break;
       if (isdigit (c))
 	c -= '0';
       else if (isalpha (c))
@@ -187,3 +239,16 @@ noconv:
     *endptr = (char *) nptr;
   return 0L;
 }
+
+/* External user entry point.  */
+
+weak_symbol (strtol)
+
+INT
+strtol (nptr, endptr, base)
+     const char *nptr;
+     char **endptr;
+     int base;
+{
+  return INTERNAL (strtol) (nptr, endptr, base, 0);
+}
diff --git a/stdlib/wcstombs.c b/stdlib/wcstombs.c
index acaf15a94e..6ddbfb1725 100644
--- a/stdlib/wcstombs.c
+++ b/stdlib/wcstombs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1995 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
@@ -17,7 +17,7 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#include <localeinfo.h>
+#include "../locale/localeinfo.h"
 #include <ctype.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -32,8 +32,10 @@ size_t
 DEFUN(wcstombs, (s, pwcs, n),
       register char *s AND register CONST wchar_t *pwcs AND register size_t n)
 {
+#if 0
   register CONST mb_char *mb;
   register int shift = 0;
+#endif
 
   register size_t written = 0;
   register wchar_t w;
@@ -49,6 +51,10 @@ DEFUN(wcstombs, (s, pwcs, n),
 	}
       else
 	{
+#if 1
+	  written = (size_t) -1;
+	  break;
+#else
 	  mb = &_ctype_info->mbchar->mb_chars[w + shift];
 	  if (mb->string == NULL || mb->len == 0)
 	    {
@@ -65,6 +71,7 @@ DEFUN(wcstombs, (s, pwcs, n),
 	      written += mb->len;
 	      shift += mb->shift;
 	    }
+#endif
 	}
     }
 
diff --git a/stdlib/wctomb.c b/stdlib/wctomb.c
index 78b55b7af5..15f32ab71f 100644
--- a/stdlib/wctomb.c
+++ b/stdlib/wctomb.c
@@ -53,7 +53,7 @@ DEFUN(wctomb, (s, wchar), register char *s AND wchar_t wchar)
 	*s = '\0';
       return 1;
     }
-  else if (mb == NULL)
+  else /* if (mb == NULL) */
     {
       if ((wchar_t) (char) wchar == wchar && isascii ((char) wchar))
 	{
diff --git a/sysdeps/generic/memchr.c b/sysdeps/generic/memchr.c
index 1731574907..5ceb2ba7c9 100644
--- a/sysdeps/generic/memchr.c
+++ b/sysdeps/generic/memchr.c
@@ -35,8 +35,8 @@ Cambridge, MA 02139, USA.  */
 # include <string.h>
 #endif
 
-#if defined (HAVE_LIMIT_H) || defined (_LIBC)
-# include <limit.h>
+#if defined (HAVE_LIMITS_H) || defined (_LIBC)
+# include <limits.h>
 #endif
 
 #define LONG_MAX_32_BITS 2147483647
diff --git a/sysdeps/mach/hurd/dirfd.c b/sysdeps/mach/hurd/dirfd.c
index 366a34079b..9e713fc4ca 100644
--- a/sysdeps/mach/hurd/dirfd.c
+++ b/sysdeps/mach/hurd/dirfd.c
@@ -19,6 +19,8 @@ Cambridge, MA 02139, USA.  */
 
 #include <dirent.h>
 #include <dirstream.h>
+#include <hurd/fd.h>
+#include <errno.h>
 
 int
 dirfd (DIR *dirp)
@@ -30,7 +32,7 @@ dirfd (DIR *dirp)
       break;
   if (fd == _hurd_dtablesize)
     {
-      errno = EINVAL
+      errno = EINVAL;
       fd = -1;
     }
   __mutex_unlock (&_hurd_dtable_lock);
diff --git a/sysdeps/mach/hurd/euidaccess.c b/sysdeps/mach/hurd/euidaccess.c
index 5ba2af4965..bbd2d21afe 100644
--- a/sysdeps/mach/hurd/euidaccess.c
+++ b/sysdeps/mach/hurd/euidaccess.c
@@ -20,6 +20,7 @@ Cambridge, MA 02139, USA.  */
 #include <errno.h>
 #include <stddef.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <hurd.h>
 
 int
@@ -27,6 +28,7 @@ euidaccess (file, type)
      const char *file;
      int type;
 {
+  error_t err;
   file_t port;
   int allowed, flags;
 
@@ -35,8 +37,8 @@ euidaccess (file, type)
     return -1;
 
   /* Find out what types of access we are allowed to this file.  */
-  err = __file_check_access (file, &allowed);
-  __mach_port_deallocate (__mach_task_self (), file);
+  err = __file_check_access (port, &allowed);
+  __mach_port_deallocate (__mach_task_self (), port);
   if (err)
     return __hurd_fail (err);
 
@@ -54,5 +56,3 @@ euidaccess (file, type)
 
   return 0;
 }
-
-weak_alias (__access, access)
diff --git a/sysdeps/mach/hurd/i386/trampoline.c b/sysdeps/mach/hurd/i386/trampoline.c
index eabf940b44..75f11457cd 100644
--- a/sysdeps/mach/hurd/i386/trampoline.c
+++ b/sysdeps/mach/hurd/i386/trampoline.c
@@ -1,5 +1,5 @@
 /* Set thread_state for sighandler, and sigcontext to recover.  i386 version.
-Copyright (C) 1994 Free Software Foundation, Inc.
+Copyright (C) 1994, 1995 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
@@ -51,6 +51,8 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
       int signo;
       long int sigcode;
       struct sigcontext *scp;	/* Points to ctx, below.  */
+      void *sigreturn_addr;
+      void *sigreturn_returns_here;
       struct sigcontext *return_scp; /* Same; arg to sigreturn.  */
       struct sigcontext ctx;
     } *stackframe;
@@ -120,6 +122,7 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
       stackframe->signo = signo;
       stackframe->sigcode = sigcode;
       stackframe->scp = stackframe->return_scp = scp = &stackframe->ctx;
+      stackframe->sigreturn_addr = &__sigreturn;
 
       /* Set up the sigcontext from the current state of the thread.  */
 
@@ -224,11 +227,13 @@ _hurd_setup_sighandler (struct hurd_sigstate *ss, __sighandler_t handler,
        8(%esp)	SCP
      */
   asm volatile
-    ("call %*%%edx\n"		/* Call the handler function.  */
-     "addl $12, %%esp\n"	/* Pop its args.  */
-     "call %P0\n"		/* Call __sigreturn (SCP); never returns.  */
-     "hlt"			/* Just in case.  */
-     : : "i" (&__sigreturn));
+    ("call *%edx\n"		/* Call the handler function.  */
+     "addl $12, %esp\n"		/* Pop its args.  */
+     /* The word at the top of stack is &__sigreturn; following are a dummy
+	word to fill the slot for the address for __sigreturn to return to,
+	and a copy of SCP for __sigreturn's argument.  "Return" to calling
+	__sigreturn (SCP); this call never returns.  */
+     "ret");
 
   /* NOTREACHED */
   return NULL;
diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c
index 001016d087..40cb9d0dc0 100644
--- a/sysdeps/mach/hurd/opendir.c
+++ b/sysdeps/mach/hurd/opendir.c
@@ -28,6 +28,7 @@ Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #include <stdio.h>
 #include <hurd.h>
+#include <hurd/fd.h>
 
 
 /* Open a directory stream on NAME.  */
@@ -35,8 +36,8 @@ DIR *
 DEFUN(opendir, (name), CONST char *name)
 {
   DIR *dirp;
-  file_t port;
   int fd;
+  struct hurd_fd *d;
 
   fd = __open (name, O_RDONLY);
   if (fd < 0)
@@ -51,13 +52,13 @@ DEFUN(opendir, (name), CONST char *name)
 
   /* Extract the pointer to the descriptor structure.  */
   __mutex_lock (&_hurd_dtable_lock);
-  dirp->__fd = _hurd_dtable[fd];
+  d = dirp->__fd = _hurd_dtable[fd];
   __mutex_unlock (&_hurd_dtable_lock);
 
   /* Set the descriptor to close on exec. */
-  __spin_lock (&dirp->__fd->port.lock);
-  dirp->__fd->flags |= FD_CLOEXEC;
-  __spin_unlock (&dirp->__fd->port.lock);
+  __spin_lock (&d->port.lock);
+  d->flags |= FD_CLOEXEC;
+  __spin_unlock (&d->port.lock);
 
   dirp->__data = dirp->__ptr = NULL;
   dirp->__entry_data = dirp->__entry_ptr = 0;
diff --git a/sysdeps/mach/hurd/readdir.c b/sysdeps/mach/hurd/readdir.c
index 9e9f1ae3bd..746b11e523 100644
--- a/sysdeps/mach/hurd/readdir.c
+++ b/sysdeps/mach/hurd/readdir.c
@@ -25,6 +25,7 @@ Cambridge, MA 02139, USA.  */
 #include <unistd.h>
 #include <sys/types.h>
 #include <hurd.h>
+#include <hurd/fd.h>
 
 
 /* Read a directory entry from DIRP.  */
@@ -50,7 +51,7 @@ DEFUN(readdir, (dirp), DIR *dirp)
 	  error_t err;
 
 	  if (err = HURD_FD_PORT_USE (dirp->__fd,
-				      __dir_readdir (dirp->__port,
+				      __dir_readdir (port,
 						     &data, &dirp->__size,
 						     dirp->__entry_ptr,
 						     -1, 0, &nentries)))
diff --git a/time/tzfile.c b/time/tzfile.c
index 9ff24df08b..cc99802d53 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -269,7 +269,7 @@ DEFUN(__tzfile_default, (std, dst, stdoff, dstoff),
   /* Find the standard and daylight time offsets used by the rule file.
      We choose the offsets in the types of each flavor that are
      transitioned to earliest in time.  */
-  rule_dstoff = 0;
+  rule_stdoff = rule_dstoff = 0;
   for (i = 0; i < num_transitions; ++i)
     {
       if (!rule_stdoff && !types[type_idxs[i]].isdst)