aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-12-18 19:45:25 +0000
committerUlrich Drepper <drepper@redhat.com>1999-12-18 19:45:25 +0000
commitb85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a (patch)
tree6aec765390be55804ecbe7c1bde6c79dda2e1dc2
parent440a52ea7b427b7a5668c77283825cae20d7fc3c (diff)
downloadglibc-b85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a.tar
glibc-b85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a.tar.gz
glibc-b85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a.tar.bz2
glibc-b85697f61d8aeeaeb8b91d50ab2c668b7fcbbd8a.zip
Update.
1999-12-17 Ulrich Drepper <drepper@cygnus.com> * string/bits/string2.h (__strtok_r_1c): Help gcc optimizing string access. * locale/programs/ld-collate.c: Implement handling of absolute ellipsis. Parsing of file and constructing the internal data structures should now be complete. (collate_finish): Start adding support to generate the data structures which are written out to the file. * intl/dcgettext.c: Rewrite to handle caching of previous results here instead of in the dcgettext macro. * intl/libintl.h (dcgettext): Don't define for systems using this glibc or systems with tsearch. * sysdeps/generic/mathdef.h: Protect definitions for math.h against double inclusion. * sysdeps/alpha/fpu/bits/mathdef.h: Likewise. * sysdeps/i386/fpu/bits/mathdef.h: Likewise. * sysdeps/m68k/fpu/bits/mathdef.h: Likewise. * sysdeps/powerpc/fpu/bits/mathdef.h: Likewise. * sysdeps/i386/fpu/libm-test-ulps: Add more deltas (are mobile PIIs that different?). 1999-12-17 Andreas Jaeger <aj@suse.de> * rt/aio.h (struct aiocb64): Add member __next_prio to sync the struct with aiocb. * rt/Makefile (tests): Added tst-aio64. Added dependency rules for tst-aio64. * rt/tst-aio64.c: New file, copied from tst-aio.c and changed for 64bit tests. 1999-12-15 Thorsten Kukuk <kukuk@suse.de> * sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/bits/resource.h: Change RLIM_INFINITY back to old value (signed long). * sysdeps/unix/sysv/linux/i386/bits/resource.h: New, with unsigned long RLIM_INFINITY. * sysdeps/unix/sysv/linux/getrlimit.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/getrlimit.c: ... here. * sysdeps/unix/sysv/linux/getrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/getrlimit64.c: ... here. * sysdeps/unix/sysv/linux/oldgetrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c: ... here. * sysdeps/unix/sysv/linux/oldsetrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c: ... here. * sysdeps/unix/sysv/linux/setrlimit.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/setrlimit.c: ... here. * sysdeps/unix/sysv/linux/setrlimit64.c: Moved from here to ... * sysdeps/unix/sysv/linux/i386/setrlimit64.c: ... here. * sysdeps/unix/sysv/linux/sparc/bits/resource.h: New. * sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c: Removed. * sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c: Removed. 1999-12-17 Andreas Jaeger <aj@suse.de> * elf/ldconfig.c: Add new option -l to manualy link shared libraries. (options): Added option. (parse_opt): Set option. (main): Handle option. (manual_link): New function. 1999-12-17 Thorsten Kukuk <kukuk@suse.de> * string/bits/string2.h: Fix patch from 1999-12-07. 1999-12-16 Ulrich Drepper <drepper@cygnus.com> * sysdeps/generic/strsep.c: If delim string has only one character don't run over end of string. * locale/programs/ld-collate.c (insert_weights): Also update next pointer of last cursor element. (insert_value): Return nonzero value if nothing got inserted. (handle_ellipsis): Don't do anything if to-value cannot be inserted. 1999-12-10 Jakub Jelinek <jakub@redhat.com> * stdlib/longlong.h (__sparc_v9__): Use %rDIGIT instead of %DIGIT where appropriate. 1999-12-10 Jakub Jelinek <jakub@redhat.com> * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c (__sigaction): Copy sa_flags into kernel sigaction structure. 1999-12-14 Andreas Jaeger <aj@suse.de> * string/tester.c (test_strsep): More tests for access beyond the final NUL. The first two tests come from PR libc/1486 by martinea@iro.umontreal.ca. 1999-12-14 Thorsten Kukuk <kukuk@suse.de> * nis/ypclnt.c: Correct handling of cached client handles. (__xdr_ypresp_all): Call callback function for errors, too, like Solaris does. * nis/nss_compat/compat-grp.c: Make sure errno is always set correct. * nis/nss_compat/compat-initgroups.c: Likewise. * nis/nss_compat/compat-spwd.c: Likewise. * nis/nss_nis/nis-alias.c: Likewise. * nis/nss_nis/nis-ethers.c: Likewise. * nis/nss_nis/nis-grp.c: Likewise. * nis/nss_nis/nis-hosts.c: Likewise. * nis/nss_nis/nis-netgrp.c: Likewise. * nis/nss_nis/nis-publickey.c: Likewise. * nis/nss_nis/nis-service.c: Likewise. Also use services.byservicename Map if available, optimize query if name/port and protocol is known.
-rw-r--r--ChangeLog117
-rw-r--r--bits/mathdef.h4
-rw-r--r--elf/ldconfig.c93
-rw-r--r--intl/dcgettext.c175
-rw-r--r--intl/libintl.h2
-rw-r--r--linuxthreads/ChangeLog8
-rw-r--r--linuxthreads/manager.c22
-rw-r--r--linuxthreads/pthread.c5
-rw-r--r--locale/programs/ld-collate.c317
-rw-r--r--nis/nss_compat/compat-grp.c12
-rw-r--r--nis/nss_compat/compat-initgroups.c6
-rw-r--r--nis/nss_compat/compat-spwd.c23
-rw-r--r--nis/nss_nis/nis-alias.c5
-rw-r--r--nis/nss_nis/nis-ethers.c9
-rw-r--r--nis/nss_nis/nis-grp.c6
-rw-r--r--nis/nss_nis/nis-hosts.c6
-rw-r--r--nis/nss_nis/nis-netgrp.c9
-rw-r--r--nis/nss_nis/nis-publickey.c33
-rw-r--r--nis/nss_nis/nis-service.c115
-rw-r--r--nis/ypclnt.c358
-rw-r--r--rt/Makefile6
-rw-r--r--rt/aio.h4
-rw-r--r--rt/tst-aio64.c196
-rw-r--r--stdlib/longlong.h8
-rw-r--r--string/bits/string2.h8
-rw-r--r--string/tester.c27
-rw-r--r--sysdeps/alpha/fpu/bits/mathdef.h4
-rw-r--r--sysdeps/generic/bits/mathdef.h4
-rw-r--r--sysdeps/generic/strsep.c4
-rw-r--r--sysdeps/i386/fpu/bits/mathdef.h4
-rw-r--r--sysdeps/i386/fpu/libm-test-ulps63
-rw-r--r--sysdeps/m68k/fpu/bits/mathdef.h4
-rw-r--r--sysdeps/powerpc/fpu/bits/mathdef.h4
-rw-r--r--sysdeps/sparc/fpu/bits/mathdef.h4
-rw-r--r--sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c1
-rw-r--r--sysdeps/unix/sysv/linux/bits/resource.h6
-rw-r--r--sysdeps/unix/sysv/linux/i386/bits/resource.h227
-rw-r--r--sysdeps/unix/sysv/linux/i386/getrlimit.c (renamed from sysdeps/unix/sysv/linux/getrlimit.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/getrlimit64.c (renamed from sysdeps/unix/sysv/linux/getrlimit64.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c (renamed from sysdeps/unix/sysv/linux/oldgetrlimit64.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c (renamed from sysdeps/unix/sysv/linux/oldsetrlimit64.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/setrlimit.c (renamed from sysdeps/unix/sysv/linux/setrlimit.c)0
-rw-r--r--sysdeps/unix/sysv/linux/i386/setrlimit64.c (renamed from sysdeps/unix/sysv/linux/setrlimit64.c)0
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/resource.h243
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c1
48 files changed, 1830 insertions, 316 deletions
diff --git a/ChangeLog b/ChangeLog
index e08445df95..f3b284705f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,120 @@
+1999-12-17 Ulrich Drepper <drepper@cygnus.com>
+
+ * string/bits/string2.h (__strtok_r_1c): Help gcc optimizing string
+ access.
+
+ * locale/programs/ld-collate.c: Implement handling of absolute
+ ellipsis. Parsing of file and constructing the internal data
+ structures should now be complete.
+ (collate_finish): Start adding support to generate the data
+ structures which are written out to the file.
+
+ * intl/dcgettext.c: Rewrite to handle caching of previous results here
+ instead of in the dcgettext macro.
+ * intl/libintl.h (dcgettext): Don't define for systems using this
+ glibc or systems with tsearch.
+
+ * sysdeps/generic/mathdef.h: Protect definitions for math.h
+ against double inclusion.
+ * sysdeps/alpha/fpu/bits/mathdef.h: Likewise.
+ * sysdeps/i386/fpu/bits/mathdef.h: Likewise.
+ * sysdeps/m68k/fpu/bits/mathdef.h: Likewise.
+ * sysdeps/powerpc/fpu/bits/mathdef.h: Likewise.
+
+ * sysdeps/i386/fpu/libm-test-ulps: Add more deltas (are mobile PIIs
+ that different?).
+
+1999-12-17 Andreas Jaeger <aj@suse.de>
+
+ * rt/aio.h (struct aiocb64): Add member __next_prio to sync the
+ struct with aiocb.
+
+ * rt/Makefile (tests): Added tst-aio64.
+ Added dependency rules for tst-aio64.
+
+ * rt/tst-aio64.c: New file, copied from tst-aio.c and changed for
+ 64bit tests.
+
+1999-12-15 Thorsten Kukuk <kukuk@suse.de>
+
+ * sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c: Removed.
+ * sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c: Removed.
+ * sysdeps/unix/sysv/linux/bits/resource.h: Change RLIM_INFINITY back to
+ old value (signed long).
+ * sysdeps/unix/sysv/linux/i386/bits/resource.h: New, with unsigned
+ long RLIM_INFINITY.
+ * sysdeps/unix/sysv/linux/getrlimit.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/getrlimit.c: ... here.
+ * sysdeps/unix/sysv/linux/getrlimit64.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/getrlimit64.c: ... here.
+ * sysdeps/unix/sysv/linux/oldgetrlimit64.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c: ... here.
+ * sysdeps/unix/sysv/linux/oldsetrlimit64.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c: ... here.
+ * sysdeps/unix/sysv/linux/setrlimit.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/setrlimit.c: ... here.
+ * sysdeps/unix/sysv/linux/setrlimit64.c: Moved from here to ...
+ * sysdeps/unix/sysv/linux/i386/setrlimit64.c: ... here.
+ * sysdeps/unix/sysv/linux/sparc/bits/resource.h: New.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c: Removed.
+ * sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c: Removed.
+
+1999-12-17 Andreas Jaeger <aj@suse.de>
+
+ * elf/ldconfig.c: Add new option -l to manualy link shared
+ libraries.
+ (options): Added option.
+ (parse_opt): Set option.
+ (main): Handle option.
+ (manual_link): New function.
+
+1999-12-17 Thorsten Kukuk <kukuk@suse.de>
+
+ * string/bits/string2.h: Fix patch from 1999-12-07.
+
+1999-12-16 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/generic/strsep.c: If delim string has only one character
+ don't run over end of string.
+
+ * locale/programs/ld-collate.c (insert_weights): Also update next
+ pointer of last cursor element.
+ (insert_value): Return nonzero value if nothing got inserted.
+ (handle_ellipsis): Don't do anything if to-value cannot be inserted.
+
+1999-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ * stdlib/longlong.h (__sparc_v9__): Use %rDIGIT instead of %DIGIT
+ where appropriate.
+
+1999-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c (__sigaction):
+ Copy sa_flags into kernel sigaction structure.
+
+1999-12-14 Andreas Jaeger <aj@suse.de>
+
+ * string/tester.c (test_strsep): More tests for access beyond
+ the final NUL. The first two tests come from PR libc/1486 by
+ martinea@iro.umontreal.ca.
+
+1999-12-14 Thorsten Kukuk <kukuk@suse.de>
+
+ * nis/ypclnt.c: Correct handling of cached client handles.
+ (__xdr_ypresp_all): Call callback function for errors, too,
+ like Solaris does.
+ * nis/nss_compat/compat-grp.c: Make sure errno is always set correct.
+ * nis/nss_compat/compat-initgroups.c: Likewise.
+ * nis/nss_compat/compat-spwd.c: Likewise.
+ * nis/nss_nis/nis-alias.c: Likewise.
+ * nis/nss_nis/nis-ethers.c: Likewise.
+ * nis/nss_nis/nis-grp.c: Likewise.
+ * nis/nss_nis/nis-hosts.c: Likewise.
+ * nis/nss_nis/nis-netgrp.c: Likewise.
+ * nis/nss_nis/nis-publickey.c: Likewise.
+ * nis/nss_nis/nis-service.c: Likewise. Also use services.byservicename
+ Map if available, optimize query if name/port and protocol is known.
+
1999-12-12 Ulrich Drepper <drepper@cygnus.com>
* locale/programs/ld-collate.c (collate_read): Make symbolic
diff --git a/bits/mathdef.h b/bits/mathdef.h
index d306e54366..0c30b01f52 100644
--- a/bits/mathdef.h
+++ b/bits/mathdef.h
@@ -20,7 +20,9 @@
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
#endif
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
/* Normally, there is no long double type and the `float' and `double'
expressions are evaluated as `double'. */
typedef double float_t; /* `float' expressions are evaluated as
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
index 6c2bcb2d4f..98a4817202 100644
--- a/elf/ldconfig.c
+++ b/elf/ldconfig.c
@@ -97,6 +97,9 @@ static int opt_only_cline = 0;
/* Path to root for chroot. */
static char *opt_chroot;
+/* Manually link given shared libraries. */
+static int opt_manual_link = 0;
+
/* Cache file to use. */
static const char *cache_file;
@@ -119,6 +122,7 @@ static const struct argp_option options[] =
{ NULL, 'C', "CACHE", 0, N_("Use CACHE as cache file"), 0},
{ NULL, 'f', "CONF", 0, N_("Use CONF as configuration file"), 0},
{ NULL, 'n', NULL, 0, N_("Only process directories specified on the command line. Don't build cache."), 0},
+ { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
{ NULL, 0, NULL, 0, NULL, 0 }
};
@@ -148,6 +152,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'f':
config_file = arg;
break;
+ case 'l':
+ opt_manual_link = 1;
+ break;
case 'N':
opt_build_cache = 0;
break;
@@ -323,6 +330,75 @@ create_links (const char *path, const char *libname, const char *soname)
fputs ("\n", stdout);
}
+/* Manually link the given library. */
+static void
+manual_link (char *library)
+{
+ char *path;
+ char *libname;
+ char *soname;
+ struct stat stat_buf;
+ int flag;
+
+ /* Prepare arguments for create_links call. Split library name in
+ directory and filename first. Since path is allocated, we've got
+ to be careful to free at the end. */
+ path = xstrdup (library);
+ libname = strrchr (path, '/');
+
+ if (libname)
+ {
+ /* Successfully split names. Check if path is just "/" to avoid
+ an empty path. */
+ if (libname == path)
+ {
+ libname = library + 1;
+ path = xrealloc (path, 2);
+ strcpy (path, "/");
+ }
+ else
+ {
+ *libname = '\0';
+ ++libname;
+ }
+ }
+ else
+ {
+ /* There's no path, construct one. */
+ libname = library;
+ path = xrealloc (path, 2);
+ strcpy (path, ".");
+ }
+
+ /* Do some sanity checks first. */
+ if (lstat (library, &stat_buf))
+ {
+ error (0, errno, _("Can't lstat %s"), library);
+ free (path);
+ return;
+ }
+ /* We don't want links here! */
+ else if (!S_ISREG (stat_buf.st_mode))
+ {
+ error (0, 0, _("Ignored file %s since it is not a regular file."),
+ library);
+ free (path);
+ return;
+ }
+ libname = basename (library);
+ if (process_file (library, libname, &flag, &soname, 0))
+ {
+ error (0, 0, _("No link created since soname could not be found for %s"),
+ library);
+ free (path);
+ return;
+ }
+ create_links (path, libname, soname);
+ free (soname);
+ free (path);
+}
+
+
/* Read a whole directory and search for libraries.
The purpose is two-fold:
- search for libraries which will be added to the cache
@@ -595,8 +671,9 @@ main (int argc, char **argv)
/* Parse and process arguments. */
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
- /* Remaining arguments are additional libraries. */
- if (remaining != argc)
+ /* Remaining arguments are additional libraries if opt_manual_link
+ is not set. */
+ if (remaining != argc && !opt_manual_link)
{
int i;
for (i = remaining; i < argc; ++i)
@@ -626,6 +703,18 @@ main (int argc, char **argv)
exit (0);
}
+ if (opt_manual_link)
+ {
+ /* Link all given libraries manually. */
+ int i;
+
+ for (i = remaining; i < argc; ++i)
+ manual_link (argv [i]);
+
+ exit (0);
+ }
+
+
if (opt_build_cache)
init_cache ();
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index d482da39b8..8e51970495 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -121,6 +121,9 @@ char *getcwd ();
# ifndef HAVE_STPCPY
static char *stpcpy PARAMS ((char *dest, const char *src));
# endif
+# ifndef HAVE_MEMPCPY
+static void *mempcpy PARAMS ((void *dest, const void *src, size_t n));
+# endif
#endif
/* Amount to increase buffer size by in each try. */
@@ -130,7 +133,7 @@ static char *stpcpy PARAMS ((char *dest, const char *src));
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
PATH_MAX but might cause redefinition warnings when sys/param.h is
later included (as on MORE/BSD 4.3). */
-#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
+#if defined _POSIX_VERSION || (defined HAVE_LIMITS_H && !defined __GNUC__)
# include <limits.h>
#endif
@@ -138,16 +141,16 @@ static char *stpcpy PARAMS ((char *dest, const char *src));
# define _POSIX_PATH_MAX 255
#endif
-#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
+#if !defined PATH_MAX && defined _PC_PATH_MAX
# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
#endif
/* Don't include sys/param.h if it already has been. */
-#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
+#if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
# include <sys/param.h>
#endif
-#if !defined(PATH_MAX) && defined(MAXPATHLEN)
+#if !defined PATH_MAX && defined MAXPATHLEN
# define PATH_MAX MAXPATHLEN
#endif
@@ -165,6 +168,68 @@ static char *stpcpy PARAMS ((char *dest, const char *src));
# define HAVE_LOCALE_NULL
#endif
+/* We want to allocate a string at the end of the struct. gcc makes
+ this easy. */
+#ifdef __GNUC__
+# define ZERO 0
+#else
+# define ZERO 1
+#endif
+
+/* This is the type used for the search tree where known translations
+ are stored. */
+struct known_translation_t
+{
+ /* Domain in which to search. */
+ char *domain;
+
+ /* The category. */
+ int category;
+
+ /* State of the catalog counter at the point the string was found. */
+ int counter;
+
+ /* And finally the translation. */
+ const char *translation;
+
+ /* Pointer to the string in question. */
+ char msgid[ZERO];
+};
+
+/* Root of the search tree with known translations. We can use this
+ only if the system provides the `tsearch' function family. */
+#if defined HAVE_TSEARCH || defined _LIBC
+# include <search.h>
+
+static void *root;
+
+# ifdef _LIBC
+# define tsearch __tsearch
+# endif
+
+/* Function to compare two entries in the table of known translations. */
+static int
+transcmp (const void *p1, const void *p2)
+{
+ struct known_translation_t *s1 = (struct known_translation_t *) p1;
+ struct known_translation_t *s2 = (struct known_translation_t *) p2;
+ int result;
+
+ result = strcmp (s1->msgid, s2->msgid);
+ if (result == 0)
+ {
+ result = strcmp (s1->msgid, s2->msgid);
+ if (result == 0)
+ /* We compare the category last (though this is the cheapest
+ operation) since it is hopefully always the same (namely
+ LC_MESSAGES). */
+ result = s1->category - s2->category;
+ }
+
+ return result;
+}
+#endif
+
/* Name of the default domain used for gettext(3) prior any call to
textdomain(3). The default value for this is "messages". */
const char _nl_default_default_domain[] = "messages";
@@ -268,12 +333,34 @@ DCGETTEXT (domainname, msgid, category)
char *dirname, *xdomainname;
char *single_locale;
char *retval;
- int saved_errno = errno;
+ int saved_errno;
+#if defined HAVE_TSEARCH || defined _LIBC
+ struct known_translation_t *search;
+ struct known_translation_t **foundp;
+ size_t msgid_len = strlen (msgid) + 1;
+#endif
+ size_t domainname_len;
/* If no real MSGID is given return NULL. */
if (msgid == NULL)
return NULL;
+#if defined HAVE_TSEARCH || defined _LIBC
+ /* Try to find the translation among those which we found at some time. */
+ search = (struct known_translation_t *) alloca (sizeof (*search)
+ + msgid_len);
+ memcpy (search->msgid, msgid, msgid_len);
+ search->domain = (char *) domainname;
+ search->category = category;
+
+ foundp = (struct known_translation_t **) tfind (search, &root, transcmp);
+ if (foundp != NULL && (*foundp)->counter == _nl_msg_cat_cntr)
+ return (char *) (*foundp)->translation;
+#endif
+
+ /* Preserve the `errno' value. */
+ saved_errno = errno;
+
/* See whether this is a SUID binary or not. */
DETERMINE_SECURE;
@@ -340,12 +427,13 @@ DCGETTEXT (domainname, msgid, category)
categoryname = category_to_name (category);
categoryvalue = guess_category_value (category, categoryname);
+ domainname_len = strlen (domainname);
xdomainname = (char *) alloca (strlen (categoryname)
- + strlen (domainname) + 5);
+ + domainname_len + 5);
ADD_BLOCK (block_list, xdomainname);
- stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
- domainname),
+ stpcpy (mempcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"),
+ domainname, domainname_len),
".mo");
/* Creating working area. */
@@ -422,6 +510,38 @@ DCGETTEXT (domainname, msgid, category)
{
FREE_BLOCKS (block_list);
__set_errno (saved_errno);
+#if defined HAVE_TSEARCH || defined _LIBC
+ if (foundp == NULL)
+ {
+ /* Create a new entry and add it to the search tree. */
+ struct known_translation_t *newp;
+
+ newp = (struct known_translation_t *)
+ malloc (sizeof (*newp) + msgid_len
+ + domainname_len + 1 - ZERO);
+ if (newp != NULL)
+ {
+ newp->domain = mempcpy (newp->msgid, msgid, msgid_len);
+ memcpy (newp->domain, domainname, domainname_len + 1);
+ newp->category = category;
+ newp->counter = _nl_msg_cat_cntr;
+ newp->translation = retval;
+
+ /* Insert the entry in the search tree. */
+ foundp = (struct known_translation_t **)
+ tsearch (newp, &root, transcmp);
+ if (&newp != foundp)
+ /* The insert failed. */
+ free (newp);
+ }
+ }
+ else
+ {
+ /* We can update the existing entry. */
+ (*foundp)->counter = _nl_msg_cat_cntr;
+ (*foundp)->translation = retval;
+ }
+#endif
return retval;
}
}
@@ -571,12 +691,13 @@ _nl_find_msg (domain_file, msgid)
return NULL;
if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len
- && strcmp (msgid,
- domain->data + W (domain->must_swap,
- domain->orig_tab[nstr - 1].offset))
- == 0)
- return (char *) domain->data
- + W (domain->must_swap, domain->trans_tab[nstr - 1].offset);
+ && (strcmp (msgid,
+ domain->data + W (domain->must_swap,
+ domain->orig_tab[nstr - 1].offset))
+ == 0))
+ return ((char *) domain->data
+ + W (domain->must_swap,
+ domain->trans_tab[nstr - 1].offset));
}
/* NOTREACHED */
}
@@ -590,9 +711,9 @@ _nl_find_msg (domain_file, msgid)
int cmp_val;
act = (bottom + top) / 2;
- cmp_val = strcmp (msgid, domain->data
- + W (domain->must_swap,
- domain->orig_tab[act].offset));
+ cmp_val = strcmp (msgid, (domain->data
+ + W (domain->must_swap,
+ domain->orig_tab[act].offset)));
if (cmp_val < 0)
top = act;
else if (cmp_val > 0)
@@ -602,9 +723,9 @@ _nl_find_msg (domain_file, msgid)
}
/* If an translation is found return this. */
- return bottom >= top ? NULL : (char *) domain->data
- + W (domain->must_swap,
- domain->trans_tab[act].offset);
+ return bottom >= top ? NULL : ((char *) domain->data
+ + W (domain->must_swap,
+ domain->trans_tab[act].offset));
}
@@ -728,6 +849,17 @@ stpcpy (dest, src)
}
#endif
+#if !_LIBC && !HAVE_MEMPCPY
+static void *
+mempcpy (dest, src, n)
+ void *dest;
+ const void *src;
+ size_t n;
+{
+ return (void *) ((char *) memcpy (dst, src, n) + n);
+}
+#endif
+
#ifdef _LIBC
/* If we want to free all resources we have to do some work at
@@ -748,6 +880,9 @@ free_mem (void)
if (_nl_current_default_domain != _nl_default_default_domain)
/* Yes, again a pointer comparison. */
free ((char *) _nl_current_default_domain);
+
+ /* Remove the search tree with the know translations. */
+ __tdestroy (root, free);
}
text_set_element (__libc_subfreeres, free_mem);
diff --git a/intl/libintl.h b/intl/libintl.h
index aec7ea4b27..0c987e7d73 100644
--- a/intl/libintl.h
+++ b/intl/libintl.h
@@ -82,7 +82,7 @@ extern char *bindtextdomain (__const char *__domainname,
# define dgettext(domainname, msgid) \
dcgettext (domainname, msgid, LC_MESSAGES)
-# if __GNUC_PREREQ (2,7)
+# if __GLIBC__ >= 2 && __GNUC_PREREQ (2,7)
/* Variable defined in loadmsgcat.c which gets incremented every time a
new catalog is loaded. */
extern int _nl_msg_cat_cntr;
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 7d161b8254..9bdf83e951 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,11 @@
+1999-12-18 Ulrich Drepper <drepper@cygnus.com>
+
+ * manager.c (pthread_allocate_stack): Correct computation of
+ new_thread_bottom. Correct handling of stack size and when the
+ rlimit method to guard for stack growth is used.
+ * pthread.c (pthread_initialize): Stack limit must be STACK_SIZE
+ minus one pagesize (not two).
+
1999-12-03 Andreas Jaeger <aj@suse.de>
* Versions: Add __res_state with version GLIBC_2.2.
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 307ce63721..0cbb426c9d 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -289,9 +289,12 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
}
else
{
+ stacksize = STACK_SIZE - pagesize;
+ if (attr != NULL)
+ stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize));
/* Allocate space for stack and thread descriptor at default address */
new_thread = default_new_thread;
- new_thread_bottom = (char *) new_thread - STACK_SIZE;
+ new_thread_bottom = (char *) (new_thread + 1) - stacksize;
if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
@@ -300,14 +303,10 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
return -1;
/* We manage to get a stack. Now see whether we need a guard
and allocate it if necessary. Notice that the default
- attributes (stack_size = STACK_SIZE - pagesize and
- guardsize = pagesize) do not need a guard page, since
- the RLIMIT_STACK soft limit prevents stacks from
- running into one another. */
- if (attr == NULL ||
- attr->__guardsize == 0 ||
- (attr->__guardsize == pagesize &&
- attr->__stacksize == STACK_SIZE - pagesize))
+ attributes (stack_size = STACK_SIZE - pagesize) do not need
+ a guard page, since the RLIMIT_STACK soft limit prevents stacks
+ from running into one another. */
+ if (stacksize == STACK_SIZE - pagesize)
{
/* We don't need a guard page. */
guardaddr = NULL;
@@ -316,10 +315,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
else
{
/* Put a bad page at the bottom of the stack */
- stacksize = roundup(attr->__stacksize, pagesize);
- if (stacksize >= STACK_SIZE - pagesize)
- stacksize = STACK_SIZE - pagesize;
- guardaddr = (void *)new_thread - stacksize;
+ guardaddr = (void *)new_thread_bottom - stacksize;
guardsize = attr->__guardsize;
if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
== MAP_FAILED)
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 41d09a833c..a9083635b6 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -300,10 +300,9 @@ static void pthread_initialize(void)
__pthread_initial_thread_bos =
(char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
/* Play with the stack size limit to make sure that no stack ever grows
- beyond STACK_SIZE minus two pages (one page for the thread descriptor
- immediately beyond, and one page to act as a guard page). */
+ beyond STACK_SIZE minus one page (to act as a guard page). */
getrlimit(RLIMIT_STACK, &limit);
- max_stack = STACK_SIZE - 2 * __getpagesize();
+ max_stack = STACK_SIZE - __getpagesize();
if (limit.rlim_cur > max_stack) {
limit.rlim_cur = max_stack;
setrlimit(RLIMIT_STACK, &limit);
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 42fd601064..87005e86ab 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -73,7 +73,8 @@ struct element_t
const char *mbs;
const uint32_t *wcs;
- int order;
+ int mborder;
+ int wcorder;
struct element_list_t *weights;
@@ -87,6 +88,9 @@ struct element_t
/* Predecessor and successor in the order list. */
struct element_t *last;
struct element_t *next;
+
+ /* Next element in multibyte output list. */
+ struct element_t *mbnext;
};
/* Special element value. */
@@ -151,6 +155,10 @@ struct locale_collate_t
that the definitions from more than one input file contains information.
Therefore we keep all relevant input in a list. */
struct locale_collate_t *next;
+
+ /* Arrays with heads of the list for each of the leading bytes in
+ the multibyte sequences. */
+ struct element_t *mbheads[256];
};
@@ -176,7 +184,7 @@ make_seclist_elem (struct locale_collate_t *collate, const char *string,
static struct element_t *
-new_element (struct locale_collate_t *collate, const char *mbs,
+new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
const uint32_t *wcs, const char *name, size_t namelen)
{
struct element_t *newp;
@@ -185,7 +193,10 @@ new_element (struct locale_collate_t *collate, const char *mbs,
sizeof (*newp));
newp->name = name == NULL ? NULL : obstack_copy (&collate->mempool,
name, namelen);
- newp->mbs = mbs;
+ if (mbs != NULL)
+ newp->mbs = obstack_copy0 (&collate->mempool, mbs, mbslen);
+ else
+ newp->mbs = NULL;
if (wcs != NULL)
{
size_t nwcs = wcslen ((wchar_t *) wcs) + 1;
@@ -196,7 +207,8 @@ new_element (struct locale_collate_t *collate, const char *mbs,
}
else
newp->wcs = NULL;
- newp->order = 0;
+ newp->mborder = 0;
+ newp->wcorder = 0;
/* Will be allocated later. */
newp->weights = NULL;
@@ -209,6 +221,8 @@ new_element (struct locale_collate_t *collate, const char *mbs,
newp->last = NULL;
newp->next = NULL;
+ newp->mbnext = NULL;
+
return newp;
}
@@ -457,14 +471,15 @@ find_element (struct linereader *ldfile, struct locale_collate_t *collate,
result = sym->order;
if (result == NULL)
- result = sym->order = new_element (collate, NULL, NULL, NULL, 0);
+ result = sym->order = new_element (collate, NULL, 0, NULL,
+ NULL, 0);
}
else if (find_entry (&collate->elem_table, str, len,
(void **) &result) != 0)
{
/* It's also no collation element. So it is an character
element defined later. */
- result = new_element (collate, NULL, NULL, str, len);
+ result = new_element (collate, NULL, 0, NULL, str, len);
if (result != NULL)
/* Insert it into the sequence table. */
insert_entry (&collate->seq_table, str, len, result);
@@ -499,6 +514,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
elem->line = ldfile->lineno;
elem->last = collate->cursor;
elem->next = collate->cursor ? collate->cursor->next : NULL;
+ if (collate->cursor != NULL)
+ collate->cursor->next = elem;
elem->weights = (struct element_list_t *)
obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
@@ -683,7 +700,7 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
}
-static void
+static int
insert_value (struct linereader *ldfile, struct token *arg,
struct charmap_t *charmap, struct repertoire_t *repertoire,
struct locale_collate_t *collate)
@@ -721,14 +738,14 @@ insert_value (struct linereader *ldfile, struct token *arg,
elem = sym->order;
if (elem == NULL)
- elem = sym->order = new_element (collate, NULL, NULL, NULL, 0);
+ elem = sym->order = new_element (collate, NULL, 0, NULL, NULL, 0);
}
else if (find_entry (&collate->elem_table, arg->val.str.startmb,
arg->val.str.lenmb, (void **) &elem) != 0)
{
/* It's also no collation element. Therefore ignore it. */
lr_ignore_rest (ldfile, 0);
- return;
+ return 1;
}
}
else
@@ -741,6 +758,7 @@ insert_value (struct linereader *ldfile, struct token *arg,
/* We have to allocate an entry. */
elem = new_element (collate, seq != NULL ? seq->bytes : NULL,
+ seq != NULL ? seq->nbytes : 0,
wcs, arg->val.str.startmb, arg->val.str.lenmb);
/* And add it to the table. */
@@ -755,14 +773,16 @@ insert_value (struct linereader *ldfile, struct token *arg,
if (elem->next != NULL || (collate->cursor != NULL
&& elem->next == collate->cursor))
{
- lr_error (ldfile, _("order for `%.*s' already defined at %s:%Z"),
+ lr_error (ldfile, _("order for `%.*s' already defined at %s:%zu"),
arg->val.str.lenmb, arg->val.str.startmb,
elem->file, elem->line);
lr_ignore_rest (ldfile, 0);
- return;
+ return 1;
}
insert_weights (ldfile, elem, charmap, repertoire, collate, tok_none);
+
+ return 0;
}
@@ -780,8 +800,11 @@ handle_ellipsis (struct linereader *ldfile, struct token *arg,
startp = collate->cursor;
/* Process and add the end-entry. */
- if (arg != NULL)
- insert_value (ldfile, arg, charmap, repertoire, collate);
+ if (arg != NULL
+ && insert_value (ldfile, arg, charmap, repertoire, collate))
+ /* Something went wrong with inserting the to-value. This means
+ we cannot process the ellipsis. */
+ return;
/* Reset the cursor. */
collate->cursor = startp;
@@ -805,7 +828,168 @@ handle_ellipsis (struct linereader *ldfile, struct token *arg,
if (ellipsis == tok_ellipsis3)
{
- /* XXX */
+ /* One requirement we make here: the length of the byte
+ sequences for the first and end character must be the same.
+ This is mainly to prevent unwanted effects and this is often
+ not what is wanted. */
+ size_t len = (startp->mbs != NULL ? strlen (startp->mbs)
+ : (endp->mbs != NULL ? strlen (endp->mbs) : 0));
+ char mbcnt[len + 1];
+ char mbend[len + 1];
+
+ /* Well, this should be caught somewhere else already. Just to
+ make sure. */
+ assert (startp == NULL || startp->wcs == NULL || startp->wcs[1] == 0);
+ assert (endp == NULL || endp->wcs == NULL || endp->wcs[1] == 0);
+
+ if (startp != NULL && endp != NULL
+ && startp->mbs != NULL && endp->mbs != NULL
+ && strlen (startp->mbs) != strlen (endp->mbs))
+ {
+ lr_error (ldfile, _("\
+%s: byte sequences of first and last character must have the same length"),
+ "LC_COLLATE");
+ return;
+ }
+
+ /* Determine whether we have to generate multibyte sequences. */
+ if ((startp == NULL || startp->mbs != NULL)
+ && (endp == NULL || endp->mbs != NULL))
+ {
+ int cnt;
+ int ret;
+
+ /* Prepare the beginning byte sequence. This is either from the
+ beginning byte sequence or it is all nulls if it was an
+ initial ellipsis. */
+ if (startp == NULL || startp->mbs == NULL)
+ memset (mbcnt, '\0', len);
+ else
+ {
+ memcpy (mbcnt, startp->mbs, len);
+
+ /* And increment it so that the value is the first one we will
+ try to insert. */
+ for (cnt = len - 1; cnt >= 0; --cnt)
+ if (++mbcnt[cnt] != '\0')
+ break;
+ }
+ mbcnt[len] = '\0';
+
+ /* And the end sequence. */
+ if (endp == NULL || endp->mbs == NULL)
+ memset (mbend, '\0', len);
+ else
+ memcpy (mbend, endp->mbs, len);
+ mbend[len] = '\0';
+
+ /* Test whether we have a correct range. */
+ ret = memcmp (mbcnt, mbend, len);
+ if (ret >= 0)
+ {
+ if (ret > 0)
+ lr_error (ldfile, _("%s: byte sequence of first character of \
+sequence is not lower than that of the last character"), "LC_COLLATE");
+ return;
+ }
+
+ /* Generate the byte sequences data. */
+ while (1)
+ {
+ struct charseq *seq;
+
+ /* Quite a bit of work ahead. We have to find the character
+ definition for the byte sequence and then determine the
+ wide character belonging to it. */
+ seq = charmap_find_symbol (charmap, mbcnt, len);
+ if (seq != NULL)
+ {
+ struct element_t *elem;
+ size_t namelen;
+
+ if (seq->ucs4 == UNINITIALIZED_CHAR_VALUE)
+ seq->ucs4 = repertoire_find_value (repertoire, seq->name,
+ strlen (seq->name));
+
+ /* I don't this this can ever happen. */
+ assert (seq->name != NULL);
+ namelen = strlen (seq->name);
+
+ /* Now we are ready to insert the new value in the
+ sequence. Find out whether the element is
+ already known. */
+ if (find_entry (&collate->seq_table, seq->name, namelen,
+ (void **) &elem) != 0)
+ {
+ uint32_t wcs[2] = { seq->ucs4, 0 };
+
+ /* We have to allocate an entry. */
+ elem = new_element (collate, mbcnt, len, wcs, seq->name,
+ namelen);
+
+ /* And add it to the table. */
+ if (insert_entry (&collate->seq_table, seq->name,
+ namelen, elem) != 0)
+ /* This cannot happen. */
+ assert (! "Internal error");
+ }
+
+ /* Test whether this element is not already in the list. */
+ if (elem->next != NULL || (collate->cursor != NULL
+ && elem->next == collate->cursor))
+ {
+ lr_error (ldfile, _("\
+order for `%.*s' already defined at %s:%zu"),
+ namelen, seq->name, elem->file, elem->line);
+ goto increment;
+ }
+
+ /* Enqueue the new element. */
+ elem->last = collate->cursor;
+ elem->next = collate->cursor->next;
+ elem->last->next = elem;
+ if (elem->next != NULL)
+ elem->next->last = elem;
+ collate->cursor = elem;
+
+ /* Add the weight value. We take them from the
+ `ellipsis_weights' member of `collate'. */
+ elem->weights = (struct element_list_t *)
+ obstack_alloc (&collate->mempool,
+ nrules * sizeof (struct element_list_t));
+ for (cnt = 0; cnt < nrules; ++cnt)
+ if (collate->ellipsis_weight.weights[cnt].cnt == 1
+ && (collate->ellipsis_weight.weights[cnt].w[0]
+ == ELEMENT_ELLIPSIS2))
+ {
+ elem->weights[cnt].w = (struct element_t **)
+ obstack_alloc (&collate->mempool,
+ sizeof (struct element_t *));
+ elem->weights[cnt].w[0] = elem;
+ elem->weights[cnt].cnt = 1;
+ }
+ else
+ {
+ /* Simly use the weight from `ellipsis_weight'. */
+ elem->weights[cnt].w =
+ collate->ellipsis_weight.weights[cnt].w;
+ elem->weights[cnt].cnt =
+ collate->ellipsis_weight.weights[cnt].cnt;
+ }
+ }
+
+ /* Increment for the next round. */
+ increment:
+ for (cnt = len - 1; cnt >= 0; --cnt)
+ if (++mbcnt[cnt] != '\0')
+ break;
+
+ /* Find out whether this was all. */
+ if (cnt < 0 || memcmp (mbcnt, mbend, len) >= 0)
+ /* Yep, that's all. */
+ break;
+ }
+ }
}
else
{
@@ -883,7 +1067,7 @@ handle_ellipsis (struct linereader *ldfile, struct token *arg,
&& elem->next == collate->cursor))
{
lr_error (ldfile, _("\
-%s: order for `%.*s' already defined at %s:%Z"),
+%s: order for `%.*s' already defined at %s:%zu"),
"LC_COLLATE", lenfrom, buf,
elem->file, elem->line);
continue;
@@ -923,6 +1107,7 @@ handle_ellipsis (struct linereader *ldfile, struct token *arg,
/* We have to allocate an entry. */
elem = new_element (collate,
seq != NULL ? seq->bytes : NULL,
+ seq != NULL ? seq->nbytes : 0,
wc == ILLEGAL_CHAR_VALUE
? NULL : wcs,
buf, lenfrom);
@@ -1023,6 +1208,67 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
void
collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
{
+ /* Now is the time when we can assign the individual collation
+ values for all the symbols. We have possibly different values
+ for the wide- and the multibyte-character symbols. This is done
+ since it might make a difference in the encoding if there is in
+ some cases no multibyte-character but there are wide-characters.
+ (The other way around it is not important since theencoded
+ collation value in the wide-character case is 32 bits wide and
+ therefore requires no encoding).
+
+ The lowest collation value assigned is 2. Zero is reserved for
+ the NUL byte terminating the strings in the `strxfrm'/`wcsxfrm'
+ functions and 1 is used to separate the individual passes for the
+ different rules.
+
+ We also have to construct is list with all the bytes/words which
+ can come first in a sequence, followed by all the elements which
+ also start with this byte/word. The order is reverse which has
+ among others the important effect that longer strings are located
+ first in the list. This is required for the output data since
+ the algorithm used in `strcoll' etc depends on this.
+
+ The multibyte case is easy. We simply sort into an array with
+ 256 elements. */
+ struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
+ int mbact = 2;
+ int wcact = 2;
+ struct element_t *runp = collate->start;
+
+ while (runp != NULL)
+ {
+ if (runp->mbs != NULL)
+ {
+ struct element_t **eptr;
+
+ /* Determine the order. */
+ runp->mborder = mbact++;
+
+ /* Find the point where to insert in the list. */
+ eptr = &collate->mbheads[(unsigned int) runp->mbs[0]];
+ while (*eptr != NULL)
+ {
+ /* Check which string is larger, the one we want to insert
+ or the current element of the list we are looking at. */
+ assert (runp->mbs[0] == (*eptr)->mbs[0]);
+ if (strcmp (runp->mbs, (*eptr)->mbs) > 0)
+ break;
+
+ eptr = &(*eptr)->mbnext;
+ }
+
+ /* Set the pointers. */
+ runp->mbnext = *eptr;
+ *eptr = runp;
+ }
+
+ if (runp->wcs != NULL)
+ runp->wcorder = wcact++;
+
+ /* Up to the next entry. */
+ runp = runp->next;
+ }
}
@@ -1257,7 +1503,8 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
if (insert_entry (&collate->elem_table,
symbol, symbol_len,
new_element (collate,
- NULL, NULL, NULL, 0)) < 0)
+ NULL, 0, NULL, symbol,
+ symbol_len)) < 0)
lr_error (ldfile, _("\
error while adding collating element"));
}
@@ -1519,9 +1766,12 @@ error while adding equivalent collating symbol"));
goto err_label;
/* Handle ellipsis at end of list. */
- if (was_ellipsis)
- /* XXX */
- abort ();
+ if (was_ellipsis != tok_none)
+ {
+ handle_ellipsis (ldfile, NULL, was_ellipsis, charmap, repertoire,
+ collate);
+ was_ellipsis = tok_none;
+ }
state = 2;
lr_ignore_rest (ldfile, 1);
@@ -1543,9 +1793,12 @@ error while adding equivalent collating symbol"));
state = 2;
/* Handle ellipsis at end of list. */
- if (was_ellipsis)
- /* XXX */
- abort ();
+ if (was_ellipsis != tok_none)
+ {
+ handle_ellipsis (ldfile, arg, was_ellipsis, charmap,
+ repertoire, collate);
+ was_ellipsis = tok_none;
+ }
}
else if (state != 2 && state != 3)
goto err_label;
@@ -1610,9 +1863,12 @@ error while adding equivalent collating symbol"));
state = 2;
/* Handle ellipsis at end of list. */
- if (was_ellipsis)
- /* XXX */
- abort ();
+ if (was_ellipsis != tok_none)
+ {
+ handle_ellipsis (ldfile, NULL, was_ellipsis, charmap,
+ repertoire, collate);
+ was_ellipsis = tok_none;
+ }
}
else if (state == 3)
{
@@ -1848,7 +2104,7 @@ error while adding equivalent collating symbol"));
&& collate->undefined.next == collate->cursor))
{
lr_error (ldfile,
- _("%s: order for `%.*s' already defined at %s:%Z"),
+ _("%s: order for `%.*s' already defined at %s:%zu"),
"LC_COLLATE", 9, "UNDEFINED", collate->undefined.file,
collate->undefined.line);
lr_ignore_rest (ldfile, 0);
@@ -1892,9 +2148,12 @@ error while adding equivalent collating symbol"));
"LC_COLLATE");
/* Handle ellipsis at end of list. */
- if (was_ellipsis)
- /* XXX */
- abort ();
+ if (was_ellipsis != tok_none)
+ {
+ handle_ellipsis (ldfile, NULL, was_ellipsis, charmap,
+ repertoire, collate);
+ was_ellipsis = tok_none;
+ }
}
else if (state == 3)
error (0, 0, _("%s: missing `reorder-end' keyword"),
diff --git a/nis/nss_compat/compat-grp.c b/nis/nss_compat/compat-grp.c
index ac56f6fbec..2de46088df 100644
--- a/nis/nss_compat/compat-grp.c
+++ b/nis/nss_compat/compat-grp.c
@@ -1,6 +1,6 @@
/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -730,7 +730,10 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
enum nss_status status;
if (name[0] == '-' || name[0] == '+')
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
__libc_lock_lock (lock);
@@ -915,7 +918,10 @@ internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
status = getgrgid_plusgroup (gid, result, buffer, buflen, errnop);
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
else
return status;
}
diff --git a/nis/nss_compat/compat-initgroups.c b/nis/nss_compat/compat-initgroups.c
index 47b395ede6..d4c3422bd4 100644
--- a/nis/nss_compat/compat-initgroups.c
+++ b/nis/nss_compat/compat-initgroups.c
@@ -263,6 +263,7 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
{
ent->nis = 0;
+ *errnop = ENOENT;
return NSS_STATUS_NOTFOUND;
}
@@ -445,7 +446,10 @@ getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
++p;
parse_res = _nss_files_parse_grent (p, result, data, buflen, errnop);
if (parse_res == -1)
- return NSS_STATUS_TRYAGAIN;
+ {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
}
if (parse_res)
diff --git a/nis/nss_compat/compat-spwd.c b/nis/nss_compat/compat-spwd.c
index 1290346881..f254fadf5c 100644
--- a/nis/nss_compat/compat-spwd.c
+++ b/nis/nss_compat/compat-spwd.c
@@ -383,6 +383,7 @@ getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
if (parse_res == -1)
{
ent->netgrdata.cursor = saved_cursor;
+ *errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
@@ -1112,7 +1113,10 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
&& result->sp_namp[1] != '@')
{
if (strcmp (&result->sp_namp[1], name) == 0)
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
else
continue;
}
@@ -1128,8 +1132,11 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
status = getspnam_plususer (name, result, buffer, buflen,
errnop);
if (status == NSS_STATUS_RETURN)
- /* We couldn't parse the entry */
- return NSS_STATUS_NOTFOUND;
+ {
+ /* We couldn't parse the entry */
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
else
return status;
}
@@ -1142,7 +1149,10 @@ internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
status = getspnam_plususer (name, result, buffer, buflen, errnop);
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
else
return status;
}
@@ -1159,7 +1169,10 @@ _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
enum nss_status status;
if (name[0] == '-' || name[0] == '+')
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
if (ni == NULL)
{
diff --git a/nis/nss_nis/nis-alias.c b/nis/nss_nis/nis-alias.c
index 64d0bf8de5..e6e2386547 100644
--- a/nis/nss_nis/nis-alias.c
+++ b/nis/nss_nis/nis-alias.c
@@ -278,7 +278,10 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
}
return NSS_STATUS_SUCCESS;
diff --git a/nis/nss_nis/nis-ethers.c b/nis/nss_nis/nis-ethers.c
index c95f766469..c1ea32adc5 100644
--- a/nis/nss_nis/nis-ethers.c
+++ b/nis/nss_nis/nis-ethers.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -241,7 +241,10 @@ _nss_nis_gethostton_r (const char *name, struct ether *eth,
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
}
return NSS_STATUS_SUCCESS;
}
diff --git a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c
index 6dca66e4df..62e6b475b7 100644
--- a/nis/nss_nis/nis-grp.c
+++ b/nis/nss_nis/nis-grp.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -207,7 +207,7 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
return NSS_STATUS_TRYAGAIN;
else
{
- *errnop = EAGAIN;
+ *errnop = ENOENT;
return NSS_STATUS_NOTFOUND;
}
}
diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c
index 0ddc930687..15aff251e5 100644
--- a/nis/nss_nis/nis-hosts.c
+++ b/nis/nss_nis/nis-hosts.c
@@ -321,6 +321,7 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
else
{
*h_errnop = HOST_NOT_FOUND;
+ *errnop = ENOENT;
return NSS_STATUS_NOTFOUND;
}
}
@@ -392,7 +393,10 @@ _nss_nis_gethostbyaddr_r (char *addr, size_t addrlen, int af,
*errnop = errno;
}
if (retval == NSS_STATUS_NOTFOUND)
- *h_errnop = HOST_NOT_FOUND;
+ {
+ *h_errnop = HOST_NOT_FOUND;
+ *errnop = ENOENT;
+ }
return retval;
}
diff --git a/nis/nss_nis/nis-netgrp.c b/nis/nss_nis/nis-netgrp.c
index d170b56f50..0d3ed44d3f 100644
--- a/nis/nss_nis/nis-netgrp.c
+++ b/nis/nss_nis/nis-netgrp.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -117,7 +117,10 @@ _nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
enum nss_status status;
if (cursor == NULL)
- return NSS_STATUS_NOTFOUND;
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
__libc_lock_lock (lock);
diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c
index 73afd442a9..821accfbae 100644
--- a/nis/nss_nis/nis-publickey.c
+++ b/nis/nss_nis/nis-publickey.c
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -50,8 +50,11 @@ _nss_nis_getpublickey (const char *netname, char *pkey, int *errnop)
domain = strchr (netname, '@');
if (!domain)
- return NSS_STATUS_UNAVAIL;
- domain++;
+ {
+ *errnop = EINVAL;
+ return NSS_STATUS_UNAVAIL;
+ }
+ ++domain;
retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
strlen (netname), &result, &len));
@@ -95,8 +98,11 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
domain = strchr (netname, '@');
if (!domain)
- return NSS_STATUS_UNAVAIL;
- domain++;
+ {
+ *errnop = EINVAL;
+ return NSS_STATUS_UNAVAIL;
+ }
+ ++domain;
retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
strlen (netname), &result, &len));
@@ -196,10 +202,13 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
domain = strchr (netname, '@');
if (!domain)
- return NSS_STATUS_UNAVAIL;
+ {
+ *errnop = EINVAL;
+ return NSS_STATUS_UNAVAIL;
+ }
/* Point past the '@' character */
- domain++;
+ ++domain;
lookup = NULL;
yperr = yp_match (domain, "netid.byname", netname, strlen (netname),
&lookup, &len);
@@ -209,11 +218,13 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
break; /* the successful case */
case YPERR_DOMAIN:
case YPERR_KEY:
+ *errnop = ENOENT;
return NSS_STATUS_NOTFOUND;
case YPERR_MAP:
default:
return NSS_STATUS_UNAVAIL;
}
+
if (lookup)
{
enum nss_status err;
@@ -224,7 +235,9 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
return err;
}
else
- return NSS_STATUS_NOTFOUND;
-
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
return NSS_STATUS_SUCCESS;
}
diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c
index 103b1e4115..cece55c283 100644
--- a/nis/nss_nis/nis-service.c
+++ b/nis/nss_nis/nis-service.c
@@ -172,7 +172,7 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
return NSS_STATUS_NOTFOUND;
}
p = strncpy (buffer, data->next->val, buflen);
- while (isspace (*p))
+ while (isspace (*p))
++p;
parse_res = _nss_files_parse_servent (p, serv, pdata, buflen, errnop);
@@ -215,6 +215,63 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
return NSS_STATUS_UNAVAIL;
}
+ /* If the protocol is given, we could try if our NIS server knows
+ about services.byservicename map. If yes, we only need one query */
+ if (protocol != NULL)
+ {
+ char key[strlen (name) + strlen (protocol) + 2];
+ char *cp, *domain, *result;
+ size_t keylen, len;
+
+ /* If this fails, the other solution will also fail. */
+ if (yp_get_default_domain (&domain))
+ return NSS_STATUS_UNAVAIL;
+
+ /* key is: "name/protocol" */
+ cp = stpcpy (key, name);
+ *cp++ = '/';
+ stpcpy (cp, protocol);
+ keylen = strlen (key);
+ status = yperr2nss (yp_match (domain, "services.byservicename", key,
+ keylen, &result, &len));
+
+ /* If we found the key, it's ok and parse the result. If not,
+ fall through and parse the complete table. */
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ struct parser_data *pdata = (void *) buffer;
+ int parse_res;
+ char *p;
+
+ if ((size_t) (len + 1) > buflen)
+ {
+ free (result);
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ p = strncpy (buffer, result, len);
+ buffer[len] = '\0';
+ while (isspace (*p))
+ ++p;
+ free (result);
+ parse_res = _nss_files_parse_servent (p, serv, pdata,
+ buflen, errnop);
+ if (parse_res < 0)
+ {
+ if (parse_res == -1)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
+ }
+ else
+ return NSS_STATUS_SUCCESS;
+ }
+ }
+
status = internal_nis_setservent (&data);
if (status != NSS_STATUS_SUCCESS)
return status;
@@ -256,10 +313,57 @@ _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
enum nss_status status;
int found;
- if (protocol == NULL)
+ /* If the protocol is given, we only need one query */
+ if (protocol != NULL)
{
- *errnop = EINVAL;
- return NSS_STATUS_UNAVAIL;
+ char key[100 + strlen (protocol) + 2];
+ char *domain, *result;
+ size_t keylen, len;
+
+ /* If this fails, the other solution will also fail. */
+ if (yp_get_default_domain (&domain))
+ return NSS_STATUS_UNAVAIL;
+
+ /* key is: "port/protocol" */
+ keylen = snprintf (key, sizeof (key), "%d/%s", port, protocol);
+ status = yperr2nss (yp_match (domain, "services.byname", key,
+ keylen, &result, &len));
+
+ /* If we found the key, it's ok and parse the result. If not,
+ fall through and parse the complete table. */
+ if (status == NSS_STATUS_SUCCESS)
+ {
+ struct parser_data *pdata = (void *) buffer;
+ int parse_res;
+ char *p;
+
+ if ((size_t) (len + 1) > buflen)
+ {
+ free (result);
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
+
+ p = strncpy (buffer, result, len);
+ buffer[len] = '\0';
+ while (isspace (*p))
+ ++p;
+ free (result);
+ parse_res = _nss_files_parse_servent (p, serv, pdata,
+ buflen, errnop);
+ if (parse_res < 0)
+ {
+ if (parse_res == -1)
+ return NSS_STATUS_TRYAGAIN;
+ else
+ {
+ *errnop = ENOENT;
+ return NSS_STATUS_NOTFOUND;
+ }
+ }
+ else
+ return NSS_STATUS_SUCCESS;
+ }
}
status = internal_nis_setservent (&data);
@@ -270,7 +374,8 @@ _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
while (!found &&
((status = internal_nis_getservent_r (serv, buffer, buflen, errnop,
&data)) == NSS_STATUS_SUCCESS))
- if (serv->s_port == port && strcmp (serv->s_proto, protocol) == 0)
+ if (serv->s_port == port &&
+ (protocol == NULL || strcmp (serv->s_proto, protocol) == 0))
found = 1;
internal_nis_endservent (&data);
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index 1dc9ca3126..00d0f8b4c8 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -1,6 +1,6 @@
/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+ Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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
@@ -42,7 +42,6 @@ struct dom_binding
struct sockaddr_in dom_server_addr;
int dom_socket;
CLIENT *dom_client;
- long int dom_vers;
};
typedef struct dom_binding dom_binding;
@@ -63,7 +62,6 @@ __yp_bind (const char *domain, dom_binding **ypdb)
int clnt_sock;
CLIENT *client;
int is_new = 0;
- int try;
if (domain == NULL || domain[0] == '\0')
return YPERR_BADARGS;
@@ -83,137 +81,127 @@ __yp_bind (const char *domain, dom_binding **ypdb)
{
is_new = 1;
ysd = (dom_binding *) calloc (1, sizeof *ysd);
- ysd->dom_socket = -1;
- ysd->dom_vers = -1;
}
- try = 0;
-
- do
- {
- ++try;
- if (try > MAXTRIES)
- {
- if (is_new)
- free (ysd);
- return YPERR_YPBIND;
- }
-
#if USE_BINDINGDIR
- if (ysd->dom_vers < 1 && try == 1) /* Try binding dir only first time */
+ if (ysd->dom_client == NULL)
+ {
+ /* Try binding dir at first if we have no binding */
+ char path[sizeof (BINDINGDIR) + strlen (domain) + 10];
+ struct iovec vec[2];
+ unsigned short port;
+ int fd;
+
+ sprintf (path, "%s/%s.%d", BINDINGDIR, domain, YPBINDVERS);
+ fd = open (path, O_RDONLY);
+ if (fd >= 0)
{
- char path[sizeof (BINDINGDIR) - 1 + strlen (domain) + 10];
- struct iovec vec[2];
- unsigned short port;
- int fd;
-
- sprintf (path, "%s/%s.%d", BINDINGDIR, domain, YPBINDVERS);
- fd = open (path, O_RDONLY);
- if (fd >= 0)
+ /* We have a binding file and could save a RPC call */
+ vec[0].iov_base = &port;
+ vec[0].iov_len = sizeof (port);
+ vec[1].iov_base = &ypbr;
+ vec[1].iov_len = sizeof (ypbr);
+
+ if (readv (fd, vec, 2) == sizeof (port) + sizeof (ypbr))
{
- /* We have a binding file and could save a RPC call */
- vec[0].iov_base = &port;
- vec[0].iov_len = sizeof (port);
- vec[1].iov_base = &ypbr;
- vec[1].iov_len = sizeof (ypbr);
-
- if (readv (fd, vec, 2) == sizeof (port) + sizeof (ypbr))
- {
- ysd->dom_server_addr.sin_family = AF_INET;
- memcpy (&ysd->dom_server_addr.sin_port,
- ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
- sizeof (ysd->dom_server_addr.sin_port));
- memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
- ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
- sizeof (ysd->dom_server_addr.sin_addr.s_addr));
- ysd->dom_vers = YPVERS;
- strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
- ysd->dom_domain[YPMAXDOMAIN] = '\0';
- }
- close (fd);
+ ysd->dom_server_addr.sin_family = AF_INET;
+ memcpy (&ysd->dom_server_addr.sin_port,
+ ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
+ sizeof (ysd->dom_server_addr.sin_port));
+ memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
+ ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+ sizeof (ysd->dom_server_addr.sin_addr.s_addr));
+ strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+ ysd->dom_domain[YPMAXDOMAIN] = '\0';
+
+ ysd->dom_socket = RPC_ANYSOCK;
+ ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG,
+ YPVERS, UDPTIMEOUT,
+ &ysd->dom_socket);
+
+ if (ysd->dom_client != NULL)
+ /* If the program exits, close the socket */
+ if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
+ perror ("fcntl: F_SETFD");
}
+ close (fd);
}
+ }
#endif /* USE_BINDINGDIR */
- if (ysd->dom_vers == -1)
+ if (ysd->dom_client == NULL)
+ {
+ memset (&clnt_saddr, '\0', sizeof clnt_saddr);
+ clnt_saddr.sin_family = AF_INET;
+ clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+ clnt_sock = RPC_ANYSOCK;
+ client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
+ &clnt_sock, 0, 0);
+ if (client == NULL)
{
- if (ysd->dom_client)
- {
- clnt_destroy (ysd->dom_client);
- ysd->dom_client = NULL;
- ysd->dom_socket = -1;
- }
- memset (&clnt_saddr, '\0', sizeof clnt_saddr);
- clnt_saddr.sin_family = AF_INET;
- clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- clnt_sock = RPC_ANYSOCK;
- client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
- &clnt_sock, 0, 0);
- if (client == NULL)
- {
- if (is_new)
- free (ysd);
- return YPERR_YPBIND;
- }
- /*
- ** Check the port number -- should be < IPPORT_RESERVED.
- ** If not, it's possible someone has registered a bogus
- ** ypbind with the portmapper and is trying to trick us.
- */
- if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
- {
- clnt_destroy (client);
- if (is_new)
- free (ysd);
- return YPERR_YPBIND;
- }
-
- if (clnt_call (client, YPBINDPROC_DOMAIN,
- (xdrproc_t) xdr_domainname, (caddr_t) &domain,
- (xdrproc_t) xdr_ypbind_resp,
- (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
- {
- clnt_destroy (client);
- if (is_new)
- free (ysd);
- return YPERR_YPBIND;
- }
-
- clnt_destroy (client);
-
- if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
- {
- fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
- ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
- if (is_new)
- free (ysd);
- return YPERR_DOMAIN;
- }
- memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
- ysd->dom_server_addr.sin_family = AF_INET;
- memcpy (&ysd->dom_server_addr.sin_port,
- ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
- sizeof (ysd->dom_server_addr.sin_port));
- memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
- ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
- sizeof (ysd->dom_server_addr.sin_addr.s_addr));
- ysd->dom_vers = YPVERS;
- strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
- ysd->dom_domain[YPMAXDOMAIN] = '\0';
- }
+ if (is_new)
+ free (ysd);
+ return YPERR_YPBIND;
+ }
+ /* Check the port number -- should be < IPPORT_RESERVED.
+ If not, it's possible someone has registered a bogus
+ ypbind with the portmapper and is trying to trick us. */
+ if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
+ {
+ clnt_destroy (client);
+ if (is_new)
+ free (ysd);
+ return YPERR_YPBIND;
+ }
+
+ if (clnt_call (client, YPBINDPROC_DOMAIN,
+ (xdrproc_t) xdr_domainname, (caddr_t) &domain,
+ (xdrproc_t) xdr_ypbind_resp,
+ (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
+ {
+ clnt_destroy (client);
+ if (is_new)
+ free (ysd);
+ return YPERR_YPBIND;
+ }
+
+ clnt_destroy (client);
+
+ if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
+ {
+ fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
+ ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
+ if (is_new)
+ free (ysd);
+ return YPERR_DOMAIN;
+ }
+ memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
+ ysd->dom_server_addr.sin_family = AF_INET;
+ memcpy (&ysd->dom_server_addr.sin_port,
+ ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
+ sizeof (ysd->dom_server_addr.sin_port));
+ memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
+ ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+ sizeof (ysd->dom_server_addr.sin_addr.s_addr));
+ strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+ ysd->dom_domain[YPMAXDOMAIN] = '\0';
ysd->dom_socket = RPC_ANYSOCK;
ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
UDPTIMEOUT, &ysd->dom_socket);
- if (ysd->dom_client == NULL)
- ysd->dom_vers = -1;
+ if (ysd->dom_client != NULL)
+ /* If the program exits, close the socket */
+ if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
+ perror ("fcntl: F_SETFD");
}
- while (ysd->dom_client == NULL);
- /* If the program exists, close the socket */
- if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
- perror ("fcntl: F_SETFD");
+ if (ysd->dom_client == NULL)
+ {
+ if (is_new)
+ free (ysd);
+ return YPERR_YPSERV;
+ }
if (is_new && ypdb != NULL)
{
@@ -229,7 +217,60 @@ __yp_unbind (dom_binding *ydb)
{
clnt_destroy (ydb->dom_client);
ydb->dom_client = NULL;
- ydb->dom_socket = -1;
+}
+
+int
+yp_bind (const char *indomain)
+{
+ int status;
+
+ __libc_lock_lock (ypbindlist_lock);
+
+ status = __yp_bind (indomain, &__ypbindlist);
+
+ __libc_lock_unlock (ypbindlist_lock);
+
+ return status;
+}
+
+static void
+yp_unbind_locked (const char *indomain)
+{
+ dom_binding *ydbptr, *ydbptr2;
+
+ ydbptr2 = NULL;
+ ydbptr = __ypbindlist;
+
+ while (ydbptr != NULL)
+ {
+ if (strcmp (ydbptr->dom_domain, indomain) == 0)
+ {
+ dom_binding *work;
+
+ work = ydbptr;
+ if (ydbptr2 == NULL)
+ __ypbindlist = __ypbindlist->dom_pnext;
+ else
+ ydbptr2 = ydbptr->dom_pnext;
+ __yp_unbind (work);
+ free (work);
+ break;
+ }
+ ydbptr2 = ydbptr;
+ ydbptr = ydbptr->dom_pnext;
+ }
+}
+
+void
+yp_unbind (const char *indomain)
+{
+ __libc_lock_lock (ypbindlist_lock);
+
+ yp_unbind_locked (indomain);
+
+ __libc_lock_unlock (ypbindlist_lock);
+
+ return;
}
static int
@@ -278,14 +319,26 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
if (result != RPC_SUCCESS)
{
- clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
- ydb->dom_vers = -1;
- if (!use_ypbindlist)
+ /* Don't print the error message on the first try. It
+ could be that we use cached data which is now invalid. */
+ if (try != 0)
+ clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
+
+ if (use_ypbindlist)
+ {
+ /* We use ypbindlist, and the old cached data is
+ invalid. unbind now and create a new binding */
+ yp_unbind_locked (domain);
+ __libc_lock_unlock (ypbindlist_lock);
+ use_ypbindlist = FALSE;
+ }
+ else
{
__yp_unbind (ydb);
free (ydb);
- ydb = NULL;
}
+
+ ydb = NULL;
status = YPERR_RPC;
}
else
@@ -311,52 +364,6 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
return status;
}
-int
-yp_bind (const char *indomain)
-{
- int status;
-
- __libc_lock_lock (ypbindlist_lock);
-
- status = __yp_bind (indomain, &__ypbindlist);
-
- __libc_lock_unlock (ypbindlist_lock);
-
- return status;
-}
-
-void
-yp_unbind (const char *indomain)
-{
- dom_binding *ydbptr, *ydbptr2;
-
- __libc_lock_lock (ypbindlist_lock);
-
- ydbptr2 = NULL;
- ydbptr = __ypbindlist;
- while (ydbptr != NULL)
- {
- if (strcmp (ydbptr->dom_domain, indomain) == 0)
- {
- dom_binding *work;
-
- work = ydbptr;
- if (ydbptr2 == NULL)
- __ypbindlist = __ypbindlist->dom_pnext;
- else
- ydbptr2 = ydbptr->dom_pnext;
- __yp_unbind (work);
- free (work);
- break;
- }
- ydbptr2 = ydbptr;
- ydbptr = ydbptr->dom_pnext;
- }
-
- __libc_lock_unlock (ypbindlist_lock);
-
- return;
-}
__libc_lock_define_initialized (static, domainname_lock)
@@ -374,7 +381,7 @@ yp_get_default_domain (char **outdomain)
result = YPERR_NODOM;
else if (strcmp (__ypdomainname, "(none)") == 0)
{
- /* If domainname is not set, some Systems will return "(none)" */
+ /* If domainname is not set, some systems will return "(none)" */
__ypdomainname[0] = '\0';
result = YPERR_NODOM;
}
@@ -629,6 +636,10 @@ __xdr_ypresp_all (XDR *xdrs, u_long *objp)
int keylen = resp.ypresp_all_u.val.key.keydat_len;
int vallen = resp.ypresp_all_u.val.val.valdat_len;
+ /* We are not allowed to modify the key and val data.
+ But we are allowed to add data behind the buffer,
+ if we don't modify the length. So add an extra NUL
+ character to avoid trouble with broken code. */
*objp = YP_TRUE;
memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
key[keylen] = '\0';
@@ -640,14 +651,13 @@ __xdr_ypresp_all (XDR *xdrs, u_long *objp)
return TRUE;
}
break;
- case YP_NOMORE:
- *objp = YP_NOMORE;
- xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
- return TRUE;
- break;
default:
*objp = resp.ypresp_all_u.val.stat;
xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
+ /* Sun says we don't need to make this call, but must return
+ immediatly. Since Solaris makes this call, we will call
+ the callback function, too. */
+ (*ypall_foreach) (*objp, NULL, 0, NULL, 0, ypall_data);
return TRUE;
}
}
diff --git a/rt/Makefile b/rt/Makefile
index b102cc834e..2044eb4bf6 100644
--- a/rt/Makefile
+++ b/rt/Makefile
@@ -35,7 +35,7 @@ include ../Makeconfig
ifeq ($(have-thread-library),yes)
-tests := tst-aio
+tests := tst-aio tst-aio64
extra-libs := librt
extra-libs-others := $(extra-libs)
@@ -51,6 +51,8 @@ $(objpfx)librt.so: $(common-objpfx)libc.so $(shared-thread-library)
ifeq (yes,$(build-shared))
$(objpfx)tst-aio: $(objpfx)librt.so $(shared-thread-library)
+$(objpfx)tst-aio64: $(objpfx)librt.so $(shared-thread-library)
else
$(objpfx)tst-aio: $(objpfx)librt.a $(static-thread-library)
-endif \ No newline at end of file
+$(objpfx)tst-aio64: $(objpfx)librt.a $(static-thread-library)
+endif
diff --git a/rt/aio.h b/rt/aio.h
index 0190ce9cd5..205d63afe7 100644
--- a/rt/aio.h
+++ b/rt/aio.h
@@ -57,7 +57,8 @@ struct aiocb
char __unused[32];
};
-/* The same for the 64bit offsets. */
+/* The same for the 64bit offsets. Please note that the members aio_fildes
+ to __return_value have to be the same in aiocb and aiocb64. */
#ifdef __USE_LARGEFILE64
struct aiocb64
{
@@ -69,6 +70,7 @@ struct aiocb64
struct sigevent aio_sigevent; /* Signal number and value. */
/* Internal members. */
+ struct aiocb *__next_prio;
int __abs_prio;
int __policy;
int __error_code;
diff --git a/rt/tst-aio64.c b/rt/tst-aio64.c
new file mode 100644
index 0000000000..60db0dd1aa
--- /dev/null
+++ b/rt/tst-aio64.c
@@ -0,0 +1,196 @@
+/* Tests for 64bit AIO in librt.
+ Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ 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. */
+
+#define _LARGEFILE_SOURCE 1
+#include <aio.h>
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+/* Prototype for our test function. */
+extern void do_prepare (int argc, char *argv[]);
+extern int do_test (int argc, char *argv[]);
+
+/* We have a preparation function. */
+#define PREPARE do_prepare
+
+/* We might need a bit longer timeout. */
+#define TIMEOUT 20 /* sec */
+
+/* This defines the `main' function and some more. */
+#include <test-skeleton.c>
+
+
+/* These are for the temporary file we generate. */
+char *name;
+int fd;
+
+void
+do_prepare (int argc, char *argv[])
+{
+ char name_len;
+
+ name_len = strlen (test_dir);
+ name = malloc (name_len + sizeof ("/aioXXXXXX"));
+ mempcpy (mempcpy (name, test_dir, name_len),
+ "/aioXXXXXX", sizeof ("/aioXXXXXX"));
+ add_temp_file (name);
+
+ /* Open our test file. */
+ fd = mkstemp (name);
+ if (fd == -1)
+ error (EXIT_FAILURE, errno, "cannot open test file `%s'", name);
+}
+
+
+int
+test_file (const void *buf, size_t size, int fd, const char *msg)
+{
+ struct stat st;
+ char tmp[size];
+
+ errno = 0;
+ if (fstat (fd, &st) < 0)
+ {
+ error (0, errno, "%s: failed stat", msg);
+ return 1;
+ }
+
+ if (st.st_size != size)
+ {
+ error (0, errno, "%s: wrong size: %lu, should be %lu",
+ msg, (unsigned long int) st.st_size, (unsigned long int) size);
+ return 1;
+ }
+
+ if (pread (fd, tmp, size, 0) != size)
+ {
+ error (0, errno, "%s: failed stat", msg);
+ return 1;
+ }
+
+ if (memcmp (buf, tmp, size) != 0)
+ {
+ error (0, errno, "%s: failed comparison", msg);
+ return 1;
+ }
+
+ printf ("%s test ok\n", msg);
+
+ return 0;
+}
+
+
+void
+do_wait (struct aiocb64 **cbp, size_t nent)
+{
+ int go_on;
+ do
+ {
+ size_t cnt;
+
+ aio_suspend64 ((const struct aiocb64 *const *) cbp, nent, NULL);
+ go_on = 0;
+ for (cnt = 0; cnt < nent; ++cnt)
+ if (cbp[cnt] != NULL && aio_error64 (cbp[cnt]) == EINPROGRESS)
+ go_on = 1;
+ else
+ cbp[cnt] = NULL;
+ }
+ while (go_on);
+}
+
+
+int
+do_test (int argc, char *argv[])
+{
+ struct aiocb64 cbs[10];
+ struct aiocb64 *cbp[10];
+ char buf[1000];
+ size_t cnt;
+ int result = 0;
+
+ /* Preparation. */
+ for (cnt = 0; cnt < 10; ++cnt)
+ {
+ cbs[cnt].aio_fildes = fd;
+ cbs[cnt].aio_reqprio = 0;
+ cbs[cnt].aio_buf = memset (&buf[cnt * 100], '0' + cnt, 100);
+ cbs[cnt].aio_nbytes = 100;
+ cbs[cnt].aio_offset = cnt * 100;
+ cbs[cnt].aio_sigevent.sigev_notify = SIGEV_NONE;
+
+ cbp[cnt] = &cbs[cnt];
+ }
+
+ /* First a simple test. */
+ for (cnt = 10; cnt > 0; )
+ aio_write64 (cbp[--cnt]);
+ /* Wait 'til the results are there. */
+ do_wait (cbp, 10);
+ /* Test this. */
+ result |= test_file (buf, sizeof (buf), fd, "aio_write");
+
+ /* Read now as we've written it. */
+ memset (buf, '\0', sizeof (buf));
+ /* Issue the commands. */
+ for (cnt = 10; cnt > 0; )
+ {
+ --cnt;
+ cbp[cnt] = &cbs[cnt];
+ aio_read64 (cbp[cnt]);
+ }
+ /* Wait 'til the results are there. */
+ do_wait (cbp, 10);
+ /* Test this. */
+ for (cnt = 0; cnt < 1000; ++cnt)
+ if (buf[cnt] != '0' + (cnt / 100))
+ {
+ result = 1;
+ error (0, 0, "comparison failed for aio_read test");
+ break;
+ }
+
+ if (cnt == 1000)
+ puts ("aio_read test ok");
+
+ /* Remove the test file contents. */
+ if (ftruncate64 (fd, 0) < 0)
+ {
+ error (0, errno, "ftruncate failed\n");
+ result = 1;
+ }
+
+ /* Test lio_listio. */
+ for (cnt = 0; cnt < 10; ++cnt)
+ {
+ cbs[cnt].aio_lio_opcode = LIO_WRITE;
+ cbp[cnt] = &cbs[cnt];
+ }
+ /* Issue the command. */
+ lio_listio64 (LIO_WAIT, cbp, 10, NULL);
+ /* ...and immediately test it since we started it in wait mode. */
+ result |= test_file (buf, sizeof (buf), fd, "lio_listio (write)");
+
+ return result;
+}
diff --git a/stdlib/longlong.h b/stdlib/longlong.h
index f76f4799c7..a2e56c4c67 100644
--- a/stdlib/longlong.h
+++ b/stdlib/longlong.h
@@ -1185,8 +1185,8 @@ UDItype __umulsidi3 (USItype, USItype);
#if (defined (__sparc_v9__) || (defined (__sparc__) && defined (__arch64__)) \
|| defined (__sparcv9)) && W_TYPE_SIZE == 64
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addcc %4,%5,%1
- add %2,%3,%0
+ __asm__ ("addcc %r4,%5,%1
+ add %r2,%3,%0
bcs,a,pn %%xcc, 1f
add %0, 1, %0
1:" \
@@ -1199,8 +1199,8 @@ UDItype __umulsidi3 (USItype, USItype);
__CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subcc %4,%5,%1
- sub %2,%3,%0
+ __asm__ ("subcc %r4,%5,%1
+ sub %r2,%3,%0
bcs,a,pn %%xcc, 1f
sub %0, 1, %0
1:" \
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 4d1baa2062..336aafef9a 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -118,7 +118,7 @@ __STRING2_COPY_TYPE (8);
__uint8_t __c = (__uint8_t) (c); \
\
/* This `switch' statement will be removed at compile-time. */ \
- switch ((unsigned int) n) \
+ switch ((unsigned int) (n)) \
{ \
case 15: \
__u->__ui = __c * 0x01010101; \
@@ -1078,8 +1078,10 @@ __strtok_r_1c (char *__s, char __sep, char **__nextp)
__extension__ \
({ char __r0, __r1, __r2; \
(__builtin_constant_p (reject) && __string2_1bptr_p (reject) \
- && (__r0 = ((__const char *) (reject))[0], __r0 != '\0') \
- ? ((__r1 = ((__const char *) (reject))[1], __r1 == '\0') \
+ && (__r0 = ((__const char *) (reject))[0], \
+ ((__const char *) (reject))[0] != '\0') \
+ ? ((__r1 = ((__const char *) (reject))[1], \
+ ((__const char *) (reject))[1] == '\0') \
? __strsep_1c (s, __r0) \
: ((__r2 = ((__const char *) (reject))[2], __r2 == '\0') \
? __strsep_2c (s, __r0, __r1) \
diff --git a/string/tester.c b/string/tester.c
index 4fed10e4b4..d9043e046f 100644
--- a/string/tester.c
+++ b/string/tester.c
@@ -807,6 +807,7 @@ test_strtok_r (void)
void
test_strsep (void)
{
+ char *ptr;
it = "strsep";
cp = strcpy(one, "first, second, third");
equal(strsep(&cp, ", "), "first", 1); /* Basic test. */
@@ -901,6 +902,32 @@ test_strsep (void)
equal(strsep(&cp, "xy,"), "", 71);
check(strsep(&cp, "x,y") == NULL, 72);
check(strsep(&cp, ",xy") == NULL, 73); /* Persistence. */
+
+ cp = strcpy(one, "ABC");
+ one[4] = ':';
+ equal(strsep(&cp, "C"), "AB", 74); /* Access beyond NUL. */
+ ptr = strsep(&cp, ":");
+ equal(ptr, "", 75);
+ check(ptr == one + 3, 76);
+ check(cp == NULL, 77);
+
+ cp = strcpy(one, "ABC");
+ one[4] = ':';
+ equal(strsep(&cp, "CD"), "AB", 78); /* Access beyond NUL. */
+ ptr = strsep(&cp, ":.");
+ equal(ptr, "", 79);
+ check(ptr == one + 3, 80);
+
+ cp = strcpy(one, "ABC"); /* No token in string. */
+ equal(strsep(&cp, ","), "ABC", 81);
+ check(cp == NULL, 82);
+
+ *one = '\0'; /* Empty string. */
+ cp = one;
+ ptr = strsep(&cp, ",");
+ equal(ptr, "", 83);
+ check(ptr == one, 84);
+ check(cp == NULL, 85);
}
void
diff --git a/sysdeps/alpha/fpu/bits/mathdef.h b/sysdeps/alpha/fpu/bits/mathdef.h
index f5d5de8b12..30f93dda1c 100644
--- a/sysdeps/alpha/fpu/bits/mathdef.h
+++ b/sysdeps/alpha/fpu/bits/mathdef.h
@@ -23,7 +23,9 @@
/* FIXME! This file describes properties of the compiler, not the machine;
it should not be part of libc! */
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
# ifdef __GNUC__
# if __STDC__ == 1
diff --git a/sysdeps/generic/bits/mathdef.h b/sysdeps/generic/bits/mathdef.h
index d306e54366..0c30b01f52 100644
--- a/sysdeps/generic/bits/mathdef.h
+++ b/sysdeps/generic/bits/mathdef.h
@@ -20,7 +20,9 @@
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
#endif
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
/* Normally, there is no long double type and the `float' and `double'
expressions are evaluated as `double'. */
typedef double float_t; /* `float' expressions are evaluated as
diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c
index 7ca44f3c3a..004d8d8ac2 100644
--- a/sysdeps/generic/strsep.c
+++ b/sysdeps/generic/strsep.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 93, 96, 97, 98, 99 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
@@ -43,6 +43,8 @@ __strsep (char **stringp, const char *delim)
{
if (*begin == ch)
end = begin;
+ else if (*begin == '\0')
+ end = NULL;
else
end = strchr (begin + 1, ch);
}
diff --git a/sysdeps/i386/fpu/bits/mathdef.h b/sysdeps/i386/fpu/bits/mathdef.h
index ba5129895d..9436877a77 100644
--- a/sysdeps/i386/fpu/bits/mathdef.h
+++ b/sysdeps/i386/fpu/bits/mathdef.h
@@ -20,7 +20,9 @@
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
#endif
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
/* 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: */
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index 443117da63..195bcca168 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -488,10 +488,14 @@ Test "Real part of: ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383
ildouble: 2
ldouble: 2
Test "Imaginary part of: ctanh (-2 - 3 i) == -0.9653858790221331242 + 0.0098843750383224937 i":
+float: 1
+ifloat: 1
ildouble: 23
ldouble: 23
Test "Real part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i":
+float: 1
+ifloat: 1
double: 0.5
idouble: 0.5
Test "Real part of: ctanh (0.7 + 1.2 i) == 1.3472197399061191630 + 0.4778641038326365540 i":
@@ -636,6 +640,9 @@ idouble: 1
Test "j0 (8.0) == 0.17165080713755390609":
float: 1
ifloat: 1
+Test "j0 (10.0) == -0.24593576445134833520":
+double: 2
+idouble: 2
# j1
Test "j1 (10.0) == 0.043472746168861436670":
@@ -654,6 +661,8 @@ ifloat: 1
Test "jn (0, 10.0) == -0.24593576445134833520":
float: 1
ifloat: 1
+double: 2
+idouble: 2
Test "jn (0, 2.0) == 0.22389077914123566805":
float: 1
ifloat: 1
@@ -673,33 +682,46 @@ idouble: 1
Test "jn (1, 8.0) == 0.23463634685391462438":
float: 1
ifloat: 1
+Test "jn (10, -1.0) == 0.26306151236874532070e-9":
+float: 1
+ifloat: 1
Test "jn (10, 0.1) == 0.26905328954342155795e-19":
double: 4
float: 2
idouble: 4
ifloat: 2
Test "jn (10, 0.7) == 0.75175911502153953928e-11":
-double: 3
+double: 4
float: 1
-idouble: 3
+idouble: 4
ifloat: 1
-Test "jn (10, 2.0) == 0.25153862827167367096e-6":
+Test "jn (10, 1.0) == 0.26306151236874532070e-9":
float: 1
ifloat: 1
-double: 1
-idouble: 1
-Test "jn (10, 10.0) == 0.20748610663335885770":
+Test "jn (10, 2.0) == 0.25153862827167367096e-6":
float: 1
ifloat: 1
+double: 2
+idouble: 2
+Test "jn (10, 10.0) == 0.20748610663335885770":
+float: 2
+ifloat: 2
+double: 4
+idouble: 4
Test "jn (3, 0.1) == 0.000020820315754756261429":
double: 1
idouble: 1
Test "jn (3, 0.7) == 0.0069296548267508408077":
double: 2
idouble: 2
+Test "jn (3, 2.0) == 0.12894324947440205110":
+double: 1
+idouble: 1
Test "jn (3, 10.0) == 0.058379379305186812343":
float: 1
ifloat: 1
+double: 3
+idouble: 3
# lgamma
Test "lgamma (-0.5) == log(2*sqrt(pi))":
@@ -847,6 +869,8 @@ float: 1
idouble: 1
ifloat: 1
Test "y0 (0.7) == -0.19066492933739506743":
+float: 1
+ifloat: 1
double: 2
idouble: 2
Test "y0 (1.0) == 0.088256964215676957983":
@@ -857,6 +881,8 @@ ifloat: 1
Test "y0 (1.5) == 0.38244892379775884396":
float: 1
ifloat: 1
+double: 1
+idouble: 1
Test "y0 (2.0) == 0.51037567264974511960":
double: 1
idouble: 1
@@ -891,9 +917,9 @@ idouble: 3
ifloat: 2
Test "y1 (2.0) == -0.10703243154093754689":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
Test "y1 (8.0) == -0.15806046173124749426":
float: 2
ifloat: 2
@@ -905,6 +931,8 @@ float: 1
idouble: 1
ifloat: 1
Test "yn (0, 0.7) == -0.19066492933739506743":
+float: 1
+ifloat: 1
double: 2
idouble: 2
Test "yn (0, 1.0) == 0.088256964215676957983":
@@ -915,6 +943,8 @@ ifloat: 1
Test "yn (0, 1.5) == 0.38244892379775884396":
float: 1
ifloat: 1
+double: 1
+idouble: 1
Test "yn (0, 2.0) == 0.51037567264974511960":
double: 1
idouble: 1
@@ -947,9 +977,9 @@ idouble: 3
ifloat: 2
Test "yn (1, 2.0) == -0.10703243154093754689":
double: 1
-float: 1
+float: 2
idouble: 1
-ifloat: 1
+ifloat: 2
Test "yn (1, 8.0) == -0.15806046173124749426":
float: 2
ifloat: 2
@@ -974,8 +1004,8 @@ ifloat: 1
Test "yn (10, 2.0) == -129184.54220803928264":
float: 1
ifloat: 1
-double: 1
-idouble: 1
+double: 2
+idouble: 2
Test "yn (3, 0.1) == -5099.3323786129048894":
double: 1
float: 1
@@ -984,6 +1014,9 @@ ifloat: 1
Test "yn (3, 0.7) == -15.819479052819633505":
double: 2
idouble: 2
+Test "yn (3, 2.0) == -1.1277837768404277861":
+double: 1
+idouble: 1
Test "yn (3, 10.0) == -0.25136265718383732978":
double: 1
float: 1
@@ -1263,6 +1296,8 @@ ildouble: 286
ldouble: 286
Function: Imaginary part of "ctanh":
+float: 1
+ifloat: 1
double: 1
idouble: 1
ildouble: 3074
@@ -1313,8 +1348,8 @@ ldouble: 560
Function: "j0":
float: 1
ifloat: 1
-double: 1
-idouble: 1
+double: 2
+idouble: 2
Function: "j1":
double: 1
diff --git a/sysdeps/m68k/fpu/bits/mathdef.h b/sysdeps/m68k/fpu/bits/mathdef.h
index 2f650ec8b5..c80dad3fe1 100644
--- a/sysdeps/m68k/fpu/bits/mathdef.h
+++ b/sysdeps/m68k/fpu/bits/mathdef.h
@@ -20,7 +20,9 @@
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
#endif
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
/* The m68k FPUs evaluate all values in the 96 bit floating-point format
which is also available for the user as `long double'. Therefore we
define: */
diff --git a/sysdeps/powerpc/fpu/bits/mathdef.h b/sysdeps/powerpc/fpu/bits/mathdef.h
index 71378c8458..577a596843 100644
--- a/sysdeps/powerpc/fpu/bits/mathdef.h
+++ b/sysdeps/powerpc/fpu/bits/mathdef.h
@@ -27,7 +27,9 @@
FIXME! This file does not deal with the -fshort-double option of
gcc! */
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
# ifdef __GNUC__
# if __STDC__ == 1
diff --git a/sysdeps/sparc/fpu/bits/mathdef.h b/sysdeps/sparc/fpu/bits/mathdef.h
index c58167ce83..9477790654 100644
--- a/sysdeps/sparc/fpu/bits/mathdef.h
+++ b/sysdeps/sparc/fpu/bits/mathdef.h
@@ -25,7 +25,9 @@
/* FIXME! This file describes properties of the compiler, not the machine;
it should not be part of libc! */
-#if defined __USE_ISOC99 && defined _MATH_H
+#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF
+# define _MATH_H_MATHDEF 1
+
# ifdef __GNUC__
# if __STDC__ == 1
diff --git a/sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c
deleted file mode 100644
index 9feab0e6b8..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/oldgetrlimit64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* getrlimit64 is the same as getrlimit. */
diff --git a/sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c b/sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c
deleted file mode 100644
index 8edcff0086..0000000000
--- a/sysdeps/unix/sysv/linux/alpha/oldsetrlimit64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* setrlimit64 is the same as setrlimit. */
diff --git a/sysdeps/unix/sysv/linux/bits/resource.h b/sysdeps/unix/sysv/linux/bits/resource.h
index fcff605892..6a3d86ce18 100644
--- a/sysdeps/unix/sysv/linux/bits/resource.h
+++ b/sysdeps/unix/sysv/linux/bits/resource.h
@@ -106,13 +106,13 @@ enum __rlimit_resource
/* Value to indicate that there is no limit. */
#ifndef __USE_FILE_OFFSET64
-# define RLIM_INFINITY ((unsigned long int)(~0UL))
+# define RLIM_INFINITY ((long int)(~0UL >> 1))
#else
-# define RLIM_INFINITY 0xffffffffffffffffuLL
+# define RLIM_INFINITY 0x7fffffffffffffffLL
#endif
#ifdef __USE_LARGEFILE64
-# define RLIM64_INFINITY 0xffffffffffffffffuLL
+# define RLIM64_INFINITY 0x7fffffffffffffffLL
#endif
/* We can represent all limits. */
diff --git a/sysdeps/unix/sysv/linux/i386/bits/resource.h b/sysdeps/unix/sysv/linux/i386/bits/resource.h
new file mode 100644
index 0000000000..fcff605892
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/i386/bits/resource.h
@@ -0,0 +1,227 @@
+/* Bit values & structures for resource limits. Linux version.
+ Copyright (C) 1994, 1996, 1997, 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. */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <asm/resource.h>
+#include <bits/types.h>
+
+/* Transmute defines to enumerations. The macro re-definitions are
+ necessary because some programs want to test for operating system
+ features with #ifdef RUSAGE_SELF. In ISO C the reflexive
+ definition is a no-op. */
+
+/* Kinds of resource limit. */
+enum __rlimit_resource
+{
+ /* Per-process CPU limit, in seconds. */
+ _RLIMIT_CPU = RLIMIT_CPU,
+#undef RLIMIT_CPU
+ RLIMIT_CPU = _RLIMIT_CPU,
+#define RLIMIT_CPU RLIMIT_CPU
+
+ /* Largest file that can be created, in bytes. */
+ _RLIMIT_FSIZE = RLIMIT_FSIZE,
+#undef RLIMIT_FSIZE
+ RLIMIT_FSIZE = _RLIMIT_FSIZE,
+#define RLIMIT_FSIZE RLIMIT_FSIZE
+
+ /* Maximum size of data segment, in bytes. */
+ _RLIMIT_DATA = RLIMIT_DATA,
+#undef RLIMIT_DATA
+ RLIMIT_DATA = _RLIMIT_DATA,
+#define RLIMIT_DATA RLIMIT_DATA
+
+ /* Maximum size of stack segment, in bytes. */
+ _RLIMIT_STACK = RLIMIT_STACK,
+#undef RLIMIT_STACK
+ RLIMIT_STACK = _RLIMIT_STACK,
+#define RLIMIT_STACK RLIMIT_STACK
+
+ /* Largest core file that can be created, in bytes. */
+ _RLIMIT_CORE = RLIMIT_CORE,
+#undef RLIMIT_CORE
+ RLIMIT_CORE = _RLIMIT_CORE,
+#define RLIMIT_CORE RLIMIT_CORE
+
+ /* Largest resident set size, in bytes.
+ This affects swapping; processes that are exceeding their
+ resident set size will be more likely to have physical memory
+ taken from them. */
+ _RLIMIT_RSS = RLIMIT_RSS,
+#undef RLIMIT_RSS
+ RLIMIT_RSS = _RLIMIT_RSS,
+#define RLIMIT_RSS RLIMIT_RSS
+
+ /* Number of open files. */
+ _RLIMIT_NOFILE = RLIMIT_NOFILE,
+#undef RLIMIT_NOFILE
+ RLIMIT_NOFILE = _RLIMIT_NOFILE,
+ RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE RLIMIT_OFILE
+
+ /* Address space limit (?) */
+ _RLIMIT_AS = RLIMIT_AS,
+#undef RLIMIT_AS
+ RLIMIT_AS = _RLIMIT_AS,
+#define RLIMIT_AS RLIMIT_AS
+
+ /* Number of processes. */
+ _RLIMIT_NPROC = RLIMIT_NPROC,
+#undef RLIMIT_NPROC
+ RLIMIT_NPROC = _RLIMIT_NPROC,
+#define RLIMIT_NPROC RLIMIT_NPROC
+
+ /* Locked-in-memory address space. */
+ _RLIMIT_MEMLOCK = RLIMIT_MEMLOCK,
+#undef RLIMIT_MEMLOCK
+ RLIMIT_MEMLOCK = _RLIMIT_MEMLOCK,
+#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK
+
+ RLIMIT_NLIMITS = RLIM_NLIMITS,
+#undef RLIM_NLIMITS
+ RLIM_NLIMITS = RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS RLIMIT_NLIMITS
+#define RLIM_NLIMITS RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit. */
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((unsigned long int)(~0UL))
+#else
+# define RLIM_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffuLL
+#endif
+
+/* We can represent all limits. */
+#define RLIM_SAVED_MAX RLIM_INFINITY
+#define RLIM_SAVED_CUR RLIM_INFINITY
+
+
+/* Type for resource quantity measurement. */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+ {
+ /* The current (soft) limit. */
+ rlim_t rlim_cur;
+ /* The hard limit. */
+ rlim_t rlim_max;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+ {
+ /* The current (soft) limit. */
+ rlim64_t rlim_cur;
+ /* The hard limit. */
+ rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want? */
+enum __rusage_who
+{
+ /* The calling process. */
+ RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+ /* All of its terminated child processes. */
+ RUSAGE_CHILDREN = -1,
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+
+ /* Both. */
+ RUSAGE_BOTH = -2
+#define RUSAGE_BOTH RUSAGE_BOTH
+};
+
+#define __need_timeval
+#include <bits/time.h> /* For `struct timeval'. */
+
+/* Structure which says how much of each resource has been used. */
+struct rusage
+ {
+ /* Total amount of user time used. */
+ struct timeval ru_utime;
+ /* Total amount of system time used. */
+ struct timeval ru_stime;
+ /* Maximum resident set size (in kilobytes). */
+ long int ru_maxrss;
+ /* Amount of sharing of text segment memory
+ with other processes (kilobyte-seconds). */
+ long int ru_ixrss;
+ /* Amount of data segment memory used (kilobyte-seconds). */
+ long int ru_idrss;
+ /* Amount of stack memory used (kilobyte-seconds). */
+ long int ru_isrss;
+ /* Number of soft page faults (i.e. those serviced by reclaiming
+ a page from the list of pages awaiting reallocation. */
+ long int ru_minflt;
+ /* Number of hard page faults (i.e. those that required I/O). */
+ long int ru_majflt;
+ /* Number of times a process was swapped out of physical memory. */
+ long int ru_nswap;
+ /* Number of input operations via the file system. Note: This
+ and `ru_oublock' do not include operations with the cache. */
+ long int ru_inblock;
+ /* Number of output operations via the file system. */
+ long int ru_oublock;
+ /* Number of IPC messages sent. */
+ long int ru_msgsnd;
+ /* Number of IPC messages received. */
+ long int ru_msgrcv;
+ /* Number of signals delivered. */
+ long int ru_nsignals;
+ /* Number of voluntary context switches, i.e. because the process
+ gave up the process before it had to (usually to wait for some
+ resource to be available). */
+ long int ru_nvcsw;
+ /* Number of involuntary context switches, i.e. a higher priority process
+ became runnable or the current process used up its time slice. */
+ long int ru_nivcsw;
+ };
+
+/* Priority limits. */
+#define PRIO_MIN -20 /* Minimum priority a process can have. */
+#define PRIO_MAX 20 /* Maximum priority a process can have. */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+ indicating what flavor of entity the WHO argument specifies. */
+enum __priority_which
+{
+ PRIO_PROCESS = 0, /* WHO is a process ID. */
+#define PRIO_PROCESS PRIO_PROCESS
+ PRIO_PGRP = 1, /* WHO is a process group ID. */
+#define PRIO_PGRP PRIO_PGRP
+ PRIO_USER = 2 /* WHO is a user ID. */
+#define PRIO_USER PRIO_USER
+};
diff --git a/sysdeps/unix/sysv/linux/getrlimit.c b/sysdeps/unix/sysv/linux/i386/getrlimit.c
index 14a879c5df..14a879c5df 100644
--- a/sysdeps/unix/sysv/linux/getrlimit.c
+++ b/sysdeps/unix/sysv/linux/i386/getrlimit.c
diff --git a/sysdeps/unix/sysv/linux/getrlimit64.c b/sysdeps/unix/sysv/linux/i386/getrlimit64.c
index 602dd28d8a..602dd28d8a 100644
--- a/sysdeps/unix/sysv/linux/getrlimit64.c
+++ b/sysdeps/unix/sysv/linux/i386/getrlimit64.c
diff --git a/sysdeps/unix/sysv/linux/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c
index 5fb0becfbe..5fb0becfbe 100644
--- a/sysdeps/unix/sysv/linux/oldgetrlimit64.c
+++ b/sysdeps/unix/sysv/linux/i386/oldgetrlimit64.c
diff --git a/sysdeps/unix/sysv/linux/oldsetrlimit64.c b/sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c
index c5448dcdce..c5448dcdce 100644
--- a/sysdeps/unix/sysv/linux/oldsetrlimit64.c
+++ b/sysdeps/unix/sysv/linux/i386/oldsetrlimit64.c
diff --git a/sysdeps/unix/sysv/linux/setrlimit.c b/sysdeps/unix/sysv/linux/i386/setrlimit.c
index 2123360fc9..2123360fc9 100644
--- a/sysdeps/unix/sysv/linux/setrlimit.c
+++ b/sysdeps/unix/sysv/linux/i386/setrlimit.c
diff --git a/sysdeps/unix/sysv/linux/setrlimit64.c b/sysdeps/unix/sysv/linux/i386/setrlimit64.c
index 3e7e5cc0e0..3e7e5cc0e0 100644
--- a/sysdeps/unix/sysv/linux/setrlimit64.c
+++ b/sysdeps/unix/sysv/linux/i386/setrlimit64.c
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/resource.h b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
new file mode 100644
index 0000000000..abfe433c59
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/resource.h
@@ -0,0 +1,243 @@
+/* Bit values & structures for resource limits. Linux version.
+ Copyright (C) 1994, 1996, 1997, 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. */
+
+#ifndef _SYS_RESOURCE_H
+# error "Never use <bits/resource.h> directly; include <sys/resource.h> instead."
+#endif
+
+#include <asm/resource.h>
+#include <bits/types.h>
+
+/* Transmute defines to enumerations. The macro re-definitions are
+ necessary because some programs want to test for operating system
+ features with #ifdef RUSAGE_SELF. In ISO C the reflexive
+ definition is a no-op. */
+
+/* Kinds of resource limit. */
+enum __rlimit_resource
+{
+ /* Per-process CPU limit, in seconds. */
+ _RLIMIT_CPU = RLIMIT_CPU,
+#undef RLIMIT_CPU
+ RLIMIT_CPU = _RLIMIT_CPU,
+#define RLIMIT_CPU RLIMIT_CPU
+
+ /* Largest file that can be created, in bytes. */
+ _RLIMIT_FSIZE = RLIMIT_FSIZE,
+#undef RLIMIT_FSIZE
+ RLIMIT_FSIZE = _RLIMIT_FSIZE,
+#define RLIMIT_FSIZE RLIMIT_FSIZE
+
+ /* Maximum size of data segment, in bytes. */
+ _RLIMIT_DATA = RLIMIT_DATA,
+#undef RLIMIT_DATA
+ RLIMIT_DATA = _RLIMIT_DATA,
+#define RLIMIT_DATA RLIMIT_DATA
+
+ /* Maximum size of stack segment, in bytes. */
+ _RLIMIT_STACK = RLIMIT_STACK,
+#undef RLIMIT_STACK
+ RLIMIT_STACK = _RLIMIT_STACK,
+#define RLIMIT_STACK RLIMIT_STACK
+
+ /* Largest core file that can be created, in bytes. */
+ _RLIMIT_CORE = RLIMIT_CORE,
+#undef RLIMIT_CORE
+ RLIMIT_CORE = _RLIMIT_CORE,
+#define RLIMIT_CORE RLIMIT_CORE
+
+ /* Largest resident set size, in bytes.
+ This affects swapping; processes that are exceeding their
+ resident set size will be more likely to have physical memory
+ taken from them. */
+ _RLIMIT_RSS = RLIMIT_RSS,
+#undef RLIMIT_RSS
+ RLIMIT_RSS = _RLIMIT_RSS,
+#define RLIMIT_RSS RLIMIT_RSS
+
+ /* Number of open files. */
+ _RLIMIT_NOFILE = RLIMIT_NOFILE,
+#undef RLIMIT_NOFILE
+ RLIMIT_NOFILE = _RLIMIT_NOFILE,
+ RLIMIT_OFILE = RLIMIT_NOFILE, /* BSD name for same. */
+#define RLIMIT_NOFILE RLIMIT_NOFILE
+#define RLIMIT_OFILE RLIMIT_OFILE
+
+ /* Address space limit (?) */
+ _RLIMIT_AS = RLIMIT_AS,
+#undef RLIMIT_AS
+ RLIMIT_AS = _RLIMIT_AS,
+#define RLIMIT_AS RLIMIT_AS
+
+ /* Number of processes. */
+ _RLIMIT_NPROC = RLIMIT_NPROC,
+#undef RLIMIT_NPROC
+ RLIMIT_NPROC = _RLIMIT_NPROC,
+#define RLIMIT_NPROC RLIMIT_NPROC
+
+ /* Locked-in-memory address space. */
+ _RLIMIT_MEMLOCK = RLIMIT_MEMLOCK,
+#undef RLIMIT_MEMLOCK
+ RLIMIT_MEMLOCK = _RLIMIT_MEMLOCK,
+#define RLIMIT_MEMLOCK RLIMIT_MEMLOCK
+
+ RLIMIT_NLIMITS = RLIM_NLIMITS,
+#undef RLIM_NLIMITS
+ RLIM_NLIMITS = RLIMIT_NLIMITS
+#define RLIMIT_NLIMITS RLIMIT_NLIMITS
+#define RLIM_NLIMITS RLIM_NLIMITS
+};
+
+/* Value to indicate that there is no limit. */
+#if __WORDSIZE == 64
+
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((unsigned long int)(~0UL))
+#else
+# define RLIM_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffuLL
+#endif
+
+#else
+
+#ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((long int)(~0UL >> 1))
+#else
+# define RLIM_INFINITY 0x7fffffffffffffffLL
+#endif
+
+#ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0x7fffffffffffffffLL
+#endif
+
+#endif
+
+/* We can represent all limits. */
+#define RLIM_SAVED_MAX RLIM_INFINITY
+#define RLIM_SAVED_CUR RLIM_INFINITY
+
+
+/* Type for resource quantity measurement. */
+#ifndef __USE_FILE_OFFSET64
+typedef __rlim_t rlim_t;
+#else
+typedef __rlim64_t rlim_t;
+#endif
+#ifdef __USE_LARGEFILE64
+typedef __rlim64_t rlim64_t;
+#endif
+
+struct rlimit
+ {
+ /* The current (soft) limit. */
+ rlim_t rlim_cur;
+ /* The hard limit. */
+ rlim_t rlim_max;
+ };
+
+#ifdef __USE_LARGEFILE64
+struct rlimit64
+ {
+ /* The current (soft) limit. */
+ rlim64_t rlim_cur;
+ /* The hard limit. */
+ rlim64_t rlim_max;
+ };
+#endif
+
+/* Whose usage statistics do you want? */
+enum __rusage_who
+{
+ /* The calling process. */
+ RUSAGE_SELF = 0,
+#define RUSAGE_SELF RUSAGE_SELF
+
+ /* All of its terminated child processes. */
+ RUSAGE_CHILDREN = -1,
+#define RUSAGE_CHILDREN RUSAGE_CHILDREN
+
+ /* Both. */
+ RUSAGE_BOTH = -2
+#define RUSAGE_BOTH RUSAGE_BOTH
+};
+
+#define __need_timeval
+#include <bits/time.h> /* For `struct timeval'. */
+
+/* Structure which says how much of each resource has been used. */
+struct rusage
+ {
+ /* Total amount of user time used. */
+ struct timeval ru_utime;
+ /* Total amount of system time used. */
+ struct timeval ru_stime;
+ /* Maximum resident set size (in kilobytes). */
+ long int ru_maxrss;
+ /* Amount of sharing of text segment memory
+ with other processes (kilobyte-seconds). */
+ long int ru_ixrss;
+ /* Amount of data segment memory used (kilobyte-seconds). */
+ long int ru_idrss;
+ /* Amount of stack memory used (kilobyte-seconds). */
+ long int ru_isrss;
+ /* Number of soft page faults (i.e. those serviced by reclaiming
+ a page from the list of pages awaiting reallocation. */
+ long int ru_minflt;
+ /* Number of hard page faults (i.e. those that required I/O). */
+ long int ru_majflt;
+ /* Number of times a process was swapped out of physical memory. */
+ long int ru_nswap;
+ /* Number of input operations via the file system. Note: This
+ and `ru_oublock' do not include operations with the cache. */
+ long int ru_inblock;
+ /* Number of output operations via the file system. */
+ long int ru_oublock;
+ /* Number of IPC messages sent. */
+ long int ru_msgsnd;
+ /* Number of IPC messages received. */
+ long int ru_msgrcv;
+ /* Number of signals delivered. */
+ long int ru_nsignals;
+ /* Number of voluntary context switches, i.e. because the process
+ gave up the process before it had to (usually to wait for some
+ resource to be available). */
+ long int ru_nvcsw;
+ /* Number of involuntary context switches, i.e. a higher priority process
+ became runnable or the current process used up its time slice. */
+ long int ru_nivcsw;
+ };
+
+/* Priority limits. */
+#define PRIO_MIN -20 /* Minimum priority a process can have. */
+#define PRIO_MAX 20 /* Maximum priority a process can have. */
+
+/* The type of the WHICH argument to `getpriority' and `setpriority',
+ indicating what flavor of entity the WHO argument specifies. */
+enum __priority_which
+{
+ PRIO_PROCESS = 0, /* WHO is a process ID. */
+#define PRIO_PROCESS PRIO_PROCESS
+ PRIO_PGRP = 1, /* WHO is a process group ID. */
+#define PRIO_PGRP PRIO_PGRP
+ PRIO_USER = 2 /* WHO is a user ID. */
+#define PRIO_USER PRIO_USER
+};
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c b/sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c
deleted file mode 100644
index 9feab0e6b8..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/oldgetrlimit64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* getrlimit64 is the same as getrlimit. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c b/sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c
deleted file mode 100644
index 8edcff0086..0000000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/oldsetrlimit64.c
+++ /dev/null
@@ -1 +0,0 @@
-/* setrlimit64 is the same as setrlimit. */
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
index cbfc248c8e..34d3c62e86 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c
@@ -44,6 +44,7 @@ __sigaction (int sig, __const struct sigaction *act, struct sigaction *oact)
{
kact.k_sa_handler = act->sa_handler;
memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t));
+ kact.sa_flags = act->sa_flags;
kact.sa_restorer = NULL;
}