summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--BUGS7
-rw-r--r--ChangeLog98
-rw-r--r--bits/mathdef.h7
-rw-r--r--bits/stat.h20
-rw-r--r--bits/types.h2
-rw-r--r--include/sys/stat.h1
-rw-r--r--intl/loadmsgcat.c1
-rw-r--r--libio/fileops.c1
-rw-r--r--libio/oldfileops.c1
-rw-r--r--manual/arith.texi248
-rw-r--r--manual/math.texi8
-rw-r--r--manual/time.texi16
-rw-r--r--math/complex.h5
-rw-r--r--math/libm-test.c45
-rw-r--r--math/math.h69
-rw-r--r--string/strndup.c4
-rw-r--r--sunrpc/xcrypt.c2
-rw-r--r--sysdeps/alpha/fpu/bits/mathdef.h29
-rw-r--r--sysdeps/generic/bits/mathdef.h7
-rw-r--r--sysdeps/generic/bits/stat.h20
-rw-r--r--sysdeps/generic/bits/types.h2
-rw-r--r--sysdeps/i386/fpu/bits/mathdef.h12
-rw-r--r--sysdeps/ieee754/bits/nan.h23
-rw-r--r--sysdeps/m68k/bits/nan.h59
-rw-r--r--sysdeps/m68k/fpu/bits/mathdef.h7
-rw-r--r--sysdeps/posix/getcwd.c7
-rw-r--r--sysdeps/powerpc/bits/mathdef.h29
-rw-r--r--sysdeps/sparc/fpu/bits/mathdef.h29
-rw-r--r--sysdeps/unix/arm/sysdep.S6
-rw-r--r--sysdeps/unix/sysv/linux/arm/profil-counter.h2
-rw-r--r--sysdeps/unix/sysv/linux/arm/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/getcwd.c94
-rw-r--r--sysdeps/wordsize-32/inttypes.h2
-rw-r--r--sysdeps/wordsize-64/inttypes.h2
-rw-r--r--time/mktime.c164
-rw-r--r--time/offtime.c11
-rw-r--r--time/strftime.c6
-rw-r--r--time/time.h9
-rw-r--r--time/tzset.c9
39 files changed, 802 insertions, 266 deletions
diff --git a/BUGS b/BUGS
index 7585e7fe45..f4b60398ed 100644
--- a/BUGS
+++ b/BUGS
@@ -1,7 +1,7 @@
 	    List of known bugs (certainly very incomplete)
 	    ----------------------------------------------
 
-Time-stamp: <1997-11-05T16:59:11+0100 drepper>
+Time-stamp: <1997-11-12T04:42:03+0100 drepper>
 
 This following list contains those bugs which I'm aware of.  Please
 make sure that bugs you report are not listed here.  If you can fix one
@@ -55,6 +55,11 @@ Severity: [  *] to [***]
        checked for errors, but the whole file containing the same
        category.
        [PR libc/207]
+
+[  *]  The libm-ieee `asin' function gives wrong results (at least for 0.5).
+
+[  *]  _IO_getline can loop forever, at least with C++
+       [PR libc/332]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Ulrich Drepper
 drepper@cygnus.com
diff --git a/ChangeLog b/ChangeLog
index 877ae6c470..3d8704f99c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,101 @@
+1997-11-13 01:07  Ulrich Drepper  <drepper@cygnus.com>
+
+	* manual/arith.texi: Update documentation according to most recent
+	ISO C 9X draft.
+	Document fma, fdim, fmin, and fmax.
+	* manual/math.texi: Allow multiple defitino of mul etc.
+
+	* math/complex.h (I): Define using _Complex_U not _Imaginary_I.
+
+	* math/libm-test.c: Add tests for fma.
+
+	* math/math.h: Describe DECIMAL_DIG macro.  Pretty print.
+
+	* sysdeps/alpha/fpu/bits/mathdef.h: Define INFINITY as of type float.
+	Define DECIMAL_DIG.
+	* sysdeps/generic/bits/mathdef.h: Likewise.
+	* sysdeps/i386/bits/mathdef.h: Likewise.
+	* sysdeps/m68k/fpu/bits/mathdef.h: Likewise.
+	* sysdeps/powerpc/bits/mathdef.h: Likewise.
+	* sysdeps/sparc/fpu/bits/mathdef.h: Likewise.
+
+	* sysdeps/ieee754/bits/nan.h: Define NAN as of type float.
+	* sysdeps/m68k/bits/nan.h. Likewise.  Remove NANF and NANL.
+
+1997-11-12 17:50  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sunrpc/xcrypt.c: Don't process #ident preprocessor instruction.
+	Reported by Philip Blundell <pb@nexus.co.uk>.
+
+	* string/strndup.c: Use K&R like definition.
+
+	* sysdeps/unix/sysv/linux/getcwd.c: New file.  Use kernel information
+	instead of longish search for the name.
+	* sysdeps/posix/getcwd.c: Add support for use of the code as a
+	backup solution.
+
+1997-11-12 15:31  Philip Blundell  <pb@nexus.co.uk>
+
+	* sysdeps/unix/sysv/linux/arm/sysdep.h (SYS_ify): Don't add
+	SWI_BASE in twice.
+
+	* sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
+	Use correct name to access PC.
+
+	* sysdeps/unix/arm/sysdep.S: Include <bits/errno.h> not <errnos.h>.
+
+	* sysdeps/generic/bits/types.h: Add __ino64_t and __off64_t.
+	* sysdeps/generic/bits/stat.h: Add struct stat64.
+
+1997-11-12 16:08  Ulrich Drepper  <drepper@cygnus.com>
+
+	* intl/loadmsgcat.c [_LIBC] (fstat): Don't define as __fstat since
+	now we have a definition as _fxstat.
+	* libio/fileops.c: Likewise.
+	* libio/oldfileops.c: Likewise.
+	Reported by Andreas Jaeger <aj@arthur.rhein-neckar.de>.
+
+1997-11-12  Andreas Jaeger  <aj@arthur.rhein-neckar.de>
+
+	* sysdeps/wordsize-32/inttypes.h (SIG_ATOMIC_MAX): Correct value.
+	* sysdeps/wordsize-64/inttypes.h (SIG_ATOMIC_MAX): Likewise.
+
+1997-11-11  Paul Eggert  <eggert@twinsun.com>
+
+	Add overflow checking for 64-bit time_t and 32-bit int.
+
+	* time/time.h (__offtime): Now returns int.
+
+	* time/offtime.c (__offtime): Return nonzero if successful;
+	check for tm_year overflow.
+	(DIV): New macro.
+	(LEAPS_THRU_END_OF): Handle negative years correctly.
+
+	* time/tzset.c (__tz_convert): Return NULL if offtime cannot convert.
+
+	* time/mktime.c (ranged_convert): New function.
+	(ydhms_tm_diff): Return nonzero if TP is null.
+	(__mktime_internal): Handle cases correctly even if they are near or
+	past the limits of time_t values that can be broken down to struct tm.
+	(print_tm, check_result, main): Diagnose localtime failures.
+
+	* manual/time.texi: Document the fact that localtime returns 0
+	if the time can't be represented.
+
+1997-11-12 06:03  Ulrich Drepper  <drepper@cygnus.com>
+
+	* time/strftime.c (memset_space, memset_zero): Use MEMPCPY, not
+	mempcpy.  Patch by Ken'ichi Handa  <handa@etl.go.jp>.
+
+	* manual/time.texi: Document %F and %f format for strftime.
+
+	* manual/arith.texi: Document copysign, nextafter and nan.
+
+1997-11-06  Andreas Jaeger  <aj@arthur.rhein-neckar.de>
+
+	* test-installation.pl: New file. Tests for some installation
+	problems.
+
 1997-11-11 21:30  Ulrich Drepper  <drepper@cygnus.com>
 
 	* include/sys/stat.h: Define stat, fstat, lstat and *64 variants
diff --git a/bits/mathdef.h b/bits/mathdef.h
index 93b60bd25f..15140997c0 100644
--- a/bits/mathdef.h
+++ b/bits/mathdef.h
@@ -31,10 +31,13 @@ typedef double double_t;	/* `double' expressions are evaluated as
 /* Signal that both types are `double'.  */
 #define FLT_EVAL_METHOD	1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+#define INFINITY	HUGE_VALF
 
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0	0x80000001
 #define FP_ILOGBNAN	0x7fffffff
+
+/* Number of decimal digits for the `double' type.  */
+#define DECIMAL_DIG	15
diff --git a/bits/stat.h b/bits/stat.h
index dab0cd00cb..3648fed738 100644
--- a/bits/stat.h
+++ b/bits/stat.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1996, 1997 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
@@ -70,5 +70,23 @@ struct stat
 #define	__S_IWRITE	0200	/* Write by owner.  */
 #define	__S_IEXEC	0100	/* Execute by owner.  */
 
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+
+    __ino64_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __off64_t st_size;			/* Size of file, in bytes.  */
+
+    __time_t st_atime;			/* Time of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+  };
+#endif
+
 
 #endif /* bits/stat.h */
diff --git a/bits/types.h b/bits/types.h
index fdb36f0b54..51fadd196e 100644
--- a/bits/types.h
+++ b/bits/types.h
@@ -67,6 +67,8 @@ typedef __u_quad_t __fsid_t;	/* Type of file system IDs.  */
 typedef long int __clock_t;	/* Type of CPU usage counts.  */
 typedef long int __rlim_t;	/* Type for resource measurement.  */
 typedef __quad_t __rlim64_t;	/* Type for resource measurement (LFS).  */
+typedef __quad_t __ino64_t;	/* Type for file serial numbers.  */
+typedef __loff_t __off64_t;	/* Type of file izes and offsets.  */
 
 /* Everythin' else.  */
 typedef long int __daddr_t;	/* The type of a disk address.  */
diff --git a/include/sys/stat.h b/include/sys/stat.h
index be9bdd0c42..16950eb039 100644
--- a/include/sys/stat.h
+++ b/include/sys/stat.h
@@ -8,6 +8,7 @@
 #define stat(fname, buf) __xstat (_STAT_VER, fname, buf)
 #define fstat(fd, buf) __fxstat (_STAT_VER, fd, buf)
 #define lstat(fname, buf)  __lxstat (_STAT_VER, fname, buf)
+#define __lstat(fname, buf)  __lxstat (_STAT_VER, fname, buf)
 #define stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
 #define fstat64(fd, buf) __fxstat64 (_STAT_VER, fd, buf)
 #define lstat64(fname, buf)  __lxstat64 (_STAT_VER, fname, buf)
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index a67223ff7e..de0534269f 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -48,7 +48,6 @@
 /* Rename the non ISO C functions.  This is required by the standard
    because some ISO C functions will require linking with this object
    file and the name space must not be polluted.  */
-# define fstat  __fstat
 # define open   __open
 # define close  __close
 # define read   __read
diff --git a/libio/fileops.c b/libio/fileops.c
index ffc57f1d37..a0cc2f7d0e 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -45,7 +45,6 @@ extern int errno;
 #ifdef _LIBC
 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
 # define close(FD) __close (FD)
-# define fstat(FD, Statbuf) __fstat (FD, Statbuf)
 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index 71a2bc27a1..b426e88364 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -49,7 +49,6 @@ extern int errno;
 #ifdef _LIBC
 # define open(Name, Flags, Prot) __open (Name, Flags, Prot)
 # define close(FD) __close (FD)
-# define fstat(FD, Statbuf) __fstat (FD, Statbuf)
 # define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
 # define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
 # define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
diff --git a/manual/arith.texi b/manual/arith.texi
index d0863f98df..a5ba31dde8 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -1,3 +1,19 @@
+@c We need some definitions here.
+@ifclear cdor
+@ifhtml
+@set cdot ·
+@end ifhtml
+@iftex
+@set cdot @cdot
+@end iftex
+@ifclear cdot
+@set cdot x
+@end ifclear
+@macro mul
+@value{cdot}
+@end macro
+@end ifclear
+
 @node Arithmetic, Date and Time, Mathematics, Top
 @chapter Low-Level Arithmetic Functions
 
@@ -18,6 +34,8 @@ These functions are declared in the header files @file{math.h} and
 * Normalization Functions::     Hacks for radix-2 representations.
 * Rounding and Remainders::     Determining the integer and
 			         fractional parts of a float.
+* Arithmetic on FP Values::     Setting and Modifying Single Bits of FP Values.
+* Special arithmetic on FPs::   Special Arithmetic on FPs.
 * Integer Division::            Functions for performing integer
 				 division.
 * Parsing of Numbers::          Functions for ``reading'' numbers
@@ -40,7 +58,7 @@ these situations.  There is a special value for infinity.
 
 @comment math.h
 @comment ISO
-@deftypevr Macro float_t INFINITY
+@deftypevr Macro float INFINITY
 An expression representing the infinite value.  @code{INFINITY} values are
 produced by mathematical operations like @code{1.0 / 0.0}.  It is
 possible to continue the computations with this value since the basic
@@ -85,7 +103,7 @@ a NaN.
 
 @comment math.h
 @comment GNU
-@deftypevr Macro double NAN
+@deftypevr Macro float NAN
 An expression representing a value which is ``not a number''.  This
 macro is a GNU extension, available only on machines that support ``not
 a number'' values---that is to say, on all machines that support IEEE
@@ -106,15 +124,39 @@ imaginary part of the numbers.  In mathematics one uses the symbol ``i''
 to mark a number as imaginary.  For convenience the @file{complex.h}
 header defines two macros which allow to use a similar easy notation.
 
-@deftypevr Macro float_t _Imaginary_I
-This macro is a (compiler specific) representation of the value ``1i''.
-I.e., it is the value for which
+@deftypevr Macro {const float complex} _Complex_I
+This macro is a representation of the complex number ``@math{0+1i}''.
+Computing
+
+@smallexample
+_Complex_I * _Complex_I = -1
+@end smallexample
+
+@noindent
+leads to a real-valued result.  If no @code{imaginary} types are
+available it is easiest to use this value to construct complex numbers
+from real values:
+
+@smallexample
+3.0 - _Complex_I * 4.0
+@end smallexample
+
+@noindent
+Without an optimizing compiler this is more expensive than the use of
+@code{_Imaginary_I} but with is better than nothing.  You can avoid all
+the hassles if you use the @code{I} macro below if the name is not
+problem.
+
+@deftypevr Macro {const float imaginary} _Imaginary_I
+This macro is a representation of the value ``@math{1i}''.  I.e., it is
+the value for which
 
 @smallexample
 _Imaginary_I * _Imaginary_I = -1
 @end smallexample
 
 @noindent
+The result is not of type @code{float imaginary} but instead @code{float}.
 One can use it to easily construct complex number like in
 
 @smallexample
@@ -129,11 +171,16 @@ imaginary part -4.0.
 @noindent
 A more intuitive approach is to use the following macro.
 
-@deftypevr Macro float_t I
+@deftypevr Macro {const float imaginary} I
 This macro has exactly the same value as @code{_Imaginary_I}.  The
 problem is that the name @code{I} very easily can clash with macros or
 variables in programs and so it might be a good idea to avoid this name
 and stay at the safe side by using @code{_Imaginary_I}.
+
+If the implementation does not support the @code{imaginary} types
+@code{I} is defined as @code{_Complex_I} which is the second best
+solution.  It still can be used in the same way but requires a most
+clever compiler to get the same results.
 @end deftypevr
 
 
@@ -379,7 +426,7 @@ whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt
 
 @pindex math.h
 @pindex stdlib.h
-Prototypes for @code{abs} and @code{labs} are in @file{stdlib.h};
+Prototypes for @code{abs}, @code{labs} and @code{llabs} are in @file{stdlib.h};
 @code{fabs}, @code{fabsf} and @code{fabsl} are declared in @file{math.h};
 @code{cabs}, @code{cabsf} and @code{cabsl} are declared in @file{complex.h}.
 
@@ -400,6 +447,15 @@ This is similar to @code{abs}, except that both the argument and result
 are of type @code{long int} rather than @code{int}.
 @end deftypefun
 
+@comment stdlib.h
+@comment ISO
+@deftypefun {long long int} llabs (long long int @var{number})
+This is similar to @code{abs}, except that both the argument and result
+are of type @code{long long int} rather than @code{int}.
+
+This function is defined in @w{ISO C 9X}.
+@end deftypefun
+
 @comment math.h
 @comment ISO
 @deftypefun double fabs (double @var{number})
@@ -512,29 +568,6 @@ The value returned by @code{logb} is one less than the value that
 @code{frexp} would store into @code{*@var{exponent}}.
 @end deftypefun
 
-@comment math.h
-@comment ISO
-@deftypefun double copysign (double @var{value}, double @var{sign})
-@deftypefunx float copysignf (float @var{value}, float @var{sign})
-@deftypefunx {long double} copysignl (long double @var{value}, long double @var{sign})
-These functions return a value whose absolute value is the
-same as that of @var{value}, and whose sign matches that of @var{sign}.
-This function appears in BSD and was standardized in @w{ISO C 9X}.
-@end deftypefun
-
-@comment math.h
-@comment ISO
-@deftypefun int signbit (@emph{float-type} @var{x})
-@code{signbit} is a generic macro which can work on all floating-point
-types.  It returns a nonzero value if the value of @var{x} has its sign
-bit set.
-
-This is not the same as @code{x < 0.0} since in some floating-point
-formats (e.g., @w{IEEE 754}) the zero value is optionally signed.  The
-comparison @code{-0.0 < 0.0} will not be true while @code{signbit
-(-0.0)} will return a nonzero value.
-@end deftypefun
-
 @node Rounding and Remainders
 @section Rounding and Remainder Functions
 @cindex rounding functions
@@ -652,6 +685,161 @@ If @var{denominator} is zero, @code{drem} fails and sets @code{errno} to
 @end deftypefun
 
 
+@node Arithmetic on FP Values
+@section Setting and modifying Single Bits of FP Values
+@cindex FP arithmetic
+
+In certain situations it is too complicated (or expensive) to modify a
+floating-point value by the normal operations.  For a few operations
+@w{ISO C 9X} defines functions to modify the floating-point value
+directly.
+
+@comment math.h
+@comment ISO
+@deftypefun double copysign (double @var{x}, double @var{y})
+@deftypefunx float copysignf (float @var{x}, float @var{y})
+@deftypefunx {long double} copysignl (long double @var{x}, long double @var{y})
+The @code{copysign} function allows to specifiy the sign of the
+floating-point value given in the parameter @var{x} by discarding the
+prior content and replacing it with the sign of the value @var{y}.
+The so found value is returned.
+
+This function also works and throws no exception if the parameter
+@var{x} is a @code{NaN}.  If the platform supports the signed zero
+representation @var{x} might also be zero.
+
+This function is defined in @w{IEC 559} (and the appendix with
+recommended functions in @w{IEEE 754}/@w{IEEE 854}).
+@end deftypefun
+
+@comment math.h
+@comment ISO
+@deftypefun int signbit (@emph{float-type} @var{x})
+@code{signbit} is a generic macro which can work on all floating-point
+types.  It returns a nonzero value if the value of @var{x} has its sign
+bit set.
+
+This is not the same as @code{x < 0.0} since in some floating-point
+formats (e.g., @w{IEEE 754}) the zero value is optionally signed.  The
+comparison @code{-0.0 < 0.0} will not be true while @code{signbit
+(-0.0)} will return a nonzero value.
+@end deftypefun
+
+@comment math.h
+@comment ISO
+@deftypefun double nextafter (double @var{x}, double @var{y})
+@deftypefunx float nextafterf (float @var{x}, float @var{y})
+@deftypefunx {long double} nextafterl (long double @var{x}, long double @var{y})
+The @code{nextafter} function returns the next representable neighbor of
+@var{x} in the direction towards @var{y}.  Depending on the used data
+type the steps make have a different size.  If @math{@var{x} = @var{y}}
+the function simply returns @var{x}.  If either value is a @code{NaN}
+one the @code{NaN} values is returned.  Otherwise a value corresponding
+to the value of the least significant bit in the mantissa is
+added/subtracted (depending on the direction).  If the resulting value
+is not finite but @var{x} is, overflow is signaled.  Underflow is
+signaled if the resulting value is a denormalized number (if the @w{IEEE
+754}/@w{IEEE 854} representation is used).
+
+This function is defined in @w{IEC 559} (and the appendix with
+recommended functions in @w{IEEE 754}/@w{IEEE 854}).
+@end deftypefun
+
+@cindex NaN
+@comment math.h
+@comment ISO
+@deftypefun double nan (const char *@var{tagp})
+@deftypefunx float nanf (const char *@var{tagp})
+@deftypefunx {long double} nanl (const char *@var{tagp})
+The @code{nan} function returns a representation of the NaN value.  If
+quiet NaNs are supported by the platform a call like @code{nan
+("@var{n-char-sequence}")} is equivalent to @code{strtod
+("NAN(@var{n-char-sequence})")}.  The exact implementation is left
+unspecified but on systems using IEEE arithmethic the
+@var{n-char-sequence} specifies the bits of the mantissa for the NaN
+value.
+@end deftypefun
+
+
+@node Special arithmetic on FPs
+@section Special Arithmetic on FPs
+@cindex positive difference
+@cindex minimum
+@cindex maximum
+
+A frequent operation of numbers is the determination of mimuma, maxima,
+or the difference between numbers.  The @w{ISO C 9X} standard introduces
+three functions which implement this efficiently while also providing
+some useful functions which is not so efficient to implement.  Machine
+specific implementation might perform this very efficient.
+
+@comment math.h
+@comment ISO
+@deftypefun double fmin (double @var{x}, double @var{y})
+@deftypefunx float fminf (float @var{x}, float @var{y})
+@deftypefunx {long double} fminl (long double @var{x}, long double @var{y})
+The @code{fmin} function determine the minimum of the two values @var{x}
+and @var{y} and returns it.
+
+If an argument is NaN it as treated as missing and the other value is
+returned.  If both values are NaN one of the values is returned.
+@end deftypefun
+
+@comment math.h
+@comment ISO
+@deftypefun double fmax (double @var{x}, double @var{y})
+@deftypefunx float fmaxf (float @var{x}, float @var{y})
+@deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y})
+The @code{fmax} function determine the maximum of the two values @var{x}
+and @var{y} and returns it.
+
+If an argument is NaN it as treated as missing and the other value is
+returned.  If both values are NaN one of the values is returned.
+@end deftypefun
+
+@comment math.h
+@comment ISO
+@deftypefun double fdim (double @var{x}, double @var{y})
+@deftypefunx float fdimf (float @var{x}, float @var{y})
+@deftypefunx {long double} fdiml (long double @var{x}, long double @var{y})
+The @code{fdim} function computes the positive difference between
+@var{x} and @var{y} and returns this value.  @dfn{Positive difference}
+means that if @var{x} is greater than @var{y} the value @math{@var{x} -
+@var{y}} is returned.  Otherwise the return value is @math{+0}.
+
+If any of the arguments is NaN this value is returned.  If both values
+are NaN, one of the values is returned.
+@end deftypefun
+
+@comment math.h
+@comment ISO
+@deftypefun double fma (double @var{x}, double @var{y}, double @var{z})
+@deftypefunx float fmaf (float @var{x}, float @var{y}, float @var{z})
+@deftypefunx {long double} fmal (long double @var{x}, long double @var{y}, long double @var{z})
+@cindex butterfly
+The name of the function @code{fma} means floating-point multiply-add.
+I.e., the operation performed is @math{(@var{x} @mul{} @var{y}) +
+@var{z}}.  The speciality of this function is that the intermediate
+result is not rounded and the addition is performed with the full
+precision of the multiplcation.
+
+This function was introduced because some processors provide such a
+function in their FPU implementation.  Since compilers cannot optimize
+code which performs the operation in single steps using this opcode
+because of rounding differences the operation is available separately so
+the programmer can select when the rounding of the intermediate result
+is not important.
+
+@vindex FP_FAST_FMA
+If the @file{math.h} header defines the symbol @code{FP_FAST_FMA} (or
+@code{FP_FAST_FMAF} and @code{FP_FAST_FMAL} for @code{float} and
+@code{long double} respectively) the processor typically defines the
+operation in hardware.  The symbols might also be defined if the
+software implementation is as fast as a multiply and an add but in the
+GNU C Library the macros indicate hardware support.
+@end deftypefun
+
+
 @node Integer Division
 @section Integer Division
 @cindex integer division functions
diff --git a/manual/math.texi b/manual/math.texi
index 478678f236..d6206eb4fe 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -1,4 +1,5 @@
 @c We need some definitions here.
+@ifclear cdot
 @ifhtml
 @set cdot ·
 @end ifhtml
@@ -8,15 +9,16 @@
 @ifclear cdot
 @set cdot x
 @end ifclear
+@macro mul
+@value{cdot}
+@end macro
+@end ifclear
 @iftex
 @set infty @infty
 @end iftex
 @ifclear infty
 @set infty oo
 @end ifclear
-@macro mul
-@value{cdot}
-@end macro
 @macro infinity
 @value{infty}
 @end macro
diff --git a/manual/time.texi b/manual/time.texi
index b67ef63d5e..f38c2eb87c 100644
--- a/manual/time.texi
+++ b/manual/time.texi
@@ -531,6 +531,10 @@ might be overwritten by subsequent calls to @code{ctime}, @code{gmtime},
 or @code{localtime}.  (But no other library function overwrites the contents
 of this object.)
 
+The return value is the null pointer if @var{time} cannot be represented
+as a broken-down time; typically this is because the year cannot fit into
+an @code{int}.
+
 Calling @code{localtime} has one other effect: it sets the variable
 @code{tzname} with information about the current time zone.  @xref{Time
 Zone Functions}.
@@ -784,6 +788,18 @@ The day of the month like with @code{%d}, but padded with blank (range
 
 This format is a POSIX.2 extension.
 
+@item %f
+The day of the week as a decimal number (range @code{1} through
+@code{7}), Monday being @code{1}.
+
+This format is a @w{ISO C 9X} extension.
+
+@item %F
+The date using the format @code{%Y-%m-%d}.  This is the form specified
+in the @w{ISO 8601} standard and is the preferred form for all uses.
+
+This format is a @w{ISO C 9X} extension.
+
 @item %g
 The year corresponding to the ISO week number, but without the century
 (range @code{00} through @code{99}).  This has the same format and value
diff --git a/math/complex.h b/math/complex.h
index f4b1d4640c..72b1e597fc 100644
--- a/math/complex.h
+++ b/math/complex.h
@@ -40,9 +40,10 @@ __BEGIN_DECLS
    XXX This probably has to go into a gcc related file.  */
 #define _Complex_I	(1.0iF)
 
-/* Another more descriptive name is `I'.  */
+/* Another more descriptive name is `I'.
+   XXX Once we have the imaginary support switch this to _Imaginary_I.  */
 #undef I
-#define I _Imaginary_I
+#define I _Complex_I
 
 
 /* Optimization aids.  This is not yet implemented in gcc and once it
diff --git a/math/libm-test.c b/math/libm-test.c
index c77cbee855..5d68b4953b 100644
--- a/math/libm-test.c
+++ b/math/libm-test.c
@@ -4813,6 +4813,50 @@ llround_test (void)
 
 
 static void
+fma_test (void)
+{
+  check ("fma(1.0, 2.0, 3.0) = 5.0", FUNC(fma) (1.0, 2.0, 3.0), 5.0);
+  check_isnan ("fma(NaN, 2.0, 3.0) = NaN", FUNC(fma) (nan_value, 2.0, 3.0));
+  check_isnan ("fma(1.0, NaN, 3.0) = NaN", FUNC(fma) (1.0, nan_value, 3.0));
+  check_isnan_maybe_exc ("fma(1.0, 2.0, NaN) = NaN",
+			 FUNC(fma) (1.0, 2.0, nan_value), INVALID_EXCEPTION);
+  check_isnan_maybe_exc ("fma(+Inf, 0.0, NaN) = NaN",
+			 FUNC(fma) (plus_infty, 0.0, nan_value),
+			 INVALID_EXCEPTION);
+  check_isnan_maybe_exc ("fma(-Inf, 0.0, NaN) = NaN",
+			 FUNC(fma) (minus_infty, 0.0, nan_value),
+			 INVALID_EXCEPTION);
+  check_isnan_maybe_exc ("fma(0.0, +Inf, NaN) = NaN",
+			 FUNC(fma) (0.0, plus_infty, nan_value),
+			 INVALID_EXCEPTION);
+  check_isnan_maybe_exc ("fma(0.0, -Inf, NaN) = NaN",
+			 FUNC(fma) (0.0, minus_infty, nan_value),
+			 INVALID_EXCEPTION);
+  check_isnan_exc ("fma(+Inf, 0.0, 1.0) = NaN",
+		   FUNC(fma) (plus_infty, 0.0, 1.0), INVALID_EXCEPTION);
+  check_isnan_exc ("fma(-Inf, 0.0, 1.0) = NaN",
+		   FUNC(fma) (minus_infty, 0.0, 1.0), INVALID_EXCEPTION);
+  check_isnan_exc ("fma(0.0, +Inf, 1.0) = NaN",
+		   FUNC(fma) (0.0, plus_infty, 1.0), INVALID_EXCEPTION);
+  check_isnan_exc ("fma(0.0, -Inf, 1.0) = NaN",
+		   FUNC(fma) (0.0, minus_infty, 1.0), INVALID_EXCEPTION);
+
+  check_isnan_exc ("fma(+Inf, +Inf, -Inf) = NaN",
+		   FUNC(fma) (plus_infty, plus_infty, minus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("fma(-Inf, +Inf, +Inf) = NaN",
+		   FUNC(fma) (minus_infty, plus_infty, plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("fma(+Inf, -Inf, +Inf) = NaN",
+		   FUNC(fma) (plus_infty, minus_infty, plus_infty),
+		   INVALID_EXCEPTION);
+  check_isnan_exc ("fma(-Inf, -Inf, -Inf) = NaN",
+		   FUNC(fma) (minus_infty, minus_infty, minus_infty),
+		   INVALID_EXCEPTION);
+}
+
+
+static void
 inverse_func_pair_test (const char *test_name,
 			mathfunc f1, mathfunc inverse,
 			MATHTYPE x, MATHTYPE epsilon)
@@ -5205,6 +5249,7 @@ main (int argc, char *argv[])
   ctanh_test ();
   csqrt_test ();
   cpow_test ();
+  fma_test ();
 
   /* special tests */
   identities ();
diff --git a/math/math.h b/math/math.h
index 51055849ce..0aedaf1d56 100644
--- a/math/math.h
+++ b/math/math.h
@@ -68,37 +68,37 @@ __BEGIN_DECLS
 /* Include the file of declarations again, this time using `float'
    instead of `double' and appending f to each function name.  */
 
-#ifndef _Mfloat_
-# define _Mfloat_		float
-#endif
-#define _Mdouble_ 		_Mfloat_
-#ifdef __STDC__
-# define __MATH_PRECNAME(name,r) name##f##r
-#else
-# define __MATH_PRECNAME(name,r) name/**/f/**/r
-#endif
-#include <bits/mathcalls.h>
-#undef	_Mdouble_
-#undef	__MATH_PRECNAME
-
-#if __STDC__ - 0 || __GNUC__ - 0
-/* Include the file of declarations again, this time using `long double'
-   instead of `double' and appending l to each function name.  */
-
-# ifndef _Mlong_double_
-#  define _Mlong_double_	long double
+# ifndef _Mfloat_
+#  define _Mfloat_		float
 # endif
-# define _Mdouble_ 		_Mlong_double_
+# define _Mdouble_ 		_Mfloat_
 # ifdef __STDC__
-#  define __MATH_PRECNAME(name,r) name##l##r
+#  define __MATH_PRECNAME(name,r) name##f##r
 # else
-#  define __MATH_PRECNAME(name,r) name/**/l/**/r
+#  define __MATH_PRECNAME(name,r) name/**/f/**/r
 # endif
 # include <bits/mathcalls.h>
 # undef	_Mdouble_
 # undef	__MATH_PRECNAME
 
-#endif /* __STDC__ || __GNUC__ */
+# if __STDC__ - 0 || __GNUC__ - 0
+/* Include the file of declarations again, this time using `long double'
+   instead of `double' and appending l to each function name.  */
+
+#  ifndef _Mlong_double_
+#   define _Mlong_double_	long double
+#  endif
+#  define _Mdouble_ 		_Mlong_double_
+#  ifdef __STDC__
+#   define __MATH_PRECNAME(name,r) name##l##r
+#  else
+#   define __MATH_PRECNAME(name,r) name/**/l/**/r
+#  endif
+#  include <bits/mathcalls.h>
+#  undef _Mdouble_
+#  undef __MATH_PRECNAME
+
+# endif /* __STDC__ || __GNUC__ */
 
 #endif	/* Use misc or ISO C 9X.  */
 #undef	__MATHDECL_1
@@ -118,23 +118,23 @@ extern int signgam;
 /* Get the architecture specific values describing the floating-point
    evaluation.  The following symbols will get defined:
 
-     float_t	floating-point type at least as wide as `float' used
+    float_t	floating-point type at least as wide as `float' used
 		to evaluate `float' expressions
-     double_t	floating-point type at least as wide as `double' used
+    double_t	floating-point type at least as wide as `double' used
 		to evaluate `double' expressions
 
-     FLT_EVAL_METHOD
+    FLT_EVAL_METHOD
 		Defined to
 		  0	if `float_t' is `float' and `double_t' is `double'
 		  1	if `float_t' and `double_t' are `double'
 		  2	if `float_t' and `double_t' are `long double'
 		  else	`float_t' and `double_t' are unspecified
 
-     INFINITY	representation of the infinity value of type `float_t'
+    INFINITY	representation of the infinity value of type `float'
 
-     FP_FAST_FMA
-     FP_FAST_FMAF
-     FP_FAST_FMAL
+    FP_FAST_FMA
+    FP_FAST_FMAF
+    FP_FAST_FMAL
 		If defined it indicates that the the `fma' function
 		generally executes about as fast as a multiply and an add.
 		This macro is defined only iff the `fma' function is
@@ -143,6 +143,9 @@ extern int signgam;
     FP_ILOGB0	Expands to a value returned by `ilogb (0.0)'.
     FP_ILOGBNAN	Expands to a value returned by `ilogb (NAN)'.
 
+    DECIMAL_DIG	Number of decimal digits supported by conversion between
+		decimal and all internal floating-point formats.
+
 */
 # include <bits/mathdef.h>
 
@@ -211,8 +214,8 @@ extern _LIB_VERSION_TYPE _LIB_VERSION;
 /* In SVID error handling, `matherr' is called with this description
    of the exceptional condition.
 
-   We have a problem when using C++ since `exception' is reserved in
-   C++.  */
+   We have a problem when using C++ since `exception' is a reserved
+   name in C++.  */
 # ifdef __cplusplus
 struct __exception
 # else
@@ -307,7 +310,7 @@ extern int matherr __P ((struct exception *__exc));
    for unordered numbers.  Since many FPUs provide special
    instructions to support these operations and these tests are
    defined in <bits/mathinline.h>, we define the generic macros at
-   this late point.  */
+   this late point and only if they are not defined yet.  */
 
 /* Return nonzero value if X is greater than Y.  */
 # ifndef isgreater
diff --git a/string/strndup.c b/string/strndup.c
index 6bcfa9a445..cd971e1c6f 100644
--- a/string/strndup.c
+++ b/string/strndup.c
@@ -35,7 +35,9 @@ char *malloc ();
 #endif
 
 char *
-__strndup (const char *s, size_t n)
+__strndup (s, n)
+     const char *s;
+     size_t n;
 {
   size_t len = strnlen (s, n);
   char *new = malloc (len + 1);
diff --git a/sunrpc/xcrypt.c b/sunrpc/xcrypt.c
index df191f5ad2..ec4110036c 100644
--- a/sunrpc/xcrypt.c
+++ b/sunrpc/xcrypt.c
@@ -31,7 +31,9 @@
  * Copyright (c) 1986-1991 by Sun Microsystems Inc.
  */
 
+#if 0
 #ident	"@(#)xcrypt.c	1.11	94/08/23 SMI"
+#endif
 
 #if !defined(lint) && defined(SCCSIDS)
 static char sccsid[] = "@(#)xcrypt.c 1.3 89/03/24 Copyr 1986 Sun Micro";
diff --git a/sysdeps/alpha/fpu/bits/mathdef.h b/sysdeps/alpha/fpu/bits/mathdef.h
index 0bc9c94ecc..1c259403f5 100644
--- a/sysdeps/alpha/fpu/bits/mathdef.h
+++ b/sysdeps/alpha/fpu/bits/mathdef.h
@@ -17,38 +17,38 @@
    Boston, MA 02111-1307, USA.  */
 
 #ifndef _MATH_H
-#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
 #endif
 
 /* FIXME! This file describes properties of the compiler, not the machine;
    it should not be part of libc!  */
 
 #ifdef __GNUC__
-#if __STDC__ == 1
+# if __STDC__ == 1
 
 /* In GNU or ANSI mode, gcc leaves `float' expressions as-is.  */
 typedef float float_t;
 typedef double double_t;
 
 /* Signal that types stay as they were declared.  */
-#define FLT_EVAL_METHOD	0
+#  define FLT_EVAL_METHOD	0
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VALF
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#else 
+# else
 
 /* For `gcc -traditional', `float' expressions are evaluated as `double'. */
 typedef double float_t;
 typedef double double_t;
 
 /* Signal that both types are `double'.  */
-#define FLT_EVAL_METHOD	1
+#  define FLT_EVAL_METHOD	1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#endif
+# endif
 #else
 
 /* Wild guess at types for float_t and double_t. */
@@ -56,9 +56,12 @@ typedef double float_t;
 typedef double double_t;
 
 /* Strange compiler, we don't know how it works.  */
-#define FLT_EVAL_METHOD	-1
+# define FLT_EVAL_METHOD	-1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+# define INFINITY	HUGE_VALF
 
 #endif
+
+/* Number of decimal digits for the `double' type.  */
+#define DECIMAL_DIG	15
diff --git a/sysdeps/generic/bits/mathdef.h b/sysdeps/generic/bits/mathdef.h
index 93b60bd25f..15140997c0 100644
--- a/sysdeps/generic/bits/mathdef.h
+++ b/sysdeps/generic/bits/mathdef.h
@@ -31,10 +31,13 @@ typedef double double_t;	/* `double' expressions are evaluated as
 /* Signal that both types are `double'.  */
 #define FLT_EVAL_METHOD	1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+#define INFINITY	HUGE_VALF
 
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0	0x80000001
 #define FP_ILOGBNAN	0x7fffffff
+
+/* Number of decimal digits for the `double' type.  */
+#define DECIMAL_DIG	15
diff --git a/sysdeps/generic/bits/stat.h b/sysdeps/generic/bits/stat.h
index dab0cd00cb..3648fed738 100644
--- a/sysdeps/generic/bits/stat.h
+++ b/sysdeps/generic/bits/stat.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1996, 1997 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
@@ -70,5 +70,23 @@ struct stat
 #define	__S_IWRITE	0200	/* Write by owner.  */
 #define	__S_IEXEC	0100	/* Execute by owner.  */
 
+#ifdef __USE_LARGEFILE64
+struct stat64
+  {
+    __dev_t st_dev;			/* Device.  */
+
+    __ino64_t st_ino;			/* File serial number.	*/
+    __mode_t st_mode;			/* File mode.  */
+    __nlink_t st_nlink;			/* Link count.  */
+    __uid_t st_uid;			/* User ID of the file's owner.	*/
+    __gid_t st_gid;			/* Group ID of the file's group.*/
+    __off64_t st_size;			/* Size of file, in bytes.  */
+
+    __time_t st_atime;			/* Time of last access.  */
+    __time_t st_mtime;			/* Time of last modification.  */
+    __time_t st_ctime;			/* Time of last status change.  */
+  };
+#endif
+
 
 #endif /* bits/stat.h */
diff --git a/sysdeps/generic/bits/types.h b/sysdeps/generic/bits/types.h
index fdb36f0b54..51fadd196e 100644
--- a/sysdeps/generic/bits/types.h
+++ b/sysdeps/generic/bits/types.h
@@ -67,6 +67,8 @@ typedef __u_quad_t __fsid_t;	/* Type of file system IDs.  */
 typedef long int __clock_t;	/* Type of CPU usage counts.  */
 typedef long int __rlim_t;	/* Type for resource measurement.  */
 typedef __quad_t __rlim64_t;	/* Type for resource measurement (LFS).  */
+typedef __quad_t __ino64_t;	/* Type for file serial numbers.  */
+typedef __loff_t __off64_t;	/* Type of file izes and offsets.  */
 
 /* Everythin' else.  */
 typedef long int __daddr_t;	/* The type of a disk address.  */
diff --git a/sysdeps/i386/fpu/bits/mathdef.h b/sysdeps/i386/fpu/bits/mathdef.h
index 2387a39510..9d0bd840a3 100644
--- a/sysdeps/i386/fpu/bits/mathdef.h
+++ b/sysdeps/i386/fpu/bits/mathdef.h
@@ -22,8 +22,8 @@
 
 
 /* The ix87 FPUs evaluate all values in the 80 bit floating-point format
-   which is also available for the user as `long double'.  Therefore
-   we define:  */
+   which is also available for the user as `long double'.  Therefore we
+   define:  */
 typedef long double float_t;	/* `float' expressions are evaluated as
 				   `long double'.  */
 typedef long double double_t;	/* `double' expressions are evaluated as
@@ -32,10 +32,12 @@ typedef long double double_t;	/* `double' expressions are evaluated as
 /* Signal that both types are `long double'.  */
 #define FLT_EVAL_METHOD	2
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VALL
-
+/* Define `INFINITY' as value of type `float'.  */
+#define INFINITY	HUGE_VALF
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0	0x80000000
 #define FP_ILOGBNAN	0x80000000
+
+/* Number of decimal digits for the `long double' type.  */
+#define DECIMAL_DIG	18
diff --git a/sysdeps/ieee754/bits/nan.h b/sysdeps/ieee754/bits/nan.h
index 94988ced9c..05a9d6af2a 100644
--- a/sysdeps/ieee754/bits/nan.h
+++ b/sysdeps/ieee754/bits/nan.h
@@ -26,12 +26,7 @@
 
 #ifdef	__GNUC__
 
-# define NAN                                                                 \
-  (__extension__                                                            \
-   ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
-    { __l: 0x7ff8000000000000ULL }).__d)
-
-# define NANF                                                                \
+# define NAN \
   (__extension__                                                            \
    ((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; })  \
     { __l: 0x7fc00000UL }).__d)
@@ -41,23 +36,13 @@
 # include <endian.h>
 
 # if __BYTE_ORDER == __BIG_ENDIAN
-#  define __nan_bytes		{ 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }
-#  define __nanf_bytes		{ 0x7f, 0xc0, 0, 0 }
+#  define __nan_bytes		{ 0x7f, 0xc0, 0, 0 }
 # endif
 # if __BYTE_ORDER == __LITTLE_ENDIAN
-#  define __nan_bytes		{ 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
-#  define __nanf_bytes		{ 0, 0, 0xc0, 0x7f }
+#  define __nan_bytes		{ 0, 0, 0xc0, 0x7f }
 # endif
 
-static union { unsigned char __c[8]; double __d; } __nan = { __nan_bytes };
+static union { unsigned char __c[4]; double __d; } __nan = { __nan_bytes };
 # define NAN	(__nan.__d)
 
-static union { unsigned char __c[4]; double __d; } __nanf = { __nanf_bytes };
-# define NANF	(__nanf.__d)
-
 #endif	/* GCC.  */
-
-/* Generally there is no separate `long double' format and it is the
-   same as `double'.  */
-
-#define NANL  NAN
diff --git a/sysdeps/m68k/bits/nan.h b/sysdeps/m68k/bits/nan.h
deleted file mode 100644
index b4efddfe91..0000000000
--- a/sysdeps/m68k/bits/nan.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* `NAN' constants for m68k.
-   Copyright (C) 1997 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 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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#ifndef	_NAN_H
-
-#define	_NAN_H	1
-
-/* IEEE Not A Number.  */
-
-#ifdef	__GNUC__
-
-#define NAN							\
-  (__extension__						\
-   ((union { unsigned long long __l; double __d; })		\
-    { __l: 0x7fffffffffffffffULL }).__d)
-
-#define NANF							\
-  (__extension__						\
-   ((union { unsigned long __l; float __f; })			\
-    { __l: 0x7fffffffUL }).__f)
-
-#define NANL							\
-  (__extension__						\
-   ((union { unsigned long __l[3]; long double __ld; })		\
-    { __l: { 0x7fff0000UL, 0xffffffffUL, 0xffffffffUL } }).__ld)
-
-#else
-
-static union { unsigned char __c[8]; double __d; } __nan =
-  { { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
-#define	NAN	(__nan.__d)
-
-static union { unsigned char __c[4]; float __f; } __nanf =
-  { { 0x7f, 0xff, 0xff, 0xff } };
-#define	NANF	(__nanf.__f)
-
-static union { unsigned char __c[12]; long double __ld; } __nanl =
-  { { 0x7f, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
-#define	NANL	(__nanl.__ld)
-
-#endif	/* GCC.  */
-
-#endif	/* nan.h */
diff --git a/sysdeps/m68k/fpu/bits/mathdef.h b/sysdeps/m68k/fpu/bits/mathdef.h
index c2b4eff920..e3d33a53a2 100644
--- a/sysdeps/m68k/fpu/bits/mathdef.h
+++ b/sysdeps/m68k/fpu/bits/mathdef.h
@@ -32,9 +32,12 @@ typedef long double double_t;	/* `double' expressions are evaluated as
 /* Signal that both types are `long double'.  */
 #define FLT_EVAL_METHOD	2
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VALL
+/* Define `INFINITY' as value of type `float'.  */
+#define INFINITY	HUGE_VALF
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0	0x80000000
 #define FP_ILOGBNAN	0x7fffffff
+
+/* Number of decimal digits for the `long double' type.  */
+#define DECIMAL_DIG	18
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index 2ae3c1e897..d40d8d6822 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -190,12 +190,17 @@ extern char *alloca ();
 # define __getcwd getcwd
 #endif
 
+#ifndef GETCWD_STORAGE_CLASS
+# define GETCWD_STORAGE_CLASS
+#endif
+
 /* Get the pathname of the current working directory, and put it in SIZE
    bytes of BUF.  Returns NULL if the directory couldn't be determined or
    SIZE was too small.  If successful, returns BUF.  In GNU, if BUF is
    NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
    unless SIZE <= 0, in which case it is as big as necessary.  */
 
+GETCWD_STORAGE_CLASS
 char *
 __getcwd (buf, size)
      char *buf;
@@ -396,6 +401,6 @@ __getcwd (buf, size)
   return NULL;
 }
 
-#ifdef _LIBC
+#if defined _LIBC && !defined __getcwd
 weak_alias (__getcwd, getcwd)
 #endif
diff --git a/sysdeps/powerpc/bits/mathdef.h b/sysdeps/powerpc/bits/mathdef.h
index 9f91863333..3923a5401a 100644
--- a/sysdeps/powerpc/bits/mathdef.h
+++ b/sysdeps/powerpc/bits/mathdef.h
@@ -17,7 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #ifndef _MATH_H
-#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
 #endif
 
 
@@ -28,7 +28,7 @@
    gcc! */
 
 #ifdef __GNUC__
-#if __STDC__ == 1
+# if __STDC__ == 1
 
 /* In GNU or ANSI mode, gcc leaves `float' expressions as-is.  */
 typedef float float_t;		/* `float' expressions are evaluated as
@@ -37,12 +37,12 @@ typedef double double_t;	/* `double' expressions are evaluated as
 				   `double'.  */
 
 /* Signal that types stay as they were declared.  */
-#define FLT_EVAL_METHOD	0
+#  define FLT_EVAL_METHOD	0
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VALF
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#else 
+# else
 
 /* For `gcc -traditional', `float' expressions are evaluated as `double'. */
 typedef double float_t;		/* `float' expressions are evaluated as
@@ -51,12 +51,12 @@ typedef double double_t;	/* `double' expressions are evaluated as
 				   `double'.  */
 
 /* Signal that both types are `double'.  */
-#define FLT_EVAL_METHOD	1
+#  define FLT_EVAL_METHOD	1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#endif
+# endif
 #else
 
 /* Wild guess at types for float_t and double_t. */
@@ -64,13 +64,16 @@ typedef double float_t;
 typedef double double_t;
 
 /* Strange compiler, we don't know how it works.  */
-#define FLT_EVAL_METHOD	-1
+# define FLT_EVAL_METHOD	-1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+# define INFINITY	HUGE_VALF
 
 #endif
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0	0x80000001
 #define FP_ILOGBNAN	0x7fffffff
+
+/* Number of decimal digits for the `double' type.  */
+#define DECIMAL_DIG	15
diff --git a/sysdeps/sparc/fpu/bits/mathdef.h b/sysdeps/sparc/fpu/bits/mathdef.h
index 505d724fd0..135531067b 100644
--- a/sysdeps/sparc/fpu/bits/mathdef.h
+++ b/sysdeps/sparc/fpu/bits/mathdef.h
@@ -17,38 +17,38 @@
    Boston, MA 02111-1307, USA.  */
 
 #ifndef _MATH_H
-#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
+# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
 #endif
 
 /* FIXME! This file describes properties of the compiler, not the machine;
    it should not be part of libc!  */
 
 #ifdef __GNUC__
-#if __STDC__ == 1
+# if __STDC__ == 1
 
 /* In GNU or ANSI mode, gcc leaves `float' expressions as-is.  */
 typedef float float_t;
 typedef double double_t;
 
 /* Signal that types stay as they were declared.  */
-#define FLT_EVAL_METHOD	0
+#  define FLT_EVAL_METHOD	0
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VALF
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#else 
+# else
 
 /* For `gcc -traditional', `float' expressions are evaluated as `double'. */
 typedef double float_t;
 typedef double double_t;
 
 /* Signal that both types are `double'.  */
-#define FLT_EVAL_METHOD	1
+#  define FLT_EVAL_METHOD	1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+#  define INFINITY	HUGE_VALF
 
-#endif
+# endif
 #else
 
 /* Wild guess at types for float_t and double_t. */
@@ -56,13 +56,16 @@ typedef double float_t;
 typedef double double_t;
 
 /* Strange compiler, we don't know how it works.  */
-#define FLT_EVAL_METHOD	-1
+# define FLT_EVAL_METHOD	-1
 
-/* Define `INFINITY' as value of type `float_t'.  */
-#define INFINITY	HUGE_VAL
+/* Define `INFINITY' as value of type `float'.  */
+# define INFINITY	HUGE_VALF
 
 #endif
 
 /* The values returned by `ilogb' for 0 and NaN respectively.  */
 #define FP_ILOGB0       0x80000001
 #define FP_ILOGBNAN     0x7fffffff
+
+/* Number of decimal digits for the `double' type.  */
+#define DECIMAL_DIG	15
diff --git a/sysdeps/unix/arm/sysdep.S b/sysdeps/unix/arm/sysdep.S
index 5d3ad551c6..d59500e47a 100644
--- a/sysdeps/unix/arm/sysdep.S
+++ b/sysdeps/unix/arm/sysdep.S
@@ -18,13 +18,13 @@
 
 #include <sysdep.h>
 #define _ERRNO_H
-#include <errnos.h>
+#include <bits/errno.h>
 
 .globl C_SYMBOL_NAME(errno)
 .globl syscall_error
 
 _errno_loc:	.long C_SYMBOL_NAME(errno)
-	
+
 #undef syscall_error
 #ifdef NO_UNDERSCORES
 __syscall_error:
@@ -39,7 +39,7 @@ syscall_error:
 	moveq r0, $EAGAIN	/* Yes; translate it to EAGAIN.  */
 #endif
 #ifndef	PIC
-	ldr r1, _errno_loc	
+	ldr r1, _errno_loc
 	str r0, [r1]
 #endif
 	mvn r0, $0
diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h
index 802cbd5d63..d84e70e7ff 100644
--- a/sysdeps/unix/sysv/linux/arm/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h
@@ -22,5 +22,5 @@
 void
 profil_counter (int signo, struct sigcontext sc)
 {
-  profil_count ((void *) sc.eip);
+  profil_count ((void *) sc.reg.ARM_pc);
 }
diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h
index 0aa085d351..af08277a63 100644
--- a/sysdeps/unix/sysv/linux/arm/sysdep.h
+++ b/sysdeps/unix/sysv/linux/arm/sysdep.h
@@ -29,8 +29,8 @@
    of the kernel.  But these symbols do not follow the SYS_* syntax
    so we have to redefine the `SYS_ify' macro here.  */
 #undef SYS_ify
-#define SWI_BASE  (9 << 20)
-#define SYS_ify(syscall_name)	(SWI_BASE + __NR_##syscall_name)
+#define SWI_BASE  (0x900000)
+#define SYS_ify(syscall_name)	(__NR_##syscall_name)
 
 
 #ifdef ASSEMBLER
diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c
new file mode 100644
index 0000000000..eea0b469e1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/getcwd.c
@@ -0,0 +1,94 @@
+/* Determine current working directory.  Linux version.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* #define NDEBUG 1 */
+#include <assert.h>
+
+/* The "proc" filesystem provides an easy method to retrieve the value.
+   For each process, the corresponding directory contains a symbolic link
+   named `cwd'.  Reading the content of this link immediate gives us the
+   information.  But we have to take care for systems which do not have
+   the proc filesystem mounted.  Use the POSIX implementation in this case.  */
+static char *generic_getcwd (char *buf, size_t size);
+
+char *
+__getcwd (char *buf, size_t size)
+{
+  int save_errno;
+  char *path;
+  int n;
+  char *result;
+
+  if (size == 0)
+    {
+      if (buf != NULL)
+	{
+	  __set_errno (EINVAL);
+	  return NULL;
+	}
+
+      size = PATH_MAX + 1;
+    }
+
+  if (buf != NULL)
+    path = buf;
+  else
+    {
+      path = malloc (size);
+      if (path == NULL)
+	return NULL;
+    }
+
+  save_errno = errno;
+  n = __readlink ("/proc/self/cwd", path, size);
+  if (n != -1)
+    {
+      if (n >= size)
+	{
+	  /* This should never happen when we allocate the buffer here.  */
+	  assert (buf == NULL);
+	  __set_errno (ERANGE);
+	  return NULL;
+	}
+      path[n] = '\0';
+      return buf ?: (char *) realloc (path, (size_t) n + 1);
+    }
+
+  /* Something went wrong.  Restore the error number and use the generic
+     version.  */
+  __set_errno (save_errno);
+  result = generic_getcwd (path, size);
+
+  if (result == NULL && buf == NULL)
+    free (path);
+
+  return result;
+}
+weak_alias (__getcwd, getcwd)
+
+/* Get the code for the generic version.  */
+#define GETCWD_STORAGE_CLASS	static
+#define __getcwd		generic_getcwd
+#include <sysdeps/posix/getcwd.c>
diff --git a/sysdeps/wordsize-32/inttypes.h b/sysdeps/wordsize-32/inttypes.h
index 7bb8cbd5bc..371b40bb3d 100644
--- a/sysdeps/wordsize-32/inttypes.h
+++ b/sysdeps/wordsize-32/inttypes.h
@@ -353,7 +353,7 @@ typedef unsigned long long int uint_fast64_t;
 
 /* Limits of `sig_atomic_t'.  */
 #define SIG_ATOMIC_MIN	(-2147483647-1)
-#define SIG_ATOMIC_MAX	(-2147483647-1)
+#define SIG_ATOMIC_MAX	(2147483647)
 
 /* Limit of `size_t' type.  */
 #define SIZE_MAX	(4294967295U)
diff --git a/sysdeps/wordsize-64/inttypes.h b/sysdeps/wordsize-64/inttypes.h
index 9967fc0844..5f11fc9cb1 100644
--- a/sysdeps/wordsize-64/inttypes.h
+++ b/sysdeps/wordsize-64/inttypes.h
@@ -353,7 +353,7 @@ typedef unsigned long int uint_fast64_t;
 
 /* Limits of `sig_atomic_t'.  */
 #define SIG_ATOMIC_MIN	(-2147483647-1)
-#define SIG_ATOMIC_MAX	(-2147483647-1)
+#define SIG_ATOMIC_MAX	(2147483647)
 
 /* Limit of `size_t' type.  */
 #define SIZE_MAX	(18446744073709551615uL)
diff --git a/time/mktime.c b/time/mktime.c
index 7a94c21244..406f55e170 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -102,6 +102,9 @@ const unsigned short int __mon_yday[2][13] =
     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
   };
 
+static struct tm *ranged_convert __P ((struct tm *(*) __P ((const time_t *,
+							    struct tm *)),
+				       time_t *, struct tm *));
 static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
 time_t __mktime_internal __P ((struct tm *,
 			       struct tm *(*) (const time_t *, struct tm *),
@@ -134,30 +137,36 @@ localtime_r (t, tp)
    measured in seconds, ignoring leap seconds.
    YEAR uses the same numbering as TM->tm_year.
    All values are in range, except possibly YEAR.
+   If TP is null, return a nonzero value.
    If overflow occurs, yield the low order bits of the correct answer.  */
 static time_t
 ydhms_tm_diff (year, yday, hour, min, sec, tp)
      int year, yday, hour, min, sec;
      const struct tm *tp;
 {
-  /* Compute intervening leap days correctly even if year is negative.
-     Take care to avoid int overflow.  time_t overflow is OK, since
-     only the low order bits of the correct time_t answer are needed.
-     Don't convert to time_t until after all divisions are done, since
-     time_t might be unsigned.  */
-  int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
-  int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
-  int a100 = a4 / 25 - (a4 % 25 < 0);
-  int b100 = b4 / 25 - (b4 % 25 < 0);
-  int a400 = a100 >> 2;
-  int b400 = b100 >> 2;
-  int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
-  time_t years = year - (time_t) tp->tm_year;
-  time_t days = (365 * years + intervening_leap_days
-		 + (yday - tp->tm_yday));
-  return (60 * (60 * (24 * days + (hour - tp->tm_hour))
-		+ (min - tp->tm_min))
-	  + (sec - tp->tm_sec));
+  if (!tp)
+    return 1;
+  else
+    {
+      /* Compute intervening leap days correctly even if year is negative.
+	 Take care to avoid int overflow.  time_t overflow is OK, since
+	 only the low order bits of the correct time_t answer are needed.
+	 Don't convert to time_t until after all divisions are done, since
+	 time_t might be unsigned.  */
+      int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
+      int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
+      int a100 = a4 / 25 - (a4 % 25 < 0);
+      int b100 = b4 / 25 - (b4 % 25 < 0);
+      int a400 = a100 >> 2;
+      int b400 = b100 >> 2;
+      int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+      time_t years = year - (time_t) tp->tm_year;
+      time_t days = (365 * years + intervening_leap_days
+		     + (yday - tp->tm_yday));
+      return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+		    + (min - tp->tm_min))
+	      + (sec - tp->tm_sec));
+    }
 }
 
 
@@ -178,6 +187,54 @@ mktime (tp)
   return __mktime_internal (tp, localtime_r, &localtime_offset);
 }
 
+/* Use CONVERT to convert *T to a broken down time in *TP.
+   If *T is out of range for conversion, adjust it so that
+   it is the nearest in-range value and then convert that.  */
+static struct tm *
+ranged_convert (convert, t, tp)
+     struct tm *(*convert) __P ((const time_t *, struct tm *));
+     time_t *t;
+     struct tm *tp;
+{
+  struct tm *r;
+
+  if (! (r = (*convert) (t, tp)) && *t)
+    {
+      time_t bad = *t;
+      time_t ok = 0;
+      struct tm tm;
+
+      /* BAD is a known unconvertible time_t, and OK is a known good one.
+	 Use binary search to narrow the range between BAD and OK until
+	 they differ by 1.  */
+      while (bad != ok + (bad < 0 ? -1 : 1))
+	{
+	  time_t mid = *t = (bad < 0
+			     ? bad + ((ok - bad) >> 1)
+			     : ok + ((bad - ok) >> 1));
+	  if ((r = (*convert) (t, tp)))
+	    {
+	      tm = *r;
+	      ok = mid;
+	    }
+	  else
+	    bad = mid;
+	}
+
+      if (!r && ok)
+	{
+	  /* The last conversion attempt failed;
+	     revert to the most recent successful attempt.  */
+	  *t = ok;
+	  *tp = tm;
+	  r = tp;
+	}
+    }
+
+  return r;
+}
+
+
 /* Convert *TP to a time_t value, inverting
    the monotonic and mostly-unit-linear conversion function CONVERT.
    Use *OFFSET to keep track of a guess at the offset of the result,
@@ -243,7 +300,8 @@ __mktime_internal (tp, convert, offset)
   t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
 
   for (t = t0 + *offset;
-       (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
+       (dt = ydhms_tm_diff (year, yday, hour, min, sec,
+			    ranged_convert (convert, &t, &tm)));
        t += dt)
     if (--remaining_probes == 0)
       return -1;
@@ -263,7 +321,7 @@ __mktime_internal (tp, convert, offset)
 	    {
 	      struct tm otm;
 	      if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
-					 (*convert) (&ot, &otm))))
+					 ranged_convert (convert, &ot, &otm))))
 		{
 		  t = ot;
 		  tm = otm;
@@ -283,7 +341,8 @@ __mktime_internal (tp, convert, offset)
       /* Adjust time to reflect the tm_sec requested, not the normalized value.
 	 Also, repair any damage from a false match due to a leap second.  */
       t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
-      (*convert) (&t, &tm);
+      if (! (*convert) (&t, &tm))
+	return -1;
     }
 #endif
 
@@ -333,25 +392,28 @@ static void
 print_tm (tp)
      struct tm *tp;
 {
-  printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
-	  tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
-	  tp->tm_hour, tp->tm_min, tp->tm_sec,
-	  tp->tm_yday, tp->tm_wday, tp->tm_isdst);
+  if (tp)
+    printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
+	    tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
+	    tp->tm_hour, tp->tm_min, tp->tm_sec,
+	    tp->tm_yday, tp->tm_wday, tp->tm_isdst);
+  else
+    printf ("0");
 }
 
 static int
-check_result (tk, tmk, tl, tml)
+check_result (tk, tmk, tl, lt)
      time_t tk;
      struct tm tmk;
      time_t tl;
-     struct tm tml;
+     struct tm *lt;
 {
-  if (tk != tl || not_equal_tm (&tmk, &tml))
+  if (tk != tl || !lt || not_equal_tm (&tmk, lt))
     {
       printf ("mktime (");
       print_tm (&tmk);
       printf (")\nyields (");
-      print_tm (&tml);
+      print_tm (lt);
       printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
       return 1;
     }
@@ -366,6 +428,7 @@ main (argc, argv)
 {
   int status = 0;
   struct tm tm, tmk, tml;
+  struct tm *lt;
   time_t tk, tl;
   char trailer;
 
@@ -382,11 +445,16 @@ main (argc, argv)
       tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
       tmk = tm;
       tl = mktime (&tmk);
-      tml = *localtime (&tl);
+      lt = localtime (&tl);
+      if (lt)
+	{
+	  tml = *lt;
+	  lt = &tml;
+	}
       printf ("mktime returns %ld == ", (long) tl);
       print_tm (&tmk);
       printf ("\n");
-      status = check_result (tl, tmk, tl, tml);
+      status = check_result (tl, tmk, tl, lt);
     }
   else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
     {
@@ -397,19 +465,35 @@ main (argc, argv)
       if (argc == 4)
 	for (tl = from; tl <= to; tl += by)
 	  {
-	    tml = *localtime (&tl);
-	    tmk = tml;
-	    tk = mktime (&tmk);
-	    status |= check_result (tk, tmk, tl, tml);
+	    lt = localtime (&tl);
+	    if (lt)
+	      {
+		tmk = tml = *lt;
+		tk = mktime (&tmk);
+		status |= check_result (tk, tmk, tl, tml);
+	      }
+	    else
+	      {
+		printf ("localtime (%ld) yields 0\n", (long) tl);
+		status = 1;
+	      }
 	  }
       else
 	for (tl = from; tl <= to; tl += by)
 	  {
 	    /* Null benchmark.  */
-	    tml = *localtime (&tl);
-	    tmk = tml;
-	    tk = tl;
-	    status |= check_result (tk, tmk, tl, tml);
+	    lt = localtime (&tl);
+	    if (lt)
+	      {
+		tmk = tml = *lt;
+		tk = tl;
+		status |= check_result (tk, tmk, tl, tml);
+	      }
+	    else
+	      {
+		printf ("localtime (%ld) yields 0\n", (long) tl);
+		status = 1;
+	      }
 	  }
     }
   else
@@ -426,6 +510,6 @@ main (argc, argv)
 
 /*
 Local Variables:
-compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
+compile-command: "gcc -DDEBUG -D__EXTENSIONS__ -DHAVE_LIMITS_H -DHAVE_LOCALTIME_R -DSTDC_HEADERS -Wall -W -O -g mktime.c -o mktime"
 End:
 */
diff --git a/time/offtime.c b/time/offtime.c
index a4b59ed209..52e40703c8 100644
--- a/time/offtime.c
+++ b/time/offtime.c
@@ -26,8 +26,9 @@ extern const unsigned short int __mon_yday[2][13];
 
 /* Compute the `struct tm' representation of *T,
    offset OFFSET seconds east of UTC,
-   and store year, yday, mon, mday, wday, hour, min, sec into *TP.  */
-void
+   and store year, yday, mon, mday, wday, hour, min, sec into *TP.
+   Return nonzero if successful.  */
+int
 __offtime (t, offset, tp)
      const time_t *t;
      long int offset;
@@ -59,7 +60,8 @@ __offtime (t, offset, tp)
     tp->tm_wday += 7;
   y = 1970;
 
-#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
+#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
+#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
 
   while (days < 0 || days >= (__isleap (y) ? 366 : 365))
     {
@@ -73,6 +75,8 @@ __offtime (t, offset, tp)
       y = yg;
     }
   tp->tm_year = y - 1900;
+  if (tp->tm_year != y - 1900)
+    return 0;
   tp->tm_yday = days;
   ip = __mon_yday[__isleap(y)];
   for (y = 11; days < (long int) ip[y]; --y)
@@ -80,4 +84,5 @@ __offtime (t, offset, tp)
   days -= ip[y];
   tp->tm_mon = y;
   tp->tm_mday = days + 1;
+  return 1;
 }
diff --git a/time/strftime.c b/time/strftime.c
index e66a444d40..0ebc913090 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -182,7 +182,7 @@ localtime_r (t, tp)
   return tp;
 }
 # endif /* ! HAVE_LOCALTIME_R */
-#endif /* ! defined (_LIBC) */
+#endif /* ! defined _LIBC */
 
 
 #if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
@@ -202,7 +202,7 @@ static const char zeroes[16] = /* "0000000000000000" */
     do									      \
       {									      \
 	int _this = _len > 16 ? 16 : _len;				      \
-	(P) = mempcpy ((P), spaces, _this);				      \
+	(P) = MEMPCPY ((P), spaces, _this);				      \
 	_len -= _this;							      \
       }									      \
     while (_len > 0);							      \
@@ -215,7 +215,7 @@ static const char zeroes[16] = /* "0000000000000000" */
     do									      \
       {									      \
 	int _this = _len > 16 ? 16 : _len;				      \
-	(P) = mempcpy ((P), zeroes, _this);				      \
+	(P) = MEMPCPY ((P), zeroes, _this);				      \
 	_len -= _this;							      \
       }									      \
     while (_len > 0);							      \
diff --git a/time/time.h b/time/time.h
index f60599d2cb..3e039adfa4 100644
--- a/time/time.h
+++ b/time/time.h
@@ -226,10 +226,11 @@ extern struct tm *localtime_r __P ((__const time_t *__timer,
 
 /* Compute the `struct tm' representation of *T,
    offset OFFSET seconds east of UTC,
-   and store year, yday, mon, mday, wday, hour, min, sec into *TP.  */
-extern void __offtime __P ((__const time_t *__timer,
-			    long int __offset,
-			    struct tm *__TP));
+   and store year, yday, mon, mday, wday, hour, min, sec into *TP.
+   Return nonzero if successful.  */
+extern int __offtime __P ((__const time_t *__timer,
+			   long int __offset,
+			   struct tm *__tp));
 
 /* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"
    that is the representation of TP in this format.  */
diff --git a/time/tzset.c b/time/tzset.c
index 0793027de7..64e2087905 100644
--- a/time/tzset.c
+++ b/time/tzset.c
@@ -616,8 +616,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
     }
   else
     {
-      __offtime (timer, 0, tp);
-      if (! tz_compute (*timer, tp))
+      if (! (__offtime (timer, 0, tp) && tz_compute (*timer, tp)))
 	tp = NULL;
       leap_correction = 0L;
       leap_extra_secs = 0;
@@ -638,8 +637,10 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
 	  tp->tm_gmtoff = 0L;
 	}
 
-      __offtime (timer, tp->tm_gmtoff - leap_correction, tp);
-      tp->tm_sec += leap_extra_secs;
+      if (__offtime (timer, tp->tm_gmtoff - leap_correction, tp))
+        tp->tm_sec += leap_extra_secs;
+      else
+	tp = NULL;
     }
 
   __libc_lock_unlock (tzset_lock);