summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog36
-rw-r--r--Makefile2
-rw-r--r--inet/getnameinfo.c22
-rw-r--r--stdlib/random_r.c2
-rw-r--r--stdlib/strfmon.c137
-rw-r--r--sysdeps/arm/fpu/fpu_control.h34
-rw-r--r--sysdeps/posix/getaddrinfo.c3
-rw-r--r--sysdeps/unix/sysv/linux/arm/sys/ucontext.h94
8 files changed, 282 insertions, 48 deletions
diff --git a/ChangeLog b/ChangeLog
index 6d35a8f2da..795c6b7904 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2000-03-24  Andreas Jaeger  <aj@suse.de>
+
+	* Makefile (postclean): Added soversions.i.
+
+2000-03-24  Scott Bambrough  <scottb@netwinder.org>
+
+	* sysdeps/arm/fpu/fpu_control.h: Define _FPU_MASK_IM, _FPU_MASK_ZM,
+	_FPU_MASK_OM, _FPU_MASK_UM, _FPU_MASK_PM, _FPU_MASK_DM, _FPU_DEFAULT,
+	and _FPU_IEEE.  Change _FPU_RESERVED.
+
+2000-03-24  Scott Bambrough  <scottb@netwinder.org>
+
+	* sysdeps/unix/sysv/linux/arm/sys/ucontext.h: New file.
+
+2000-03-24  Roland McGrath  <roland@baalperazim.frob.com>
+
+	* sysdeps/posix/getaddrinfo.c: Include <net/if.h> for if_nametoindex.
+	(gaih_inet): Remove unused duplicate variable.
+
+	* inet/getnameinfo.c (getnameinfo): Use IFNAMSIZ, not MAXHOSTNAMELEN.
+	Don't use __libc_sa_len, which only exists for Linux.  Just handle
+	AF_INET and AF_INET6 directly as well as AF_LOCAL, since those are the
+	only flavors supported by this function anyway.
+
+2000-03-24  Geoff Clare  <gwc@unisoft.com>
+
+	* stdlib/strfmon.c: corrected problems with missing signs and
+	missing or extra spaces; allow for sign strings longer than
+	one character; add padding to ensure positive and negative
+	formats are aligned when a left precision is used.
+
+2000-03-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* stdlib/random_r.c (__setstate_r): Allow RNGs of type 4.
+	Patch by John Mizel <John.Mizel@msdw.com>.
+
 2000-03-25  Ulrich Drepper  <drepper@redhat.com>
 
 	* manual/install.texi: Remove references to crypt add-on.
diff --git a/Makefile b/Makefile
index eee88c9e0d..b969d09d56 100644
--- a/Makefile
+++ b/Makefile
@@ -198,7 +198,7 @@ parent-clean: parent-mostlyclean common-clean
 
 postclean = $(addprefix $(common-objpfx),$(postclean-generated)) \
 	    $(addprefix $(objpfx),sysd-Makefile sysd-dirs sysd-rules) \
-	    $(addprefix $(objpfx),sysd-sorted soversions.mk)
+	    $(addprefix $(objpfx),sysd-sorted soversions.mk soversions.i)
 
 clean: parent-clean
 # This is done this way rather than having `subdir_clean' be a
diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c
index 6ee3d4d2cc..9f5d761f1a 100644
--- a/inet/getnameinfo.c
+++ b/inet/getnameinfo.c
@@ -173,7 +173,6 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
   int herrno;
   char *tmpbuf = alloca (tmpbuflen);
   struct hostent th;
-  socklen_t min_addrlen = 0;
   int ok = 0;
 
   if (sa == NULL || addrlen < sizeof (sa_family_t))
@@ -182,16 +181,23 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
   switch (sa->sa_family)
     {
     case AF_LOCAL:
-      min_addrlen = (socklen_t) (((struct sockaddr_un *) NULL)->sun_path);
+      if (addrlen < (socklen_t) (((struct sockaddr_un *) NULL)->sun_path))
+	return -1;
+      break;
+    case AF_INET:
+      if (addrlen < sizeof (struct sockaddr_in))
+	return -1;
+      break;
+    case AF_INET6:
+      if (addrlen < sizeof (struct sockaddr_in6))
+	return -1;
       break;
     default:
-      min_addrlen = __libc_sa_len (sa->sa_family);
+      return -1;
     }
-  if (addrlen < min_addrlen)
-    return -1;
 
   if (host != NULL && hostlen > 0)
-    switch(sa->sa_family)
+    switch (sa->sa_family)
       {
       case AF_INET:
       case AF_INET6:
@@ -293,7 +299,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
 			&& (scopeid = sin6p->sin6_scope_id))
 		      {
 			/* Buffer is >= IFNAMSIZ+1.  */
-			char scopebuf[MAXHOSTNAMELEN + 1];
+			char scopebuf[IFNAMSIZ + 1];
 			int ni_numericscope = 0;
 
 			if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr)
@@ -365,7 +371,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host,
     }
 
   if (serv && (servlen > 0))
-    switch(sa->sa_family)
+    switch (sa->sa_family)
       {
       case AF_INET:
       case AF_INET6:
diff --git a/stdlib/random_r.c b/stdlib/random_r.c
index 9a74451cc6..27573b3b05 100644
--- a/stdlib/random_r.c
+++ b/stdlib/random_r.c
@@ -285,7 +285,7 @@ __setstate_r (arg_state, buf)
     old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
 
   type = new_state[0] % MAX_TYPES;
-  if (type < TYPE_0 || type >= TYPE_4)
+  if (type < TYPE_0 || type > TYPE_4)
     goto fail;
 
   buf->rand_deg = degree = random_poly_info.degrees[type];
diff --git a/stdlib/strfmon.c b/stdlib/strfmon.c
index ac6b8b6c93..d7213cae7a 100644
--- a/stdlib/strfmon.c
+++ b/stdlib/strfmon.c
@@ -117,6 +117,7 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
       fpnum;
       int print_curr_symbol;
       int left_prec;
+      int left_pad;
       int right_prec;
       int group;
       char pad;
@@ -124,11 +125,15 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
       int p_sign_posn;
       int n_sign_posn;
       int sign_posn;
+      int other_sign_posn;
       int left;
       int is_negative;
       int sep_by_space;
+      int other_sep_by_space;
       int cs_precedes;
-      char sign_char;
+      int other_cs_precedes;
+      const char *sign_string;
+      const char *other_sign_string;
       int done;
       const char *currency_symbol;
       int width;
@@ -346,35 +351,102 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
       /* We now know the sign of the value and can determine the format.  */
       if (is_negative)
 	{
-	  sign_char = *_NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN);
+	  sign_string = _NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN);
 	  /* If the locale does not specify a character for the
 	     negative sign we use a '-'.  */
-	  if (sign_char == '\0')
-	    sign_char = '-';
+	  if (*sign_string == '\0')
+	    sign_string = (const char *) "-";
 	  cs_precedes = *_NL_CURRENT (LC_MONETARY, N_CS_PRECEDES);
 	  sep_by_space = *_NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE);
 	  sign_posn = n_sign_posn;
+
+	  other_sign_string = _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
+	  other_cs_precedes = *_NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
+	  other_sep_by_space = *_NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE);
+	  other_sign_posn = p_sign_posn;
 	}
       else
 	{
-	  sign_char = *_NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
-	  /* If the locale does not specify a character for the
-	     positive sign we use a <SP>.  */
-	  if (sign_char == '\0')
-	    sign_char = ' ';
+	  sign_string = _NL_CURRENT (LC_MONETARY, POSITIVE_SIGN);
 	  cs_precedes = *_NL_CURRENT (LC_MONETARY, P_CS_PRECEDES);
 	  sep_by_space = *_NL_CURRENT (LC_MONETARY, P_SEP_BY_SPACE);
 	  sign_posn = p_sign_posn;
+
+	  other_sign_string = _NL_CURRENT (LC_MONETARY, NEGATIVE_SIGN);
+	  if (*other_sign_string == '\0')
+	    other_sign_string = (const char *) "-";
+	  other_cs_precedes = *_NL_CURRENT (LC_MONETARY, N_CS_PRECEDES);
+	  other_sep_by_space = *_NL_CURRENT (LC_MONETARY, N_SEP_BY_SPACE);
+	  other_sign_posn = n_sign_posn;
 	}
 
       /* Set default values for unspecified information.  */
       if (cs_precedes != 0)
 	cs_precedes = 1;
+      if (other_cs_precedes != 0)
+	other_cs_precedes = 1;
       if (sep_by_space == 127)
 	sep_by_space = 0;
+      if (other_sep_by_space == 127)
+	other_sep_by_space = 0;
+
+      /* Set the left precision and padding needed for alignment */
       if (left_prec == -1)
-	left_prec = 0;
+	{
+	  left_prec = 0;
+	  left_pad = 0;
+	}
+      else
+	{
+	  /* Set left_pad to number of spaces needed to align positive
+	     and negative formats */
 
+	  int sign_precedes = 0;
+	  int other_sign_precedes = 0;
+
+	  left_pad = 0;
+
+	  if (!cs_precedes && other_cs_precedes)
+	    {
+	      /* The other format has currency symbol preceding value,
+		 but this format doesn't, so pad by the relevant amount */
+	      left_pad += strlen (currency_symbol);
+	      if (other_sep_by_space != 0)
+		++left_pad;
+	    }
+
+	  /* Work out for each format whether a sign (or left parenthesis)
+	     precedes the value */
+	  if (sign_posn == 0 || sign_posn == 1)
+	    sign_precedes = 1;
+	  if (other_sign_posn == 0 || other_sign_posn == 1)
+	    other_sign_precedes = 1;
+	  if (cs_precedes && (sign_posn == 3 || sign_posn == 4))
+	    sign_precedes = 1;
+	  if (other_cs_precedes
+	      && (other_sign_posn == 3 || other_sign_posn == 4))
+	    other_sign_precedes = 1;
+
+	  if (!sign_precedes && other_sign_precedes)
+	    {
+	      /* The other format has a sign (or left parenthesis) preceding
+		 the value, but this format doesn't */
+	      if (other_sign_posn == 0)
+	        ++left_pad;
+	      else
+	        left_pad += strlen (other_sign_string);
+	    }
+	  else if (sign_precedes && other_sign_precedes)
+	    {
+	      /* Both formats have a sign (or left parenthesis) preceding
+		 the value, so compare their lengths */
+	      int len_diff =
+		((other_sign_posn == 0 ? 1 : (int) strlen (other_sign_string))
+		 - (sign_posn == 0 ? 1 : (int) strlen (sign_string)));
+	      if (len_diff > 0)
+	        left_pad += len_diff;
+	    }
+	}
 
       /* Perhaps we'll someday make these things configurable so
 	 better start using symbolic names now.  */
@@ -383,15 +455,18 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
 
       startp = dest;		/* Remember start so we can compute length.  */
 
-      if (sign_posn == 0)
-	out_char (is_negative ? left_paren : ' ');
+      while (left_pad-- > 0)
+	out_char (' ');
+
+      if (sign_posn == 0 && is_negative)
+	out_char (left_paren);
 
       if (cs_precedes)
 	{
 	  if (sign_posn != 0 && sign_posn != 2 && sign_posn != 4
 	      && sign_posn != 5)
 	    {
-	      out_char (sign_char);
+	      out_string (sign_string);
 	      if (sep_by_space == 2)
 		out_char (' ');
 	    }
@@ -404,7 +479,7 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
 		{
 		  if (sep_by_space == 2)
 		    out_char (' ');
-		  out_char (sign_char);
+		  out_string (sign_string);
 		}
 	      else
 		if (sep_by_space == 1)
@@ -414,7 +489,7 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
       else
 	if (sign_posn != 0 && sign_posn != 2 && sign_posn != 3
 	    && sign_posn != 4 && sign_posn != 5)
-	  out_char (sign_char);
+	  out_string (sign_string);
 
       /* Print the number.  */
 #ifdef USE_IN_LIBIO
@@ -422,7 +497,7 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
       _IO_JUMPS ((_IO_FILE *) &f) = &_IO_str_jumps;
       _IO_str_init_static ((_IO_FILE *) &f, dest, (s + maxsize) - dest, dest);
 #else
-      memset((void *) &f, 0, sizeof(f));
+      memset ((void *) &f, 0, sizeof (f));
       f.__magic = _IOMAGIC;
       f.__mode.__write = 1;
       /* The buffer size is one less than MAXLEN
@@ -478,26 +553,34 @@ __strfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format, ...)
 	    {
 	      if (sep_by_space == 1)
 		out_char (' ');
-	      out_char (sign_char);
+	      out_string (sign_string);
 	    }
 
 	  if (print_curr_symbol)
 	    {
-	      if (sign_posn == 3 && sep_by_space == 2)
+	      if ((sign_posn == 3 && sep_by_space == 2)
+		  || (sign_posn == 2 && sep_by_space == 1)
+		  || (sign_posn == 0 && sep_by_space == 1))
 		out_char (' ');
 	      out_string (currency_symbol);
+	      if (sign_posn == 4)
+		{
+		  if (sep_by_space == 2)
+		    out_char (' ');
+		  out_string (sign_string);
+		}
 	    }
 	}
-      else
-	if (sign_posn == 2)
-	  {
-	    if (sep_by_space == 2)
-	      out_char (' ');
-	    out_char (sign_char);
-	  }
 
-      if (sign_posn == 0)
-	out_char (is_negative ? right_paren : ' ');
+      if (sign_posn == 2)
+	{
+	  if (sep_by_space == 2)
+	    out_char (' ');
+	  out_string (sign_string);
+	}
+
+      if (sign_posn == 0 && is_negative)
+	out_char (right_paren);
 
       /* Now test whether the output width is filled.  */
       if (dest - startp < width)
diff --git a/sysdeps/arm/fpu/fpu_control.h b/sysdeps/arm/fpu/fpu_control.h
index b5338c5755..dfcfaabfcd 100644
--- a/sysdeps/arm/fpu/fpu_control.h
+++ b/sysdeps/arm/fpu/fpu_control.h
@@ -1,5 +1,5 @@
 /* FPU control word definitions.  ARM version.
-   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 2000 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
@@ -23,12 +23,12 @@
 /* We have a slight terminology confusion here.  On the ARM, the register
  * we're interested in is actually the FPU status word - the FPU control
  * word is something different (which is implementation-defined and only
- * accessible from supervisor mode.)  
+ * accessible from supervisor mode.)
  *
  * The FPSR looks like this:
  *
  *     31-24        23-16          15-8              7-0
- * | system ID | trap enable | system control | exception flags | 
+ * | system ID | trap enable | system control | exception flags |
  *
  * We ignore the system ID bits; for interest's sake they are:
  *
@@ -40,7 +40,7 @@
  * The trap enable and exception flags are both structured like this:
  *
  *     7 - 5     4     3     2     1     0
- * | reserved | INX | UFL | OFL | DVZ | IVO | 
+ * | reserved | INX | UFL | OFL | DVZ | IVO |
  *
  * where a `1' bit in the enable byte means that the trap can occur, and
  * a `1' bit in the flags byte means the exception has occurred.
@@ -57,7 +57,7 @@
  *
  *     7-5      4    3    2    1    0
  * | reserved | AC | EP | SO | NE | ND |
- * 
+ *
  * where the bits mean
  *
  *  ND - no denormalised numbers (force them all to zero)
@@ -67,11 +67,27 @@
  *  AC - use alternate definition for C flag on compare operations
  */
 
-#define _FPU_RESERVED 0xfff0e0f0  /* These bits are reserved.  */
+/* masking of interrupts */
+#define _FPU_MASK_IM	0x00010000	/* invalid operation */
+#define _FPU_MASK_ZM	0x00020000	/* divide by zero */
+#define _FPU_MASK_OM	0x00040000	/* overflow */
+#define _FPU_MASK_UM	0x00080000	/* underflow */
+#define _FPU_MASK_PM	0x00100000	/* inexact */
+#define _FPU_MASK_DM	0x00000000	/* denormalized operation */
+
+/* The system id bytes cannot be changed.
+   Only the bottom 5 bits in the trap enable byte can be changed.
+   Only the bottom 5 bits in the system control byte can be changed.
+   Only the bottom 5 bits in the exception flags are used.
+   The exception flags are set by the fpu, but can be zeroed by the user. */
+#define _FPU_RESERVED	0xffe0e0e0	/* These bits are reserved.  */
 
-/* The fdlibm code requires no interrupts for exceptions.  Don't
-   change the rounding mode, it would break long double I/O!  */
-#define _FPU_DEFAULT  0x00001000 /* Default value.  */
+/* The fdlibm code requires strict IEEE double precision arithmetic,
+   no interrupts for exceptions, rounding to nearest.  Changing the
+   rounding mode will break long double I/O.  Turn on the AC bit,
+   the compiler generates code that assumes it is on.  */
+#define _FPU_DEFAULT	0x00001000	/* Default value.  */
+#define _FPU_IEEE	0x001f1000	/* Default + exceptions enabled. */
 
 /* Type of the control word.  */
 typedef unsigned int fpu_control_t;
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index be36c6a25f..59e2cec129 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -55,6 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sys/types.h>
 #include <sys/un.h>
 #include <sys/utsname.h>
+#include <net/if.h>
 
 #define GAIH_OKIFUNSPEC 0x0100
 #define GAIH_EAI        ~(GAIH_OKIFUNSPEC)
@@ -392,8 +393,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
 	  if (inet_pton (AF_INET6, namebuf, at->addr) > 0)
 	    {
-	      int try_numericscope = 0;
-
 	      if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
 		at->family = AF_INET6;
 	      else
diff --git a/sysdeps/unix/sysv/linux/arm/sys/ucontext.h b/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
new file mode 100644
index 0000000000..6e51efec99
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
@@ -0,0 +1,94 @@
+/* Copyright (C) 1998, 1999 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.  */

+

+/* System V/ARM ABI compliant context switching support.  */

+

+#ifndef _SYS_UCONTEXT_H

+#define _SYS_UCONTEXT_H	1

+

+#include <features.h>

+#include <signal.h>

+#include <sys/elf.h>

+

+typedef int greg_t;

+

+/* Number of general registers.  */

+#define NGREG	16

+

+/* Container for all general registers.  */

+typedef elf_gregset_t gregset_t;

+

+/* Number of each register is the `gregset_t' array.  */

+enum

+{

+  R0 = 0,

+#define R0	R0

+  R1 = 1,

+#define R1	R1

+  R2 = 2,

+#define R2	R2

+  R3 = 3,

+#define R3	R3

+  R4 = 4,

+#define R4	R4

+  R5 = 5,

+#define R5	R5

+  R6 = 6,

+#define R6	R6

+  R7 = 7,

+#define R7	R7

+  R8 = 8,

+#define R8	R8

+  R9 = 9,

+#define R9	R9

+  R10 = 10,

+#define R10	R10

+  R11 = 11,

+#define R11	R11

+  R12 = 12,

+#define R12	R12

+  R13 = 13,

+#define R13	R13

+  R14 = 14,

+#define R14	R14

+  R15 = 15,

+#define R15	R15

+};

+

+/* Structure to describe FPU registers.  */

+typedef elf_fpregset_t	fpregset_t;

+

+/* Context to describe whole processor state.  */

+typedef struct

+  {

+    gregset_t gregs;

+    fpregset_t fpregs;

+  } mcontext_t;

+

+/* Userlevel context.  */

+typedef struct ucontext

+  {

+    unsigned long int uc_flags;

+    struct ucontext *uc_link;

+    __sigset_t uc_sigmask;

+    stack_t uc_stack;

+    mcontext_t uc_mcontext;

+    long int uc_filler[5];

+  } ucontext_t;

+

+#endif /* sys/ucontext.h */